1; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK-VF4IC1 --check-prefix=CHECK 2; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK-VF4IC4 --check-prefix=CHECK 3; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=1 -S < %s | FileCheck %s --check-prefix=CHECK-VF1IC4 --check-prefix=CHECK 4 5define i32 @select_const_i32_from_icmp(i32* nocapture readonly %v, i64 %n) { 6; CHECK-LABEL: @select_const_i32_from_icmp 7; CHECK-VF4IC1: vector.body: 8; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 9; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 10; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 11; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 12; CHECK-VF4IC1: middle.block: 13; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 3, i32 3, i32 3, i32 3> 14; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 15; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 16 17; CHECK-VF4IC4: vector.body: 18; CHECK-VF4IC4: [[VEC_PHI1:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL1:%.*]], %vector.body ] 19; CHECK-VF4IC4-NEXT: [[VEC_PHI2:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL2:%.*]], %vector.body ] 20; CHECK-VF4IC4-NEXT: [[VEC_PHI3:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL3:%.*]], %vector.body ] 21; CHECK-VF4IC4-NEXT: [[VEC_PHI4:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL4:%.*]], %vector.body ] 22; CHECK-VF4IC4: [[VEC_ICMP1:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 23; CHECK-VF4IC4-NEXT: [[VEC_ICMP2:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 24; CHECK-VF4IC4-NEXT: [[VEC_ICMP3:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 25; CHECK-VF4IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 26; CHECK-VF4IC4-NEXT: [[VEC_SEL1:%.*]] = select <4 x i1> [[VEC_ICMP1]], <4 x i32> [[VEC_PHI1]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 27; CHECK-VF4IC4-NEXT: [[VEC_SEL2:%.*]] = select <4 x i1> [[VEC_ICMP2]], <4 x i32> [[VEC_PHI2]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 28; CHECK-VF4IC4-NEXT: [[VEC_SEL3:%.*]] = select <4 x i1> [[VEC_ICMP3]], <4 x i32> [[VEC_PHI3]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 29; CHECK-VF4IC4-NEXT: [[VEC_SEL4:%.*]] = select <4 x i1> [[VEC_ICMP4]], <4 x i32> [[VEC_PHI4]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 30; CHECK-VF4IC4: middle.block: 31; CHECK-VF4IC4-NEXT: [[VEC_ICMP5:%.*]] = icmp ne <4 x i32> [[VEC_SEL1]], <i32 3, i32 3, i32 3, i32 3> 32; CHECK-VF4IC4-NEXT: [[VEC_SEL5:%.*]] = select <4 x i1> [[VEC_ICMP5]], <4 x i32> [[VEC_SEL1]], <4 x i32> [[VEC_SEL2]] 33; CHECK-VF4IC4-NEXT: [[VEC_ICMP6:%.*]] = icmp ne <4 x i32> [[VEC_SEL5]], <i32 3, i32 3, i32 3, i32 3> 34; CHECK-VF4IC4-NEXT: [[VEC_SEL6:%.*]] = select <4 x i1> [[VEC_ICMP6]], <4 x i32> [[VEC_SEL5]], <4 x i32> [[VEC_SEL3]] 35; CHECK-VF4IC4-NEXT: [[VEC_ICMP7:%.*]] = icmp ne <4 x i32> [[VEC_SEL6]], <i32 3, i32 3, i32 3, i32 3> 36; CHECK-VF4IC4-NEXT: [[VEC_SEL_FIN:%.*]] = select <4 x i1> [[VEC_ICMP7]], <4 x i32> [[VEC_SEL6]], <4 x i32> [[VEC_SEL4]] 37; CHECK-VF4IC4-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL_FIN]], <i32 3, i32 3, i32 3, i32 3> 38; CHECK-VF4IC4-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 39; CHECK-VF4IC4-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 40 41 42; CHECK-VF1IC4: vector.body: 43; CHECK-VF1IC4: [[VEC_PHI1:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL1:%.*]], %vector.body ] 44; CHECK-VF1IC4-NEXT: [[VEC_PHI2:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL2:%.*]], %vector.body ] 45; CHECK-VF1IC4-NEXT: [[VEC_PHI3:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL3:%.*]], %vector.body ] 46; CHECK-VF1IC4-NEXT: [[VEC_PHI4:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL4:%.*]], %vector.body ] 47; CHECK-VF1IC4: [[VEC_LOAD1:%.*]] = load i32 48; CHECK-VF1IC4-NEXT: [[VEC_LOAD2:%.*]] = load i32 49; CHECK-VF1IC4-NEXT: [[VEC_LOAD3:%.*]] = load i32 50; CHECK-VF1IC4-NEXT: [[VEC_LOAD4:%.*]] = load i32 51; CHECK-VF1IC4-NEXT: [[VEC_ICMP1:%.*]] = icmp eq i32 [[VEC_LOAD1]], 3 52; CHECK-VF1IC4-NEXT: [[VEC_ICMP2:%.*]] = icmp eq i32 [[VEC_LOAD2]], 3 53; CHECK-VF1IC4-NEXT: [[VEC_ICMP3:%.*]] = icmp eq i32 [[VEC_LOAD3]], 3 54; CHECK-VF1IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp eq i32 [[VEC_LOAD4]], 3 55; CHECK-VF1IC4-NEXT: [[VEC_SEL1]] = select i1 [[VEC_ICMP1]], i32 [[VEC_PHI1]], i32 7 56; CHECK-VF1IC4-NEXT: [[VEC_SEL2]] = select i1 [[VEC_ICMP2]], i32 [[VEC_PHI2]], i32 7 57; CHECK-VF1IC4-NEXT: [[VEC_SEL3]] = select i1 [[VEC_ICMP3]], i32 [[VEC_PHI3]], i32 7 58; CHECK-VF1IC4-NEXT: [[VEC_SEL4]] = select i1 [[VEC_ICMP4]], i32 [[VEC_PHI4]], i32 7 59; CHECK-VF1IC4: middle.block: 60; CHECK-VF1IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp ne i32 [[VEC_SEL1]], 3 61; CHECK-VF1IC4-NEXT: [[VEC_SEL5:%.*]] = select i1 [[VEC_ICMP4]], i32 [[VEC_SEL1]], i32 [[VEC_SEL2]] 62; CHECK-VF1IC4-NEXT: [[VEC_ICMP5:%.*]] = icmp ne i32 [[VEC_SEL5]], 3 63; CHECK-VF1IC4-NEXT: [[VEC_SEL6:%.*]] = select i1 [[VEC_ICMP5]], i32 [[VEC_SEL5]], i32 [[VEC_SEL3]] 64; CHECK-VF1IC4-NEXT: [[VEC_ICMP6:%.*]] = icmp ne i32 [[VEC_SEL6]], 3 65; CHECK-VF1IC4-NEXT: {{.*}} = select i1 [[VEC_ICMP6]], i32 [[VEC_SEL6]], i32 [[VEC_SEL4]] 66 67entry: 68 br label %for.body 69 70for.body: ; preds = %entry, %for.body 71 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 72 %1 = phi i32 [ 3, %entry ], [ %5, %for.body ] 73 %2 = getelementptr inbounds i32, i32* %v, i64 %0 74 %3 = load i32, i32* %2, align 4 75 %4 = icmp eq i32 %3, 3 76 %5 = select i1 %4, i32 %1, i32 7 77 %6 = add nuw nsw i64 %0, 1 78 %7 = icmp eq i64 %6, %n 79 br i1 %7, label %exit, label %for.body 80 81exit: ; preds = %for.body 82 ret i32 %5 83} 84 85 86define i32 @select_const_i32_from_icmp2(i32* nocapture readonly %v, i64 %n) { 87; CHECK-LABEL: @select_const_i32_from_icmp2 88; CHECK-VF4IC1: vector.body: 89; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 90; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 91; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 92; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> <i32 7, i32 7, i32 7, i32 7>, <4 x i32> [[VEC_PHI]] 93; CHECK-VF4IC1: middle.block: 94; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 3, i32 3, i32 3, i32 3> 95; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 96; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 97 98entry: 99 br label %for.body 100 101for.body: ; preds = %entry, %for.body 102 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 103 %1 = phi i32 [ 3, %entry ], [ %5, %for.body ] 104 %2 = getelementptr inbounds i32, i32* %v, i64 %0 105 %3 = load i32, i32* %2, align 4 106 %4 = icmp eq i32 %3, 3 107 %5 = select i1 %4, i32 7, i32 %1 108 %6 = add nuw nsw i64 %0, 1 109 %7 = icmp eq i64 %6, %n 110 br i1 %7, label %exit, label %for.body 111 112exit: ; preds = %for.body 113 ret i32 %5 114} 115 116 117define i32 @select_i32_from_icmp(i32* nocapture readonly %v, i32 %a, i32 %b, i64 %n) { 118; CHECK-LABEL: @select_i32_from_icmp 119; CHECK-VF4IC1: vector.ph: 120; CHECK-VF4IC1: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 121; CHECK-VF4IC1-NEXT: [[SPLAT_OF_A:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer 122; CHECK-VF4IC1-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 123; CHECK-VF4IC1-NEXT: [[SPLAT_OF_B:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <4 x i32> zeroinitializer 124; CHECK-VF4IC1: vector.body: 125; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[SPLAT_OF_A]], %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 126; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 127; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 128; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> [[SPLAT_OF_B]] 129; CHECK-VF4IC1: middle.block: 130; CHECK-VF4IC1-NEXT: [[FIN_INS:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 131; CHECK-VF4IC1-NEXT: [[FIN_SPLAT:%.*]] = shufflevector <4 x i32> [[FIN_INS]], <4 x i32> poison, <4 x i32> zeroinitializer 132; CHECK-VF4IC1-NEXT: [[FIN_CMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], [[FIN_SPLAT]] 133; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_CMP]]) 134; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 %b, i32 %a 135entry: 136 br label %for.body 137 138for.body: ; preds = %entry, %for.body 139 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 140 %1 = phi i32 [ %a, %entry ], [ %5, %for.body ] 141 %2 = getelementptr inbounds i32, i32* %v, i64 %0 142 %3 = load i32, i32* %2, align 4 143 %4 = icmp eq i32 %3, 3 144 %5 = select i1 %4, i32 %1, i32 %b 145 %6 = add nuw nsw i64 %0, 1 146 %7 = icmp eq i64 %6, %n 147 br i1 %7, label %exit, label %for.body 148 149exit: ; preds = %for.body 150 ret i32 %5 151} 152 153 154define i32 @select_const_i32_from_fcmp_fast(float* nocapture readonly %v, i64 %n) { 155; CHECK-LABEL: @select_const_i32_from_fcmp_fast 156; CHECK-VF4IC1: vector.body: 157; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 2, i32 2, i32 2, i32 2>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 158; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x float> 159; CHECK-VF4IC1-NEXT: [[VEC_FCMP:%.*]] = fcmp fast ueq <4 x float> [[VEC_LOAD]], <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> 160; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_FCMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> 161; CHECK-VF4IC1: middle.block: 162; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 2, i32 2, i32 2, i32 2> 163; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 164; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 1, i32 2 165entry: 166 br label %for.body 167 168for.body: ; preds = %entry, %for.body 169 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 170 %1 = phi i32 [ 2, %entry ], [ %5, %for.body ] 171 %2 = getelementptr inbounds float, float* %v, i64 %0 172 %3 = load float, float* %2, align 4 173 %4 = fcmp fast ueq float %3, 3.0 174 %5 = select i1 %4, i32 %1, i32 1 175 %6 = add nuw nsw i64 %0, 1 176 %7 = icmp eq i64 %6, %n 177 br i1 %7, label %exit, label %for.body 178 179exit: ; preds = %for.body 180 ret i32 %5 181} 182 183 184define i32 @select_const_i32_from_fcmp(float* nocapture readonly %v, i64 %n) { 185; CHECK-LABEL: @select_const_i32_from_fcmp 186; CHECK-VF4IC1: vector.body: 187; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 2, i32 2, i32 2, i32 2>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 188; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x float> 189; CHECK-VF4IC1-NEXT: [[VEC_FCMP:%.*]] = fcmp ueq <4 x float> [[VEC_LOAD]], <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> 190; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_FCMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> 191; CHECK-VF4IC1: middle.block: 192; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 2, i32 2, i32 2, i32 2> 193; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 194; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 1, i32 2 195entry: 196 br label %for.body 197 198for.body: ; preds = %entry, %for.body 199 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 200 %1 = phi i32 [ 2, %entry ], [ %5, %for.body ] 201 %2 = getelementptr inbounds float, float* %v, i64 %0 202 %3 = load float, float* %2, align 4 203 %4 = fcmp ueq float %3, 3.0 204 %5 = select i1 %4, i32 %1, i32 1 205 %6 = add nuw nsw i64 %0, 1 206 %7 = icmp eq i64 %6, %n 207 br i1 %7, label %exit, label %for.body 208 209exit: ; preds = %for.body 210 ret i32 %5 211} 212 213 214define i32 @select_i32_from_icmp_same_inputs(i32 %a, i32 %b, i64 %n) { 215; CHECK-LABEL: @select_i32_from_icmp_same_inputs 216; CHECK-VF4IC1: vector.ph: 217; CHECK-VF4IC1: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 218; CHECK-VF4IC1-NEXT: [[SPLAT_OF_A:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer 219; CHECK-VF4IC1-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 220; CHECK-VF4IC1-NEXT: [[SPLAT_OF_B:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <4 x i32> zeroinitializer 221; CHECK-VF4IC1: vector.body: 222; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[SPLAT_OF_A]], %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 223; CHECK-VF4IC1: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_PHI]], <i32 3, i32 3, i32 3, i32 3> 224; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> [[SPLAT_OF_B]] 225; CHECK-VF4IC1: middle.block: 226; CHECK-VF4IC1-NEXT: [[FIN_INS:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 227; CHECK-VF4IC1-NEXT: [[FIN_SPLAT:%.*]] = shufflevector <4 x i32> [[FIN_INS]], <4 x i32> poison, <4 x i32> zeroinitializer 228; CHECK-VF4IC1-NEXT: [[FIN_CMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], [[FIN_SPLAT]] 229; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_CMP]]) 230; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 %b, i32 %a 231entry: 232 br label %for.body 233 234for.body: ; preds = %entry, %for.body 235 %0 = phi i64 [ 0, %entry ], [ %4, %for.body ] 236 %1 = phi i32 [ %a, %entry ], [ %3, %for.body ] 237 %2 = icmp eq i32 %1, 3 238 %3 = select i1 %2, i32 %1, i32 %b 239 %4 = add nuw nsw i64 %0, 1 240 %5 = icmp eq i64 %4, %n 241 br i1 %5, label %exit, label %for.body 242 243exit: ; preds = %for.body 244 ret i32 %3 245} 246 247 248; Negative tests 249 250; We don't support FP reduction variables at the moment. 251define float @select_const_f32_from_icmp(i32* nocapture readonly %v, i64 %n) { 252; CHECK: @select_const_f32_from_icmp 253; CHECK-NOT: vector.body 254entry: 255 br label %for.body 256 257for.body: ; preds = %entry, %for.body 258 %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 259 %1 = phi fast float [ 3.0, %entry ], [ %5, %for.body ] 260 %2 = getelementptr inbounds i32, i32* %v, i64 %0 261 %3 = load i32, i32* %2, align 4 262 %4 = icmp eq i32 %3, 3 263 %5 = select fast i1 %4, float %1, float 7.0 264 %6 = add nuw nsw i64 %0, 1 265 %7 = icmp eq i64 %6, %n 266 br i1 %7, label %exit, label %for.body 267 268exit: ; preds = %for.body 269 ret float %5 270} 271 272 273; We don't support select/cmp reduction patterns where there is more than one 274; use of the icmp/fcmp. 275define i32 @select_const_i32_from_icmp_mul_use(i32* nocapture readonly %v1, i32* %v2, i64 %n) { 276; CHECK-LABEL: @select_const_i32_from_icmp_mul_use 277; CHECK-NOT: vector.body 278entry: 279 br label %for.body 280 281for.body: ; preds = %entry, %for.body 282 %0 = phi i64 [ 0, %entry ], [ %8, %for.body ] 283 %1 = phi i32 [ 3, %entry ], [ %6, %for.body ] 284 %2 = phi i32 [ 0, %entry ], [ %7, %for.body ] 285 %3 = getelementptr inbounds i32, i32* %v1, i64 %0 286 %4 = load i32, i32* %3, align 4 287 %5 = icmp eq i32 %4, 3 288 %6 = select i1 %5, i32 %1, i32 7 289 %7 = zext i1 %5 to i32 290 %8 = add nuw nsw i64 %0, 1 291 %9 = icmp eq i64 %8, %n 292 br i1 %9, label %exit, label %for.body 293 294exit: ; preds = %for.body 295 store i32 %7, i32* %v2, align 4 296 ret i32 %6 297} 298 299 300; We don't support selecting loop-variant values. 301define i32 @select_variant_i32_from_icmp(i32* nocapture readonly %v1, i32* nocapture readonly %v2, i64 %n) { 302; CHECK-LABEL: @select_variant_i32_from_icmp 303; CHECK-NOT: vector.body 304entry: 305 br label %for.body 306 307for.body: ; preds = %entry, %for.body 308 %0 = phi i64 [ 0, %entry ], [ %8, %for.body ] 309 %1 = phi i32 [ 3, %entry ], [ %7, %for.body ] 310 %2 = getelementptr inbounds i32, i32* %v1, i64 %0 311 %3 = load i32, i32* %2, align 4 312 %4 = getelementptr inbounds i32, i32* %v2, i64 %0 313 %5 = load i32, i32* %4, align 4 314 %6 = icmp eq i32 %3, 3 315 %7 = select i1 %6, i32 %1, i32 %5 316 %8 = add nuw nsw i64 %0, 1 317 %9 = icmp eq i64 %8, %n 318 br i1 %9, label %exit, label %for.body 319 320exit: ; preds = %for.body 321 ret i32 %7 322} 323 324 325; We only support selects where the input comes from the same PHI as the 326; reduction PHI. In the example below, the select uses the induction 327; variable input and the icmp uses the reduction PHI. 328define i32 @select_i32_from_icmp_non_redux_phi(i32 %a, i32 %b, i32 %n) { 329; CHECK-LABEL: @select_i32_from_icmp_non_redux_phi 330; CHECK-NOT: vector.body 331entry: 332 br label %for.body 333 334for.body: ; preds = %entry, %for.body 335 %0 = phi i32 [ 0, %entry ], [ %4, %for.body ] 336 %1 = phi i32 [ %a, %entry ], [ %3, %for.body ] 337 %2 = icmp eq i32 %1, 3 338 %3 = select i1 %2, i32 %0, i32 %b 339 %4 = add nuw nsw i32 %0, 1 340 %5 = icmp eq i32 %4, %n 341 br i1 %5, label %exit, label %for.body 342 343exit: ; preds = %for.body 344 ret i32 %3 345} 346