1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -loop-vectorize -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5target triple = "x86_64-apple-macosx10.8.0" 6 7@c = common global [2048 x i32] zeroinitializer, align 16 8@b = common global [2048 x i32] zeroinitializer, align 16 9@d = common global [2048 x i32] zeroinitializer, align 16 10@a = common global [2048 x i32] zeroinitializer, align 16 11 12; The program below gathers and scatters data. We better not vectorize it. 13define void @cost_model_1() nounwind uwtable noinline ssp { 14; CHECK-LABEL: @cost_model_1( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: br label [[FOR_BODY:%.*]] 17; CHECK: for.body: 18; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 19; CHECK-NEXT: [[TMP0:%.*]] = shl nsw i64 [[INDVARS_IV]], 1 20; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @c, i64 0, i64 [[TMP0]] 21; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 8 22; CHECK-NEXT: [[IDXPROM1:%.*]] = sext i32 [[TMP1]] to i64 23; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @b, i64 0, i64 [[IDXPROM1]] 24; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4 25; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @d, i64 0, i64 [[INDVARS_IV]] 26; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4 27; CHECK-NEXT: [[IDXPROM5:%.*]] = sext i32 [[TMP3]] to i64 28; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @a, i64 0, i64 [[IDXPROM5]] 29; CHECK-NEXT: store i32 [[TMP2]], i32* [[ARRAYIDX6]], align 4 30; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 31; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 32; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], 256 33; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 34; CHECK: for.end: 35; CHECK-NEXT: ret void 36; 37entry: 38 br label %for.body 39 40for.body: ; preds = %for.body, %entry 41 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 42 %0 = shl nsw i64 %indvars.iv, 1 43 %arrayidx = getelementptr inbounds [2048 x i32], [2048 x i32]* @c, i64 0, i64 %0 44 %1 = load i32, i32* %arrayidx, align 8 45 %idxprom1 = sext i32 %1 to i64 46 %arrayidx2 = getelementptr inbounds [2048 x i32], [2048 x i32]* @b, i64 0, i64 %idxprom1 47 %2 = load i32, i32* %arrayidx2, align 4 48 %arrayidx4 = getelementptr inbounds [2048 x i32], [2048 x i32]* @d, i64 0, i64 %indvars.iv 49 %3 = load i32, i32* %arrayidx4, align 4 50 %idxprom5 = sext i32 %3 to i64 51 %arrayidx6 = getelementptr inbounds [2048 x i32], [2048 x i32]* @a, i64 0, i64 %idxprom5 52 store i32 %2, i32* %arrayidx6, align 4 53 %indvars.iv.next = add i64 %indvars.iv, 1 54 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 55 %exitcond = icmp eq i32 %lftr.wideiv, 256 56 br i1 %exitcond, label %for.end, label %for.body 57 58for.end: ; preds = %for.body 59 ret void 60} 61 62; This function uses a stride that is generally too big to benefit from vectorization without 63; really good support for a gather load. But if we don't vectorize the pointer induction, 64; then we don't need to extract the pointers out of vector of pointers, 65; and the vectorization becomes profitable. 66 67define float @PR27826(float* nocapture readonly %a, float* nocapture readonly %b, i32 %n) { 68; CHECK-LABEL: @PR27826( 69; CHECK-NEXT: entry: 70; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], 0 71; CHECK-NEXT: br i1 [[CMP]], label [[PREHEADER:%.*]], label [[FOR_END:%.*]] 72; CHECK: preheader: 73; CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64 74; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[T0]], -1 75; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 5 76; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1 77; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 16 78; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 79; CHECK: vector.ph: 80; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 16 81; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]] 82; CHECK-NEXT: [[IND_END:%.*]] = mul i64 [[N_VEC]], 32 83; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 84; CHECK: vector.body: 85; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 86; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP119:%.*]], [[VECTOR_BODY]] ] 87; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP120:%.*]], [[VECTOR_BODY]] ] 88; CHECK-NEXT: [[VEC_PHI2:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP121:%.*]], [[VECTOR_BODY]] ] 89; CHECK-NEXT: [[VEC_PHI3:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP122:%.*]], [[VECTOR_BODY]] ] 90; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 32 91; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0 92; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 32 93; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], 64 94; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 96 95; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[OFFSET_IDX]], 128 96; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[OFFSET_IDX]], 160 97; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[OFFSET_IDX]], 192 98; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 224 99; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[OFFSET_IDX]], 256 100; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[OFFSET_IDX]], 288 101; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 320 102; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 352 103; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 384 104; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 416 105; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 448 106; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[OFFSET_IDX]], 480 107; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[TMP3]] 108; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP4]] 109; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP5]] 110; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP6]] 111; CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP7]] 112; CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP8]] 113; CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]] 114; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP10]] 115; CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP11]] 116; CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP12]] 117; CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP13]] 118; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP14]] 119; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]] 120; CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP16]] 121; CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP17]] 122; CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP18]] 123; CHECK-NEXT: [[TMP35:%.*]] = load float, float* [[TMP19]], align 4 124; CHECK-NEXT: [[TMP36:%.*]] = load float, float* [[TMP20]], align 4 125; CHECK-NEXT: [[TMP37:%.*]] = load float, float* [[TMP21]], align 4 126; CHECK-NEXT: [[TMP38:%.*]] = load float, float* [[TMP22]], align 4 127; CHECK-NEXT: [[TMP39:%.*]] = insertelement <4 x float> poison, float [[TMP35]], i32 0 128; CHECK-NEXT: [[TMP40:%.*]] = insertelement <4 x float> [[TMP39]], float [[TMP36]], i32 1 129; CHECK-NEXT: [[TMP41:%.*]] = insertelement <4 x float> [[TMP40]], float [[TMP37]], i32 2 130; CHECK-NEXT: [[TMP42:%.*]] = insertelement <4 x float> [[TMP41]], float [[TMP38]], i32 3 131; CHECK-NEXT: [[TMP43:%.*]] = load float, float* [[TMP23]], align 4 132; CHECK-NEXT: [[TMP44:%.*]] = load float, float* [[TMP24]], align 4 133; CHECK-NEXT: [[TMP45:%.*]] = load float, float* [[TMP25]], align 4 134; CHECK-NEXT: [[TMP46:%.*]] = load float, float* [[TMP26]], align 4 135; CHECK-NEXT: [[TMP47:%.*]] = insertelement <4 x float> poison, float [[TMP43]], i32 0 136; CHECK-NEXT: [[TMP48:%.*]] = insertelement <4 x float> [[TMP47]], float [[TMP44]], i32 1 137; CHECK-NEXT: [[TMP49:%.*]] = insertelement <4 x float> [[TMP48]], float [[TMP45]], i32 2 138; CHECK-NEXT: [[TMP50:%.*]] = insertelement <4 x float> [[TMP49]], float [[TMP46]], i32 3 139; CHECK-NEXT: [[TMP51:%.*]] = load float, float* [[TMP27]], align 4 140; CHECK-NEXT: [[TMP52:%.*]] = load float, float* [[TMP28]], align 4 141; CHECK-NEXT: [[TMP53:%.*]] = load float, float* [[TMP29]], align 4 142; CHECK-NEXT: [[TMP54:%.*]] = load float, float* [[TMP30]], align 4 143; CHECK-NEXT: [[TMP55:%.*]] = insertelement <4 x float> poison, float [[TMP51]], i32 0 144; CHECK-NEXT: [[TMP56:%.*]] = insertelement <4 x float> [[TMP55]], float [[TMP52]], i32 1 145; CHECK-NEXT: [[TMP57:%.*]] = insertelement <4 x float> [[TMP56]], float [[TMP53]], i32 2 146; CHECK-NEXT: [[TMP58:%.*]] = insertelement <4 x float> [[TMP57]], float [[TMP54]], i32 3 147; CHECK-NEXT: [[TMP59:%.*]] = load float, float* [[TMP31]], align 4 148; CHECK-NEXT: [[TMP60:%.*]] = load float, float* [[TMP32]], align 4 149; CHECK-NEXT: [[TMP61:%.*]] = load float, float* [[TMP33]], align 4 150; CHECK-NEXT: [[TMP62:%.*]] = load float, float* [[TMP34]], align 4 151; CHECK-NEXT: [[TMP63:%.*]] = insertelement <4 x float> poison, float [[TMP59]], i32 0 152; CHECK-NEXT: [[TMP64:%.*]] = insertelement <4 x float> [[TMP63]], float [[TMP60]], i32 1 153; CHECK-NEXT: [[TMP65:%.*]] = insertelement <4 x float> [[TMP64]], float [[TMP61]], i32 2 154; CHECK-NEXT: [[TMP66:%.*]] = insertelement <4 x float> [[TMP65]], float [[TMP62]], i32 3 155; CHECK-NEXT: [[TMP67:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 [[TMP3]] 156; CHECK-NEXT: [[TMP68:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP4]] 157; CHECK-NEXT: [[TMP69:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP5]] 158; CHECK-NEXT: [[TMP70:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP6]] 159; CHECK-NEXT: [[TMP71:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP7]] 160; CHECK-NEXT: [[TMP72:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP8]] 161; CHECK-NEXT: [[TMP73:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP9]] 162; CHECK-NEXT: [[TMP74:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP10]] 163; CHECK-NEXT: [[TMP75:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP11]] 164; CHECK-NEXT: [[TMP76:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP12]] 165; CHECK-NEXT: [[TMP77:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP13]] 166; CHECK-NEXT: [[TMP78:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP14]] 167; CHECK-NEXT: [[TMP79:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP15]] 168; CHECK-NEXT: [[TMP80:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP16]] 169; CHECK-NEXT: [[TMP81:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP17]] 170; CHECK-NEXT: [[TMP82:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP18]] 171; CHECK-NEXT: [[TMP83:%.*]] = load float, float* [[TMP67]], align 4 172; CHECK-NEXT: [[TMP84:%.*]] = load float, float* [[TMP68]], align 4 173; CHECK-NEXT: [[TMP85:%.*]] = load float, float* [[TMP69]], align 4 174; CHECK-NEXT: [[TMP86:%.*]] = load float, float* [[TMP70]], align 4 175; CHECK-NEXT: [[TMP87:%.*]] = insertelement <4 x float> poison, float [[TMP83]], i32 0 176; CHECK-NEXT: [[TMP88:%.*]] = insertelement <4 x float> [[TMP87]], float [[TMP84]], i32 1 177; CHECK-NEXT: [[TMP89:%.*]] = insertelement <4 x float> [[TMP88]], float [[TMP85]], i32 2 178; CHECK-NEXT: [[TMP90:%.*]] = insertelement <4 x float> [[TMP89]], float [[TMP86]], i32 3 179; CHECK-NEXT: [[TMP91:%.*]] = load float, float* [[TMP71]], align 4 180; CHECK-NEXT: [[TMP92:%.*]] = load float, float* [[TMP72]], align 4 181; CHECK-NEXT: [[TMP93:%.*]] = load float, float* [[TMP73]], align 4 182; CHECK-NEXT: [[TMP94:%.*]] = load float, float* [[TMP74]], align 4 183; CHECK-NEXT: [[TMP95:%.*]] = insertelement <4 x float> poison, float [[TMP91]], i32 0 184; CHECK-NEXT: [[TMP96:%.*]] = insertelement <4 x float> [[TMP95]], float [[TMP92]], i32 1 185; CHECK-NEXT: [[TMP97:%.*]] = insertelement <4 x float> [[TMP96]], float [[TMP93]], i32 2 186; CHECK-NEXT: [[TMP98:%.*]] = insertelement <4 x float> [[TMP97]], float [[TMP94]], i32 3 187; CHECK-NEXT: [[TMP99:%.*]] = load float, float* [[TMP75]], align 4 188; CHECK-NEXT: [[TMP100:%.*]] = load float, float* [[TMP76]], align 4 189; CHECK-NEXT: [[TMP101:%.*]] = load float, float* [[TMP77]], align 4 190; CHECK-NEXT: [[TMP102:%.*]] = load float, float* [[TMP78]], align 4 191; CHECK-NEXT: [[TMP103:%.*]] = insertelement <4 x float> poison, float [[TMP99]], i32 0 192; CHECK-NEXT: [[TMP104:%.*]] = insertelement <4 x float> [[TMP103]], float [[TMP100]], i32 1 193; CHECK-NEXT: [[TMP105:%.*]] = insertelement <4 x float> [[TMP104]], float [[TMP101]], i32 2 194; CHECK-NEXT: [[TMP106:%.*]] = insertelement <4 x float> [[TMP105]], float [[TMP102]], i32 3 195; CHECK-NEXT: [[TMP107:%.*]] = load float, float* [[TMP79]], align 4 196; CHECK-NEXT: [[TMP108:%.*]] = load float, float* [[TMP80]], align 4 197; CHECK-NEXT: [[TMP109:%.*]] = load float, float* [[TMP81]], align 4 198; CHECK-NEXT: [[TMP110:%.*]] = load float, float* [[TMP82]], align 4 199; CHECK-NEXT: [[TMP111:%.*]] = insertelement <4 x float> poison, float [[TMP107]], i32 0 200; CHECK-NEXT: [[TMP112:%.*]] = insertelement <4 x float> [[TMP111]], float [[TMP108]], i32 1 201; CHECK-NEXT: [[TMP113:%.*]] = insertelement <4 x float> [[TMP112]], float [[TMP109]], i32 2 202; CHECK-NEXT: [[TMP114:%.*]] = insertelement <4 x float> [[TMP113]], float [[TMP110]], i32 3 203; CHECK-NEXT: [[TMP115:%.*]] = fadd fast <4 x float> [[TMP42]], [[VEC_PHI]] 204; CHECK-NEXT: [[TMP116:%.*]] = fadd fast <4 x float> [[TMP50]], [[VEC_PHI1]] 205; CHECK-NEXT: [[TMP117:%.*]] = fadd fast <4 x float> [[TMP58]], [[VEC_PHI2]] 206; CHECK-NEXT: [[TMP118:%.*]] = fadd fast <4 x float> [[TMP66]], [[VEC_PHI3]] 207; CHECK-NEXT: [[TMP119]] = fadd fast <4 x float> [[TMP115]], [[TMP90]] 208; CHECK-NEXT: [[TMP120]] = fadd fast <4 x float> [[TMP116]], [[TMP98]] 209; CHECK-NEXT: [[TMP121]] = fadd fast <4 x float> [[TMP117]], [[TMP106]] 210; CHECK-NEXT: [[TMP122]] = fadd fast <4 x float> [[TMP118]], [[TMP114]] 211; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 212; CHECK-NEXT: [[TMP123:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 213; CHECK-NEXT: br i1 [[TMP123]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 214; CHECK: middle.block: 215; CHECK-NEXT: [[BIN_RDX:%.*]] = fadd fast <4 x float> [[TMP120]], [[TMP119]] 216; CHECK-NEXT: [[BIN_RDX4:%.*]] = fadd fast <4 x float> [[TMP121]], [[BIN_RDX]] 217; CHECK-NEXT: [[BIN_RDX5:%.*]] = fadd fast <4 x float> [[TMP122]], [[BIN_RDX4]] 218; CHECK-NEXT: [[TMP124:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> [[BIN_RDX5]]) 219; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]] 220; CHECK-NEXT: br i1 [[CMP_N]], label [[LOOPEXIT:%.*]], label [[SCALAR_PH]] 221; CHECK: scalar.ph: 222; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[PREHEADER]] ] 223; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi float [ 0.000000e+00, [[PREHEADER]] ], [ [[TMP124]], [[MIDDLE_BLOCK]] ] 224; CHECK-NEXT: br label [[FOR:%.*]] 225; CHECK: for: 226; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR]] ] 227; CHECK-NEXT: [[S_02:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[ADD4:%.*]], [[FOR]] ] 228; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[INDVARS_IV]] 229; CHECK-NEXT: [[T1:%.*]] = load float, float* [[ARRAYIDX]], align 4 230; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[INDVARS_IV]] 231; CHECK-NEXT: [[T2:%.*]] = load float, float* [[ARRAYIDX3]], align 4 232; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[T1]], [[S_02]] 233; CHECK-NEXT: [[ADD4]] = fadd fast float [[ADD]], [[T2]] 234; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 32 235; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[T0]] 236; CHECK-NEXT: br i1 [[CMP1]], label [[FOR]], label [[LOOPEXIT]], !llvm.loop [[LOOP2:![0-9]+]] 237; CHECK: loopexit: 238; CHECK-NEXT: [[ADD4_LCSSA:%.*]] = phi float [ [[ADD4]], [[FOR]] ], [ [[TMP124]], [[MIDDLE_BLOCK]] ] 239; CHECK-NEXT: br label [[FOR_END]] 240; CHECK: for.end: 241; CHECK-NEXT: [[S_0_LCSSA:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[ADD4_LCSSA]], [[LOOPEXIT]] ] 242; CHECK-NEXT: ret float [[S_0_LCSSA]] 243; 244entry: 245 %cmp = icmp sgt i32 %n, 0 246 br i1 %cmp, label %preheader, label %for.end 247 248preheader: 249 %t0 = sext i32 %n to i64 250 br label %for 251 252for: 253 %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %for ] 254 %s.02 = phi float [ 0.0, %preheader ], [ %add4, %for ] 255 %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv 256 %t1 = load float, float* %arrayidx, align 4 257 %arrayidx3 = getelementptr inbounds float, float* %b, i64 %indvars.iv 258 %t2 = load float, float* %arrayidx3, align 4 259 %add = fadd fast float %t1, %s.02 260 %add4 = fadd fast float %add, %t2 261 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 32 262 %cmp1 = icmp slt i64 %indvars.iv.next, %t0 263 br i1 %cmp1, label %for, label %loopexit 264 265loopexit: 266 %add4.lcssa = phi float [ %add4, %for ] 267 br label %for.end 268 269for.end: 270 %s.0.lcssa = phi float [ 0.0, %entry ], [ %add4.lcssa, %loopexit ] 271 ret float %s.0.lcssa 272} 273 274