1204 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=slp-vectorizer -S < %s -mtriple=x86_64-apple-macosx -mcpu=corei7-avx | FileCheck %s3; RUN: opt -passes=slp-vectorizer -slp-vectorize-hor -slp-vectorize-hor-store -S < %s -mtriple=x86_64-apple-macosx -mcpu=corei7-avx | FileCheck %s4 5; #include <stdint.h>6;7; int foo(float *A, int n) {8; float sum = 0;9; for (intptr_t i=0; i < n; ++i) {10; sum += 7*A[i*4 ] +11; 7*A[i*4+1] +12; 7*A[i*4+2] +13; 7*A[i*4+3];14; }15; return sum;16; }17 18define i32 @add_red(ptr %A, i32 %n) {19; CHECK-LABEL: @add_red(20; CHECK-NEXT: entry:21; CHECK-NEXT: [[CMP31:%.*]] = icmp sgt i32 [[N:%.*]], 022; CHECK-NEXT: br i1 [[CMP31]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]23; CHECK: for.body.lr.ph:24; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[N]] to i6425; CHECK-NEXT: br label [[FOR_BODY:%.*]]26; CHECK: for.body:27; CHECK-NEXT: [[I_033:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]28; CHECK-NEXT: [[SUM_032:%.*]] = phi float [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD17:%.*]], [[FOR_BODY]] ]29; CHECK-NEXT: [[MUL:%.*]] = shl nsw i64 [[I_033]], 230; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[MUL]]31; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[ARRAYIDX]], align 432; CHECK-NEXT: [[TMP2:%.*]] = fmul <4 x float> [[TMP1]], splat (float 7.000000e+00)33; CHECK-NEXT: [[TMP3:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP2]])34; CHECK-NEXT: [[ADD17]] = fadd fast float [[SUM_032]], [[TMP3]]35; CHECK-NEXT: [[INC]] = add nsw i64 [[I_033]], 136; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP0]]37; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]], label [[FOR_BODY]]38; CHECK: for.cond.for.end_crit_edge:39; CHECK-NEXT: [[PHITMP:%.*]] = fptosi float [[ADD17]] to i3240; CHECK-NEXT: br label [[FOR_END]]41; CHECK: for.end:42; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[PHITMP]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]43; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]44;45entry:46 %cmp31 = icmp sgt i32 %n, 047 br i1 %cmp31, label %for.body.lr.ph, label %for.end48 49for.body.lr.ph:50 %0 = sext i32 %n to i6451 br label %for.body52 53for.body:54 %i.033 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]55 %sum.032 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add17, %for.body ]56 %mul = shl nsw i64 %i.033, 257 %arrayidx = getelementptr inbounds float, ptr %A, i64 %mul58 %1 = load float, ptr %arrayidx, align 459 %mul2 = fmul float %1, 7.000000e+0060 %add28 = or disjoint i64 %mul, 161 %arrayidx4 = getelementptr inbounds float, ptr %A, i64 %add2862 %2 = load float, ptr %arrayidx4, align 463 %mul5 = fmul float %2, 7.000000e+0064 %add6 = fadd fast float %mul2, %mul565 %add829 = or disjoint i64 %mul, 266 %arrayidx9 = getelementptr inbounds float, ptr %A, i64 %add82967 %3 = load float, ptr %arrayidx9, align 468 %mul10 = fmul float %3, 7.000000e+0069 %add11 = fadd fast float %add6, %mul1070 %add1330 = or disjoint i64 %mul, 371 %arrayidx14 = getelementptr inbounds float, ptr %A, i64 %add133072 %4 = load float, ptr %arrayidx14, align 473 %mul15 = fmul float %4, 7.000000e+0074 %add16 = fadd fast float %add11, %mul1575 %add17 = fadd fast float %sum.032, %add1676 %inc = add nsw i64 %i.033, 177 %exitcond = icmp eq i64 %inc, %078 br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body79 80for.cond.for.end_crit_edge:81 %phitmp = fptosi float %add17 to i3282 br label %for.end83 84for.end:85 %sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]86 ret i32 %sum.0.lcssa87}88 89; int foo(float * restrict A, float * restrict B, int n) {90; float sum = 0;91; for (intptr_t i=0; i < n; ++i) {92; sum *= B[0]*A[i*4 ] +93; B[1]*A[i*4+1] +94; B[2]*A[i*4+2] +95; B[3]*A[i*4+3];96; }97; return sum;98; }99 100define i32 @mul_red(ptr noalias %A, ptr noalias %B, i32 %n) {101; CHECK-LABEL: @mul_red(102; CHECK-NEXT: entry:103; CHECK-NEXT: [[CMP38:%.*]] = icmp sgt i32 [[N:%.*]], 0104; CHECK-NEXT: br i1 [[CMP38]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]105; CHECK: for.body.lr.ph:106; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[B:%.*]], align 4107; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64108; CHECK-NEXT: br label [[FOR_BODY:%.*]]109; CHECK: for.body:110; CHECK-NEXT: [[I_040:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]111; CHECK-NEXT: [[SUM_039:%.*]] = phi float [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[MUL21:%.*]], [[FOR_BODY]] ]112; CHECK-NEXT: [[MUL:%.*]] = shl nsw i64 [[I_040]], 2113; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[MUL]]114; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[ARRAYIDX2]], align 4115; CHECK-NEXT: [[TMP3:%.*]] = fmul <4 x float> [[TMP0]], [[TMP2]]116; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP3]])117; CHECK-NEXT: [[MUL21]] = fmul float [[SUM_039]], [[TMP4]]118; CHECK-NEXT: [[INC]] = add nsw i64 [[I_040]], 1119; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP1]]120; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]], label [[FOR_BODY]]121; CHECK: for.cond.for.end_crit_edge:122; CHECK-NEXT: [[PHITMP:%.*]] = fptosi float [[MUL21]] to i32123; CHECK-NEXT: br label [[FOR_END]]124; CHECK: for.end:125; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[PHITMP]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]126; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]127;128entry:129 %cmp38 = icmp sgt i32 %n, 0130 br i1 %cmp38, label %for.body.lr.ph, label %for.end131 132for.body.lr.ph:133 %0 = load float, ptr %B, align 4134 %arrayidx4 = getelementptr inbounds float, ptr %B, i64 1135 %1 = load float, ptr %arrayidx4, align 4136 %arrayidx9 = getelementptr inbounds float, ptr %B, i64 2137 %2 = load float, ptr %arrayidx9, align 4138 %arrayidx15 = getelementptr inbounds float, ptr %B, i64 3139 %3 = load float, ptr %arrayidx15, align 4140 %4 = sext i32 %n to i64141 br label %for.body142 143for.body:144 %i.040 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]145 %sum.039 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %mul21, %for.body ]146 %mul = shl nsw i64 %i.040, 2147 %arrayidx2 = getelementptr inbounds float, ptr %A, i64 %mul148 %5 = load float, ptr %arrayidx2, align 4149 %mul3 = fmul float %0, %5150 %add35 = or disjoint i64 %mul, 1151 %arrayidx6 = getelementptr inbounds float, ptr %A, i64 %add35152 %6 = load float, ptr %arrayidx6, align 4153 %mul7 = fmul float %1, %6154 %add8 = fadd fast float %mul3, %mul7155 %add1136 = or disjoint i64 %mul, 2156 %arrayidx12 = getelementptr inbounds float, ptr %A, i64 %add1136157 %7 = load float, ptr %arrayidx12, align 4158 %mul13 = fmul float %2, %7159 %add14 = fadd fast float %add8, %mul13160 %add1737 = or disjoint i64 %mul, 3161 %arrayidx18 = getelementptr inbounds float, ptr %A, i64 %add1737162 %8 = load float, ptr %arrayidx18, align 4163 %mul19 = fmul float %3, %8164 %add20 = fadd fast float %add14, %mul19165 %mul21 = fmul float %sum.039, %add20166 %inc = add nsw i64 %i.040, 1167 %exitcond = icmp eq i64 %inc, %4168 br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body169 170for.cond.for.end_crit_edge:171 %phitmp = fptosi float %mul21 to i32172 br label %for.end173 174for.end:175 %sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]176 ret i32 %sum.0.lcssa177}178 179; int foo(float * restrict A, float * restrict B, int n) {180; float sum = 0;181; for (intptr_t i=0; i < n; ++i) {182; sum += B[0]*A[i*6 ] +183; B[1]*A[i*6+1] +184; B[2]*A[i*6+2] +185; B[3]*A[i*6+3] +186; B[4]*A[i*6+4] +187; B[5]*A[i*6+5] +188; B[6]*A[i*6+6] +189; B[7]*A[i*6+7] +190; B[8]*A[i*6+8];191; }192; return sum;193; }194 195define i32 @long_red(ptr noalias %A, ptr noalias %B, i32 %n) {196; CHECK-LABEL: @long_red(197; CHECK-NEXT: entry:198; CHECK-NEXT: [[CMP81:%.*]] = icmp sgt i32 [[N:%.*]], 0199; CHECK-NEXT: br i1 [[CMP81]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]200; CHECK: for.body.lr.ph:201; CHECK-NEXT: [[TMP0:%.*]] = load <8 x float>, ptr [[B:%.*]], align 4202; CHECK-NEXT: [[ARRAYIDX45:%.*]] = getelementptr inbounds float, ptr [[B]], i64 8203; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX45]], align 4204; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[N]] to i64205; CHECK-NEXT: br label [[FOR_BODY:%.*]]206; CHECK: for.body:207; CHECK-NEXT: [[I_083:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]208; CHECK-NEXT: [[SUM_082:%.*]] = phi float [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD51:%.*]], [[FOR_BODY]] ]209; CHECK-NEXT: [[MUL:%.*]] = mul nsw i64 [[I_083]], 6210; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[MUL]]211; CHECK-NEXT: [[TMP3:%.*]] = load <8 x float>, ptr [[ARRAYIDX2]], align 4212; CHECK-NEXT: [[TMP4:%.*]] = fmul fast <8 x float> [[TMP0]], [[TMP3]]213; CHECK-NEXT: [[ADD47:%.*]] = add nsw i64 [[MUL]], 8214; CHECK-NEXT: [[ARRAYIDX48:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[ADD47]]215; CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX48]], align 4216; CHECK-NEXT: [[MUL49:%.*]] = fmul fast float [[TMP1]], [[TMP5]]217; CHECK-NEXT: [[TMP6:%.*]] = call fast float @llvm.vector.reduce.fadd.v8f32(float 0.000000e+00, <8 x float> [[TMP4]])218; CHECK-NEXT: [[OP_RDX:%.*]] = fadd fast float [[TMP6]], [[MUL49]]219; CHECK-NEXT: [[ADD51]] = fadd fast float [[SUM_082]], [[OP_RDX]]220; CHECK-NEXT: [[INC]] = add nsw i64 [[I_083]], 1221; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP2]]222; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]], label [[FOR_BODY]]223; CHECK: for.cond.for.end_crit_edge:224; CHECK-NEXT: [[PHITMP:%.*]] = fptosi float [[ADD51]] to i32225; CHECK-NEXT: br label [[FOR_END]]226; CHECK: for.end:227; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[PHITMP]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]228; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]229;230entry:231 %cmp81 = icmp sgt i32 %n, 0232 br i1 %cmp81, label %for.body.lr.ph, label %for.end233 234for.body.lr.ph:235 %0 = load float, ptr %B, align 4236 %arrayidx4 = getelementptr inbounds float, ptr %B, i64 1237 %1 = load float, ptr %arrayidx4, align 4238 %arrayidx9 = getelementptr inbounds float, ptr %B, i64 2239 %2 = load float, ptr %arrayidx9, align 4240 %arrayidx15 = getelementptr inbounds float, ptr %B, i64 3241 %3 = load float, ptr %arrayidx15, align 4242 %arrayidx21 = getelementptr inbounds float, ptr %B, i64 4243 %4 = load float, ptr %arrayidx21, align 4244 %arrayidx27 = getelementptr inbounds float, ptr %B, i64 5245 %5 = load float, ptr %arrayidx27, align 4246 %arrayidx33 = getelementptr inbounds float, ptr %B, i64 6247 %6 = load float, ptr %arrayidx33, align 4248 %arrayidx39 = getelementptr inbounds float, ptr %B, i64 7249 %7 = load float, ptr %arrayidx39, align 4250 %arrayidx45 = getelementptr inbounds float, ptr %B, i64 8251 %8 = load float, ptr %arrayidx45, align 4252 %9 = sext i32 %n to i64253 br label %for.body254 255for.body:256 %i.083 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]257 %sum.082 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add51, %for.body ]258 %mul = mul nsw i64 %i.083, 6259 %arrayidx2 = getelementptr inbounds float, ptr %A, i64 %mul260 %10 = load float, ptr %arrayidx2, align 4261 %mul3 = fmul fast float %0, %10262 %add80 = or disjoint i64 %mul, 1263 %arrayidx6 = getelementptr inbounds float, ptr %A, i64 %add80264 %11 = load float, ptr %arrayidx6, align 4265 %mul7 = fmul fast float %1, %11266 %add8 = fadd fast float %mul3, %mul7267 %add11 = add nsw i64 %mul, 2268 %arrayidx12 = getelementptr inbounds float, ptr %A, i64 %add11269 %12 = load float, ptr %arrayidx12, align 4270 %mul13 = fmul fast float %2, %12271 %add14 = fadd fast float %add8, %mul13272 %add17 = add nsw i64 %mul, 3273 %arrayidx18 = getelementptr inbounds float, ptr %A, i64 %add17274 %13 = load float, ptr %arrayidx18, align 4275 %mul19 = fmul fast float %3, %13276 %add20 = fadd fast float %add14, %mul19277 %add23 = add nsw i64 %mul, 4278 %arrayidx24 = getelementptr inbounds float, ptr %A, i64 %add23279 %14 = load float, ptr %arrayidx24, align 4280 %mul25 = fmul fast float %4, %14281 %add26 = fadd fast float %add20, %mul25282 %add29 = add nsw i64 %mul, 5283 %arrayidx30 = getelementptr inbounds float, ptr %A, i64 %add29284 %15 = load float, ptr %arrayidx30, align 4285 %mul31 = fmul fast float %5, %15286 %add32 = fadd fast float %add26, %mul31287 %add35 = add nsw i64 %mul, 6288 %arrayidx36 = getelementptr inbounds float, ptr %A, i64 %add35289 %16 = load float, ptr %arrayidx36, align 4290 %mul37 = fmul fast float %6, %16291 %add38 = fadd fast float %add32, %mul37292 %add41 = add nsw i64 %mul, 7293 %arrayidx42 = getelementptr inbounds float, ptr %A, i64 %add41294 %17 = load float, ptr %arrayidx42, align 4295 %mul43 = fmul fast float %7, %17296 %add44 = fadd fast float %add38, %mul43297 %add47 = add nsw i64 %mul, 8298 %arrayidx48 = getelementptr inbounds float, ptr %A, i64 %add47299 %18 = load float, ptr %arrayidx48, align 4300 %mul49 = fmul fast float %8, %18301 %add50 = fadd fast float %add44, %mul49302 %add51 = fadd fast float %sum.082, %add50303 %inc = add nsw i64 %i.083, 1304 %exitcond = icmp eq i64 %inc, %9305 br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body306 307for.cond.for.end_crit_edge:308 %phitmp = fptosi float %add51 to i32309 br label %for.end310 311for.end:312 %sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]313 ret i32 %sum.0.lcssa314}315 316; int foo(float * restrict A, float * restrict B, int n) {317; float sum = 0;318; for (intptr_t i=0; i < n; ++i) {319; sum += B[0]*A[i*4 ];320; sum += B[1]*A[i*4+1];321; sum += B[2]*A[i*4+2];322; sum += B[3]*A[i*4+3];323; }324; return sum;325; }326 327define i32 @chain_red(ptr noalias %A, ptr noalias %B, i32 %n) {328; CHECK-LABEL: @chain_red(329; CHECK-NEXT: entry:330; CHECK-NEXT: [[CMP41:%.*]] = icmp sgt i32 [[N:%.*]], 0331; CHECK-NEXT: br i1 [[CMP41]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]332; CHECK: for.body.lr.ph:333; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[B:%.*]], align 4334; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64335; CHECK-NEXT: br label [[FOR_BODY:%.*]]336; CHECK: for.body:337; CHECK-NEXT: [[I_043:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]338; CHECK-NEXT: [[SUM_042:%.*]] = phi float [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[OP_RDX:%.*]], [[FOR_BODY]] ]339; CHECK-NEXT: [[MUL:%.*]] = shl nsw i64 [[I_043]], 2340; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[MUL]]341; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[ARRAYIDX2]], align 4342; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <4 x float> [[TMP0]], [[TMP2]]343; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP3]])344; CHECK-NEXT: [[OP_RDX]] = fadd fast float [[TMP4]], [[SUM_042]]345; CHECK-NEXT: [[INC]] = add nsw i64 [[I_043]], 1346; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP1]]347; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]], label [[FOR_BODY]]348; CHECK: for.cond.for.end_crit_edge:349; CHECK-NEXT: [[PHITMP:%.*]] = fptosi float [[OP_RDX]] to i32350; CHECK-NEXT: br label [[FOR_END]]351; CHECK: for.end:352; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[PHITMP]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]353; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]354;355entry:356 %cmp41 = icmp sgt i32 %n, 0357 br i1 %cmp41, label %for.body.lr.ph, label %for.end358 359for.body.lr.ph:360 %0 = load float, ptr %B, align 4361 %arrayidx4 = getelementptr inbounds float, ptr %B, i64 1362 %1 = load float, ptr %arrayidx4, align 4363 %arrayidx10 = getelementptr inbounds float, ptr %B, i64 2364 %2 = load float, ptr %arrayidx10, align 4365 %arrayidx16 = getelementptr inbounds float, ptr %B, i64 3366 %3 = load float, ptr %arrayidx16, align 4367 %4 = sext i32 %n to i64368 br label %for.body369 370for.body:371 %i.043 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]372 %sum.042 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add21, %for.body ]373 %mul = shl nsw i64 %i.043, 2374 %arrayidx2 = getelementptr inbounds float, ptr %A, i64 %mul375 %5 = load float, ptr %arrayidx2, align 4376 %mul3 = fmul fast float %0, %5377 %add = fadd fast float %sum.042, %mul3378 %add638 = or disjoint i64 %mul, 1379 %arrayidx7 = getelementptr inbounds float, ptr %A, i64 %add638380 %6 = load float, ptr %arrayidx7, align 4381 %mul8 = fmul fast float %1, %6382 %add9 = fadd fast float %add, %mul8383 %add1239 = or disjoint i64 %mul, 2384 %arrayidx13 = getelementptr inbounds float, ptr %A, i64 %add1239385 %7 = load float, ptr %arrayidx13, align 4386 %mul14 = fmul fast float %2, %7387 %add15 = fadd fast float %add9, %mul14388 %add1840 = or disjoint i64 %mul, 3389 %arrayidx19 = getelementptr inbounds float, ptr %A, i64 %add1840390 %8 = load float, ptr %arrayidx19, align 4391 %mul20 = fmul fast float %3, %8392 %add21 = fadd fast float %add15, %mul20393 %inc = add nsw i64 %i.043, 1394 %exitcond = icmp eq i64 %inc, %4395 br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body396 397for.cond.for.end_crit_edge:398 %phitmp = fptosi float %add21 to i32399 br label %for.end400 401for.end:402 %sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]403 ret i32 %sum.0.lcssa404}405 406; void foo(const float *arg_A, unsigned arg_B, float *array) {407; for (uint32_t i = 0; i < 6; ++i) {408; const float *ptr = arg_A + i;409; float w0 = array[i * 4 + 0];410; float w1 = array[i * 4 + 1];411; float w2 = array[i * 4 + 2];412; float w3 = array[i * 4 + 3];413;414; for (unsigned j = 0; j < arg_B; ++j) {415; const float x1 = *ptr - (-1.1f * w0) - (1.2f * w1);416; const float x2 = (2.1f * x1) + (-2.2f * w0) + (2.3f * w1);417; const float x3 = x2 - (-3.1f * w2) - (3.2f * w3);418; const float x4 = x3 + (-4.0f * w2) + w3;419; w1 = w0;420; w0 = x1;421; w3 = w2;422; w2 = x3;423; }424;425; array[i * 4 + 0] = w0;426; array[i * 4 + 1] = w1;427; array[i * 4 + 2] = w2;428; array[i * 4 + 3] = w3;429; }430; }431 432define void @foo(ptr nocapture readonly %arg_A, i32 %arg_B, ptr nocapture %array) {433; CHECK-LABEL: @foo(434; CHECK-NEXT: entry:435; CHECK-NEXT: [[CMP1495:%.*]] = icmp eq i32 [[ARG_B:%.*]], 0436; CHECK-NEXT: br label [[FOR_BODY:%.*]]437; CHECK: for.cond.cleanup:438; CHECK-NEXT: ret void439; CHECK: for.body:440; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_COND_CLEANUP15:%.*]] ]441; CHECK-NEXT: [[TMP0:%.*]] = shl i64 [[INDVARS_IV]], 2442; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[ARRAY:%.*]], i64 [[TMP0]]443; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX]], align 4444; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[TMP0]], 1445; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[ARRAY]], i64 [[TMP2]]446; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX4]], align 4447; CHECK-NEXT: [[TMP4:%.*]] = or disjoint i64 [[TMP0]], 2448; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[ARRAY]], i64 [[TMP4]]449; CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX8]], align 4450; CHECK-NEXT: [[TMP6:%.*]] = or disjoint i64 [[TMP0]], 3451; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds float, ptr [[ARRAY]], i64 [[TMP6]]452; CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[ARRAYIDX12]], align 4453; CHECK-NEXT: br i1 [[CMP1495]], label [[FOR_COND_CLEANUP15]], label [[FOR_BODY16_LR_PH:%.*]]454; CHECK: for.body16.lr.ph:455; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, ptr [[ARG_A:%.*]], i64 [[INDVARS_IV]]456; CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ADD_PTR]], align 4457; CHECK-NEXT: br label [[FOR_BODY16:%.*]]458; CHECK: for.cond.cleanup15:459; CHECK-NEXT: [[W2_0_LCSSA:%.*]] = phi float [ [[TMP5]], [[FOR_BODY]] ], [ [[SUB28:%.*]], [[FOR_BODY16]] ]460; CHECK-NEXT: [[W3_0_LCSSA:%.*]] = phi float [ [[TMP7]], [[FOR_BODY]] ], [ [[W2_096:%.*]], [[FOR_BODY16]] ]461; CHECK-NEXT: [[W1_0_LCSSA:%.*]] = phi float [ [[TMP3]], [[FOR_BODY]] ], [ [[W0_0100:%.*]], [[FOR_BODY16]] ]462; CHECK-NEXT: [[W0_0_LCSSA:%.*]] = phi float [ [[TMP1]], [[FOR_BODY]] ], [ [[SUB19:%.*]], [[FOR_BODY16]] ]463; CHECK-NEXT: store float [[W0_0_LCSSA]], ptr [[ARRAYIDX]], align 4464; CHECK-NEXT: store float [[W1_0_LCSSA]], ptr [[ARRAYIDX4]], align 4465; CHECK-NEXT: store float [[W2_0_LCSSA]], ptr [[ARRAYIDX8]], align 4466; CHECK-NEXT: store float [[W3_0_LCSSA]], ptr [[ARRAYIDX12]], align 4467; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1468; CHECK-NEXT: [[EXITCOND109:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 6469; CHECK-NEXT: br i1 [[EXITCOND109]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]470; CHECK: for.body16:471; CHECK-NEXT: [[W0_0100]] = phi float [ [[TMP1]], [[FOR_BODY16_LR_PH]] ], [ [[SUB19]], [[FOR_BODY16]] ]472; CHECK-NEXT: [[W1_099:%.*]] = phi float [ [[TMP3]], [[FOR_BODY16_LR_PH]] ], [ [[W0_0100]], [[FOR_BODY16]] ]473; CHECK-NEXT: [[J_098:%.*]] = phi i32 [ 0, [[FOR_BODY16_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY16]] ]474; CHECK-NEXT: [[W3_097:%.*]] = phi float [ [[TMP7]], [[FOR_BODY16_LR_PH]] ], [ [[W2_096]], [[FOR_BODY16]] ]475; CHECK-NEXT: [[W2_096]] = phi float [ [[TMP5]], [[FOR_BODY16_LR_PH]] ], [ [[SUB28]], [[FOR_BODY16]] ]476; CHECK-NEXT: [[MUL17:%.*]] = fmul fast float [[W0_0100]], 0x3FF19999A0000000477; CHECK-NEXT: [[MUL18_NEG:%.*]] = fmul fast float [[W1_099]], 0xBFF3333340000000478; CHECK-NEXT: [[SUB92:%.*]] = fadd fast float [[MUL17]], [[MUL18_NEG]]479; CHECK-NEXT: [[SUB19]] = fadd fast float [[SUB92]], [[TMP8]]480; CHECK-NEXT: [[MUL20:%.*]] = fmul fast float [[SUB19]], 0x4000CCCCC0000000481; CHECK-NEXT: [[MUL21_NEG:%.*]] = fmul fast float [[W0_0100]], 0xC0019999A0000000482; CHECK-NEXT: [[MUL23:%.*]] = fmul fast float [[W1_099]], 0x4002666660000000483; CHECK-NEXT: [[MUL25:%.*]] = fmul fast float [[W2_096]], 0x4008CCCCC0000000484; CHECK-NEXT: [[MUL27_NEG:%.*]] = fmul fast float [[W3_097]], 0xC0099999A0000000485; CHECK-NEXT: [[ADD2293:%.*]] = fadd fast float [[MUL27_NEG]], [[MUL25]]486; CHECK-NEXT: [[ADD24:%.*]] = fadd fast float [[ADD2293]], [[MUL23]]487; CHECK-NEXT: [[SUB2694:%.*]] = fadd fast float [[ADD24]], [[MUL21_NEG]]488; CHECK-NEXT: [[SUB28]] = fadd fast float [[SUB2694]], [[MUL20]]489; CHECK-NEXT: [[INC]] = add nuw i32 [[J_098]], 1490; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[ARG_B]]491; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP15]], label [[FOR_BODY16]]492;493entry:494 %cmp1495 = icmp eq i32 %arg_B, 0495 br label %for.body496 497for.cond.cleanup: ; preds = %for.cond.cleanup15498 ret void499 500for.body: ; preds = %for.cond.cleanup15, %entry501 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.cond.cleanup15 ]502 %0 = shl i64 %indvars.iv, 2503 %arrayidx = getelementptr inbounds float, ptr %array, i64 %0504 %1 = load float, ptr %arrayidx, align 4505 %2 = or disjoint i64 %0, 1506 %arrayidx4 = getelementptr inbounds float, ptr %array, i64 %2507 %3 = load float, ptr %arrayidx4, align 4508 %4 = or disjoint i64 %0, 2509 %arrayidx8 = getelementptr inbounds float, ptr %array, i64 %4510 %5 = load float, ptr %arrayidx8, align 4511 %6 = or disjoint i64 %0, 3512 %arrayidx12 = getelementptr inbounds float, ptr %array, i64 %6513 %7 = load float, ptr %arrayidx12, align 4514 br i1 %cmp1495, label %for.cond.cleanup15, label %for.body16.lr.ph515 516for.body16.lr.ph: ; preds = %for.body517 %add.ptr = getelementptr inbounds float, ptr %arg_A, i64 %indvars.iv518 %8 = load float, ptr %add.ptr, align 4519 br label %for.body16520 521for.cond.cleanup15: ; preds = %for.body16, %for.body522 %w2.0.lcssa = phi float [ %5, %for.body ], [ %sub28, %for.body16 ]523 %w3.0.lcssa = phi float [ %7, %for.body ], [ %w2.096, %for.body16 ]524 %w1.0.lcssa = phi float [ %3, %for.body ], [ %w0.0100, %for.body16 ]525 %w0.0.lcssa = phi float [ %1, %for.body ], [ %sub19, %for.body16 ]526 store float %w0.0.lcssa, ptr %arrayidx, align 4527 store float %w1.0.lcssa, ptr %arrayidx4, align 4528 store float %w2.0.lcssa, ptr %arrayidx8, align 4529 store float %w3.0.lcssa, ptr %arrayidx12, align 4530 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1531 %exitcond109 = icmp eq i64 %indvars.iv.next, 6532 br i1 %exitcond109, label %for.cond.cleanup, label %for.body533 534for.body16: ; preds = %for.body16, %for.body16.lr.ph535 %w0.0100 = phi float [ %1, %for.body16.lr.ph ], [ %sub19, %for.body16 ]536 %w1.099 = phi float [ %3, %for.body16.lr.ph ], [ %w0.0100, %for.body16 ]537 %j.098 = phi i32 [ 0, %for.body16.lr.ph ], [ %inc, %for.body16 ]538 %w3.097 = phi float [ %7, %for.body16.lr.ph ], [ %w2.096, %for.body16 ]539 %w2.096 = phi float [ %5, %for.body16.lr.ph ], [ %sub28, %for.body16 ]540 %mul17 = fmul fast float %w0.0100, 0x3FF19999A0000000541 %mul18.neg = fmul fast float %w1.099, 0xBFF3333340000000542 %sub92 = fadd fast float %mul17, %mul18.neg543 %sub19 = fadd fast float %sub92, %8544 %mul20 = fmul fast float %sub19, 0x4000CCCCC0000000545 %mul21.neg = fmul fast float %w0.0100, 0xC0019999A0000000546 %mul23 = fmul fast float %w1.099, 0x4002666660000000547 %mul25 = fmul fast float %w2.096, 0x4008CCCCC0000000548 %mul27.neg = fmul fast float %w3.097, 0xC0099999A0000000549 %add2293 = fadd fast float %mul27.neg, %mul25550 %add24 = fadd fast float %add2293, %mul23551 %sub2694 = fadd fast float %add24, %mul21.neg552 %sub28 = fadd fast float %sub2694, %mul20553 %inc = add nuw i32 %j.098, 1554 %exitcond = icmp eq i32 %inc, %arg_B555 br i1 %exitcond, label %for.cond.cleanup15, label %for.body16556}557 558 559; void foo(double * restrict A, double * restrict B, double * restrict C,560; int n) {561; for (intptr_t i=0; i < n; ++i) {562; C[i] = B[0] *A[i*4 ] + B[1] *A[i*4+1];563; }564; }565 566define void @store_red_double(ptr noalias %A, ptr noalias %B, ptr noalias %C, i32 %n) {567; CHECK-LABEL: @store_red_double(568; CHECK-NEXT: entry:569; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0570; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]571; CHECK: for.body.lr.ph:572; CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[B:%.*]], align 8573; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64574; CHECK-NEXT: br label [[FOR_BODY:%.*]]575; CHECK: for.body:576; CHECK-NEXT: [[I_018:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]577; CHECK-NEXT: [[MUL:%.*]] = shl nsw i64 [[I_018]], 2578; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[MUL]]579; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[ARRAYIDX2]], align 8580; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <2 x double> [[TMP0]], [[TMP2]]581; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x double> [[TMP3]], i32 0582; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x double> [[TMP3]], i32 1583; CHECK-NEXT: [[ADD8:%.*]] = fadd fast double [[TMP4]], [[TMP5]]584; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds double, ptr [[C:%.*]], i64 [[I_018]]585; CHECK-NEXT: store double [[ADD8]], ptr [[ARRAYIDX9]], align 8586; CHECK-NEXT: [[INC]] = add nsw i64 [[I_018]], 1587; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP1]]588; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]]589; CHECK: for.end:590; CHECK-NEXT: ret void591;592entry:593 %cmp17 = icmp sgt i32 %n, 0594 br i1 %cmp17, label %for.body.lr.ph, label %for.end595 596for.body.lr.ph:597 %0 = load double, ptr %B, align 8598 %arrayidx4 = getelementptr inbounds double, ptr %B, i64 1599 %1 = load double, ptr %arrayidx4, align 8600 %2 = sext i32 %n to i64601 br label %for.body602 603for.body:604 %i.018 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]605 %mul = shl nsw i64 %i.018, 2606 %arrayidx2 = getelementptr inbounds double, ptr %A, i64 %mul607 %3 = load double, ptr %arrayidx2, align 8608 %mul3 = fmul fast double %0, %3609 %add16 = or disjoint i64 %mul, 1610 %arrayidx6 = getelementptr inbounds double, ptr %A, i64 %add16611 %4 = load double, ptr %arrayidx6, align 8612 %mul7 = fmul fast double %1, %4613 %add8 = fadd fast double %mul3, %mul7614 %arrayidx9 = getelementptr inbounds double, ptr %C, i64 %i.018615 store double %add8, ptr %arrayidx9, align 8616 %inc = add nsw i64 %i.018, 1617 %exitcond = icmp eq i64 %inc, %2618 br i1 %exitcond, label %for.end, label %for.body619 620for.end:621 ret void622}623 624; int foo(float * restrict A, float * restrict B, float * restrict C, int n) {625; float sum = 0;626; for (intptr_t i=0; i < n; ++i) {627; C[i] = B[0] *A[i*4 ] +628; B[1] *A[i*4+1] +629; B[2] *A[i*4+2] +630; B[3] *A[i*4+3];631; }632; return sum;633; }634 635define i32 @store_red(ptr noalias %A, ptr noalias %B, ptr noalias %C, i32 %n) {636; CHECK-LABEL: @store_red(637; CHECK-NEXT: entry:638; CHECK-NEXT: [[CMP37:%.*]] = icmp sgt i32 [[N:%.*]], 0639; CHECK-NEXT: br i1 [[CMP37]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]640; CHECK: for.body.lr.ph:641; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[N]] to i64642; CHECK-NEXT: br label [[FOR_BODY:%.*]]643; CHECK: for.body:644; CHECK-NEXT: [[I_039:%.*]] = phi i64 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]645; CHECK-NEXT: [[C_ADDR_038:%.*]] = phi ptr [ [[C:%.*]], [[FOR_BODY_LR_PH]] ], [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ]646; CHECK-NEXT: [[MUL:%.*]] = shl nsw i64 [[I_039]], 2647; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[MUL]]648; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[B:%.*]], align 4649; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[ARRAYIDX2]], align 4650; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <4 x float> [[TMP1]], [[TMP2]]651; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP3]])652; CHECK-NEXT: store float [[TMP4]], ptr [[C_ADDR_038]], align 4653; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds float, ptr [[C_ADDR_038]], i64 1654; CHECK-NEXT: [[INC]] = add nsw i64 [[I_039]], 1655; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], [[TMP0]]656; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]]657; CHECK: for.end:658; CHECK-NEXT: ret i32 0659;660entry:661 %cmp37 = icmp sgt i32 %n, 0662 br i1 %cmp37, label %for.body.lr.ph, label %for.end663 664for.body.lr.ph:665 %arrayidx4 = getelementptr inbounds float, ptr %B, i64 1666 %arrayidx9 = getelementptr inbounds float, ptr %B, i64 2667 %arrayidx15 = getelementptr inbounds float, ptr %B, i64 3668 %0 = sext i32 %n to i64669 br label %for.body670 671for.body:672 %i.039 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]673 %C.addr.038 = phi ptr [ %C, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]674 %1 = load float, ptr %B, align 4675 %mul = shl nsw i64 %i.039, 2676 %arrayidx2 = getelementptr inbounds float, ptr %A, i64 %mul677 %2 = load float, ptr %arrayidx2, align 4678 %mul3 = fmul fast float %1, %2679 %3 = load float, ptr %arrayidx4, align 4680 %add34 = or disjoint i64 %mul, 1681 %arrayidx6 = getelementptr inbounds float, ptr %A, i64 %add34682 %4 = load float, ptr %arrayidx6, align 4683 %mul7 = fmul fast float %3, %4684 %add8 = fadd fast float %mul3, %mul7685 %5 = load float, ptr %arrayidx9, align 4686 %add1135 = or disjoint i64 %mul, 2687 %arrayidx12 = getelementptr inbounds float, ptr %A, i64 %add1135688 %6 = load float, ptr %arrayidx12, align 4689 %mul13 = fmul fast float %5, %6690 %add14 = fadd fast float %add8, %mul13691 %7 = load float, ptr %arrayidx15, align 4692 %add1736 = or disjoint i64 %mul, 3693 %arrayidx18 = getelementptr inbounds float, ptr %A, i64 %add1736694 %8 = load float, ptr %arrayidx18, align 4695 %mul19 = fmul fast float %7, %8696 %add20 = fadd fast float %add14, %mul19697 store float %add20, ptr %C.addr.038, align 4698 %incdec.ptr = getelementptr inbounds float, ptr %C.addr.038, i64 1699 %inc = add nsw i64 %i.039, 1700 %exitcond = icmp eq i64 %inc, %0701 br i1 %exitcond, label %for.end, label %for.body702 703for.end:704 ret i32 0705}706 707@arr_i32 = global [32 x i32] zeroinitializer, align 16708@arr_float = global [32 x float] zeroinitializer, align 16709 710define void @float_red_example4(ptr %res) {711; CHECK-LABEL: @float_red_example4(712; CHECK-NEXT: entry:713; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr @arr_float, align 16714; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP0]])715; CHECK-NEXT: store float [[TMP1]], ptr [[RES:%.*]], align 16716; CHECK-NEXT: ret void717;718entry:719 %0 = load float, ptr @arr_float, align 16720 %1 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 1), align 4721 %add = fadd fast float %1, %0722 %2 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 2), align 8723 %add.1 = fadd fast float %2, %add724 %3 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 3), align 4725 %add.2 = fadd fast float %3, %add.1726 store float %add.2, ptr %res, align 16727 ret void728}729 730define void @float_red_example8(ptr %res) {731; CHECK-LABEL: @float_red_example8(732; CHECK-NEXT: entry:733; CHECK-NEXT: [[TMP0:%.*]] = load <8 x float>, ptr @arr_float, align 16734; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.vector.reduce.fadd.v8f32(float 0.000000e+00, <8 x float> [[TMP0]])735; CHECK-NEXT: store float [[TMP1]], ptr [[RES:%.*]], align 16736; CHECK-NEXT: ret void737;738entry:739 %0 = load float, ptr @arr_float, align 16740 %1 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 1), align 4741 %add = fadd fast float %1, %0742 %2 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 2), align 8743 %add.1 = fadd fast float %2, %add744 %3 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 3), align 4745 %add.2 = fadd fast float %3, %add.1746 %4 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 4), align 16747 %add.3 = fadd fast float %4, %add.2748 %5 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 5), align 4749 %add.4 = fadd fast float %5, %add.3750 %6 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 6), align 8751 %add.5 = fadd fast float %6, %add.4752 %7 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 7), align 4753 %add.6 = fadd fast float %7, %add.5754 store float %add.6, ptr %res, align 16755 ret void756}757 758define void @float_red_example16(ptr %res) {759; CHECK-LABEL: @float_red_example16(760; CHECK-NEXT: entry:761; CHECK-NEXT: [[TMP0:%.*]] = load <16 x float>, ptr @arr_float, align 16762; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.vector.reduce.fadd.v16f32(float 0.000000e+00, <16 x float> [[TMP0]])763; CHECK-NEXT: store float [[TMP1]], ptr [[RES:%.*]], align 16764; CHECK-NEXT: ret void765;766entry:767 %0 = load float, ptr @arr_float, align 16768 %1 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 1), align 4769 %add = fadd fast float %1, %0770 %2 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 2), align 8771 %add.1 = fadd fast float %2, %add772 %3 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 3), align 4773 %add.2 = fadd fast float %3, %add.1774 %4 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 4), align 16775 %add.3 = fadd fast float %4, %add.2776 %5 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 5), align 4777 %add.4 = fadd fast float %5, %add.3778 %6 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 6), align 8779 %add.5 = fadd fast float %6, %add.4780 %7 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 7), align 4781 %add.6 = fadd fast float %7, %add.5782 %8 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 8), align 16783 %add.7 = fadd fast float %8, %add.6784 %9 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 9), align 4785 %add.8 = fadd fast float %9, %add.7786 %10 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 10), align 8787 %add.9 = fadd fast float %10, %add.8788 %11 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 11), align 4789 %add.10 = fadd fast float %11, %add.9790 %12 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 12), align 16791 %add.11 = fadd fast float %12, %add.10792 %13 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 13), align 4793 %add.12 = fadd fast float %13, %add.11794 %14 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 14), align 8795 %add.13 = fadd fast float %14, %add.12796 %15 = load float, ptr getelementptr inbounds ([32 x float], ptr @arr_float, i64 0, i64 15), align 4797 %add.14 = fadd fast float %15, %add.13798 store float %add.14, ptr %res, align 16799 ret void800}801 802define void @i32_red_example4(ptr %res) {803; CHECK-LABEL: @i32_red_example4(804; CHECK-NEXT: entry:805; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr @arr_i32, align 16806; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP0]])807; CHECK-NEXT: store i32 [[TMP1]], ptr [[RES:%.*]], align 16808; CHECK-NEXT: ret void809;810entry:811 %0 = load i32, ptr @arr_i32, align 16812 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 4813 %add = add nsw i32 %1, %0814 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 8815 %add.1 = add nsw i32 %2, %add816 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 4817 %add.2 = add nsw i32 %3, %add.1818 store i32 %add.2, ptr %res, align 16819 ret void820}821 822define void @i32_red_example8(ptr %res) {823; CHECK-LABEL: @i32_red_example8(824; CHECK-NEXT: entry:825; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @arr_i32, align 16826; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP0]])827; CHECK-NEXT: store i32 [[TMP1]], ptr [[RES:%.*]], align 16828; CHECK-NEXT: ret void829;830entry:831 %0 = load i32, ptr @arr_i32, align 16832 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 4833 %add = add nsw i32 %1, %0834 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 8835 %add.1 = add nsw i32 %2, %add836 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 4837 %add.2 = add nsw i32 %3, %add.1838 %4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 4), align 16839 %add.3 = add nsw i32 %4, %add.2840 %5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 5), align 4841 %add.4 = add nsw i32 %5, %add.3842 %6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 6), align 8843 %add.5 = add nsw i32 %6, %add.4844 %7 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 7), align 4845 %add.6 = add nsw i32 %7, %add.5846 store i32 %add.6, ptr %res, align 16847 ret void848}849 850define void @i32_red_example16(ptr %res) {851; CHECK-LABEL: @i32_red_example16(852; CHECK-NEXT: entry:853; CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr @arr_i32, align 16854; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP0]])855; CHECK-NEXT: store i32 [[TMP1]], ptr [[RES:%.*]], align 16856; CHECK-NEXT: ret void857;858entry:859 %0 = load i32, ptr @arr_i32, align 16860 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 4861 %add = add nsw i32 %1, %0862 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 8863 %add.1 = add nsw i32 %2, %add864 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 4865 %add.2 = add nsw i32 %3, %add.1866 %4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 4), align 16867 %add.3 = add nsw i32 %4, %add.2868 %5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 5), align 4869 %add.4 = add nsw i32 %5, %add.3870 %6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 6), align 8871 %add.5 = add nsw i32 %6, %add.4872 %7 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 7), align 4873 %add.6 = add nsw i32 %7, %add.5874 %8 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 8), align 16875 %add.7 = add nsw i32 %8, %add.6876 %9 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 9), align 4877 %add.8 = add nsw i32 %9, %add.7878 %10 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 10), align 8879 %add.9 = add nsw i32 %10, %add.8880 %11 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 11), align 4881 %add.10 = add nsw i32 %11, %add.9882 %12 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 12), align 16883 %add.11 = add nsw i32 %12, %add.10884 %13 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 13), align 4885 %add.12 = add nsw i32 %13, %add.11886 %14 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 14), align 8887 %add.13 = add nsw i32 %14, %add.12888 %15 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 15), align 4889 %add.14 = add nsw i32 %15, %add.13890 store i32 %add.14, ptr %res, align 16891 ret void892}893 894define void @i32_red_example32(ptr %res) {895; CHECK-LABEL: @i32_red_example32(896; CHECK-NEXT: entry:897; CHECK-NEXT: [[TMP0:%.*]] = load <32 x i32>, ptr @arr_i32, align 16898; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> [[TMP0]])899; CHECK-NEXT: store i32 [[TMP1]], ptr [[RES:%.*]], align 16900; CHECK-NEXT: ret void901;902entry:903 %0 = load i32, ptr @arr_i32, align 16904 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 4905 %add = add nsw i32 %1, %0906 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 8907 %add.1 = add nsw i32 %2, %add908 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 4909 %add.2 = add nsw i32 %3, %add.1910 %4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 4), align 16911 %add.3 = add nsw i32 %4, %add.2912 %5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 5), align 4913 %add.4 = add nsw i32 %5, %add.3914 %6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 6), align 8915 %add.5 = add nsw i32 %6, %add.4916 %7 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 7), align 4917 %add.6 = add nsw i32 %7, %add.5918 %8 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 8), align 16919 %add.7 = add nsw i32 %8, %add.6920 %9 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 9), align 4921 %add.8 = add nsw i32 %9, %add.7922 %10 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 10), align 8923 %add.9 = add nsw i32 %10, %add.8924 %11 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 11), align 4925 %add.10 = add nsw i32 %11, %add.9926 %12 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 12), align 16927 %add.11 = add nsw i32 %12, %add.10928 %13 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 13), align 4929 %add.12 = add nsw i32 %13, %add.11930 %14 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 14), align 8931 %add.13 = add nsw i32 %14, %add.12932 %15 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 15), align 4933 %add.14 = add nsw i32 %15, %add.13934 %16 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 16), align 16935 %add.15 = add nsw i32 %16, %add.14936 %17 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 17), align 4937 %add.16 = add nsw i32 %17, %add.15938 %18 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 18), align 8939 %add.17 = add nsw i32 %18, %add.16940 %19 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 19), align 4941 %add.18 = add nsw i32 %19, %add.17942 %20 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 20), align 16943 %add.19 = add nsw i32 %20, %add.18944 %21 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 21), align 4945 %add.20 = add nsw i32 %21, %add.19946 %22 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 22), align 8947 %add.21 = add nsw i32 %22, %add.20948 %23 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 23), align 4949 %add.22 = add nsw i32 %23, %add.21950 %24 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 24), align 16951 %add.23 = add nsw i32 %24, %add.22952 %25 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 25), align 4953 %add.24 = add nsw i32 %25, %add.23954 %26 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 26), align 8955 %add.25 = add nsw i32 %26, %add.24956 %27 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 27), align 4957 %add.26 = add nsw i32 %27, %add.25958 %28 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 28), align 16959 %add.27 = add nsw i32 %28, %add.26960 %29 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 29), align 4961 %add.28 = add nsw i32 %29, %add.27962 %30 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 30), align 8963 %add.29 = add nsw i32 %30, %add.28964 %31 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 31), align 4965 %add.30 = add nsw i32 %31, %add.29966 store i32 %add.30, ptr %res, align 16967 ret void968}969 970declare i32 @foobar(i32)971 972define void @i32_red_call(i32 %val) {973; CHECK-LABEL: @i32_red_call(974; CHECK-NEXT: entry:975; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @arr_i32, align 16976; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP0]])977; CHECK-NEXT: [[RES:%.*]] = call i32 @foobar(i32 [[TMP1]])978; CHECK-NEXT: ret void979;980entry:981 %0 = load i32, ptr @arr_i32, align 16982 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 4983 %add = add nsw i32 %1, %0984 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 8985 %add.1 = add nsw i32 %2, %add986 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 4987 %add.2 = add nsw i32 %3, %add.1988 %4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 4), align 16989 %add.3 = add nsw i32 %4, %add.2990 %5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 5), align 4991 %add.4 = add nsw i32 %5, %add.3992 %6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 6), align 8993 %add.5 = add nsw i32 %6, %add.4994 %7 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 7), align 4995 %add.6 = add nsw i32 %7, %add.5996 %res = call i32 @foobar(i32 %add.6)997 ret void998}999 1000define void @i32_red_invoke(i32 %val) personality ptr @__gxx_personality_v0 {1001; CHECK-LABEL: @i32_red_invoke(1002; CHECK-NEXT: entry:1003; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @arr_i32, align 161004; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP0]])1005; CHECK-NEXT: [[RES:%.*]] = invoke i32 @foobar(i32 [[TMP1]])1006; CHECK-NEXT: to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]1007; CHECK: exception:1008; CHECK-NEXT: [[CLEANUP:%.*]] = landingpad i81009; CHECK-NEXT: cleanup1010; CHECK-NEXT: br label [[NORMAL]]1011; CHECK: normal:1012; CHECK-NEXT: ret void1013;1014entry:1015 %0 = load i32, ptr @arr_i32, align 161016 %1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 41017 %add = add nsw i32 %1, %01018 %2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 81019 %add.1 = add nsw i32 %2, %add1020 %3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 41021 %add.2 = add nsw i32 %3, %add.11022 %4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 4), align 161023 %add.3 = add nsw i32 %4, %add.21024 %5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 5), align 41025 %add.4 = add nsw i32 %5, %add.31026 %6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 6), align 81027 %add.5 = add nsw i32 %6, %add.41028 %7 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 7), align 41029 %add.6 = add nsw i32 %7, %add.51030 %res = invoke i32 @foobar(i32 %add.6) to label %normal unwind label %exception1031exception:1032 %cleanup = landingpad i8 cleanup1033 br label %normal1034normal:1035 ret void1036}1037 1038; Test case from PR47670. Reduction result is used as incoming value in phi.1039define i32 @reduction_result_used_in_phi(ptr nocapture readonly %data, i1 zeroext %b) {1040; CHECK-LABEL: @reduction_result_used_in_phi(1041; CHECK-NEXT: entry:1042; CHECK-NEXT: br i1 [[B:%.*]], label [[BB:%.*]], label [[EXIT:%.*]]1043; CHECK: bb:1044; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[DATA:%.*]], align 41045; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP0]])1046; CHECK-NEXT: br label [[EXIT]]1047; CHECK: exit:1048; CHECK-NEXT: [[SUM_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[BB]] ]1049; CHECK-NEXT: ret i32 [[SUM_1]]1050;1051entry:1052 br i1 %b, label %bb, label %exit1053 1054bb:1055 %l.0 = load i32, ptr %data, align 41056 %idx.1 = getelementptr inbounds i32, ptr %data, i64 11057 %l.1 = load i32, ptr %idx.1, align 41058 %add.1 = add i32 %l.1, %l.01059 %idx.2 = getelementptr inbounds i32, ptr %data, i64 21060 %l.2 = load i32, ptr %idx.2, align 41061 %add.2 = add i32 %l.2, %add.11062 %idx.3 = getelementptr inbounds i32, ptr %data, i64 31063 %l.3 = load i32, ptr %idx.3, align 41064 %add.3 = add i32 %l.3, %add.21065 br label %exit1066 1067exit:1068 %sum.1 = phi i32 [ 0, %entry ], [ %add.3, %bb]1069 ret i32 %sum.11070}1071 1072define i32 @reduction_result_used_in_phi_loop(ptr nocapture readonly %data, i1 zeroext %b) {1073; CHECK-LABEL: @reduction_result_used_in_phi_loop(1074; CHECK-NEXT: entry:1075; CHECK-NEXT: br i1 [[B:%.*]], label [[BB:%.*]], label [[EXIT:%.*]]1076; CHECK: bb:1077; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[DATA:%.*]], align 41078; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP0]])1079; CHECK-NEXT: br label [[EXIT]]1080; CHECK: exit:1081; CHECK-NEXT: [[SUM_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[BB]] ]1082; CHECK-NEXT: ret i32 [[SUM_1]]1083;1084entry:1085 br i1 %b, label %bb, label %exit1086 1087bb:1088 %l.0 = load i32, ptr %data, align 41089 %idx.1 = getelementptr inbounds i32, ptr %data, i64 11090 %l.1 = load i32, ptr %idx.1, align 41091 %add.1 = add i32 %l.1, %l.01092 %idx.2 = getelementptr inbounds i32, ptr %data, i64 21093 %l.2 = load i32, ptr %idx.2, align 41094 %add.2 = add i32 %l.2, %add.11095 %idx.3 = getelementptr inbounds i32, ptr %data, i64 31096 %l.3 = load i32, ptr %idx.3, align 41097 %add.3 = add i32 %l.3, %add.21098 br label %exit1099 1100exit:1101 %sum.1 = phi i32 [ 0, %entry ], [ %add.3, %bb]1102 ret i32 %sum.11103}1104 1105; Make sure we do not crash or infinite loop on ill-formed IR.1106 1107define void @unreachable_block() {1108; CHECK-LABEL: @unreachable_block(1109; CHECK-NEXT: bb.0:1110; CHECK-NEXT: br label [[BB_1:%.*]]1111; CHECK: dead:1112; CHECK-NEXT: [[T0:%.*]] = add i16 [[T0]], undef1113; CHECK-NEXT: br label [[BB_1]]1114; CHECK: bb.1:1115; CHECK-NEXT: [[T1:%.*]] = phi i16 [ undef, [[BB_0:%.*]] ], [ [[T0]], [[DEAD:%.*]] ]1116; CHECK-NEXT: ret void1117;1118bb.0:1119 br label %bb.11120 1121dead:1122 %t0 = add i16 %t0, undef ; unreachable IR may depend on itself1123 br label %bb.11124 1125bb.1:1126 %t1 = phi i16 [ undef, %bb.0 ], [ %t0, %dead ]1127 ret void1128}1129 1130; The FMF on the reduction should match the incoming insts.1131 1132define float @fadd_v4f32_fmf(ptr %p) {1133; CHECK-LABEL: @fadd_v4f32_fmf(1134; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[P:%.*]], align 41135; CHECK-NEXT: [[TMP2:%.*]] = call reassoc nsz float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP1]])1136; CHECK-NEXT: ret float [[TMP2]]1137;1138 %p1 = getelementptr inbounds float, ptr %p, i64 11139 %p2 = getelementptr inbounds float, ptr %p, i64 21140 %p3 = getelementptr inbounds float, ptr %p, i64 31141 %t0 = load float, ptr %p, align 41142 %t1 = load float, ptr %p1, align 41143 %t2 = load float, ptr %p2, align 41144 %t3 = load float, ptr %p3, align 41145 %add1 = fadd reassoc nsz float %t1, %t01146 %add2 = fadd reassoc nsz float %t2, %add11147 %add3 = fadd reassoc nsz float %t3, %add21148 ret float %add31149}1150 1151; The minimal FMF for fadd reduction are "reassoc nsz".1152; Only the common FMF of all operations in the reduction propagate to the result.1153; In this example, "contract nnan arcp" are dropped, but "ninf" transfers with the required flags.1154 1155define float @fadd_v4f32_fmf_intersect(ptr %p) {1156; CHECK-LABEL: @fadd_v4f32_fmf_intersect(1157; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[P:%.*]], align 41158; CHECK-NEXT: [[TMP2:%.*]] = call reassoc ninf nsz float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[TMP1]])1159; CHECK-NEXT: ret float [[TMP2]]1160;1161 %p1 = getelementptr inbounds float, ptr %p, i64 11162 %p2 = getelementptr inbounds float, ptr %p, i64 21163 %p3 = getelementptr inbounds float, ptr %p, i64 31164 %t0 = load float, ptr %p, align 41165 %t1 = load float, ptr %p1, align 41166 %t2 = load float, ptr %p2, align 41167 %t3 = load float, ptr %p3, align 41168 %add1 = fadd ninf reassoc nsz nnan float %t1, %t01169 %add2 = fadd ninf reassoc nsz nnan arcp float %t2, %add11170 %add3 = fadd ninf reassoc nsz contract float %t3, %add21171 ret float %add31172}1173 1174; This must not propagate 'nsw' to a new add instruction.1175 1176define void @nsw_propagation_v4i32(ptr %res, i32 %start) {1177; CHECK-LABEL: @nsw_propagation_v4i32(1178; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @arr_i32, align 161179; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP1]])1180; CHECK-NEXT: [[OP_RDX:%.*]] = add i32 [[TMP2]], [[START:%.*]]1181; CHECK-NEXT: store i32 [[OP_RDX]], ptr [[RES:%.*]], align 161182; CHECK-NEXT: ret void1183;1184 1185; STORE-LABEL: @nsw_propagation_v4i32(1186; STORE-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @arr_i32, align 161187; STORE-NEXT: [[TMP2:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP1]])1188; STORE-NEXT: [[OP_RDX:%.*]] = add i32 [[START:%.*]], [[TMP2]]1189; STORE-NEXT: store i32 [[OP_RDX]], ptr [[RES:%.*]], align 161190; STORE-NEXT: ret void1191 %t0 = load i32, ptr @arr_i32, align 161192 %t1 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 1), align 41193 %t2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 2), align 81194 %t3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr_i32, i64 0, i64 3), align 41195 %s = add nsw i32 %start, %t01196 %add = add nsw i32 %t1, %s1197 %add.1 = add nsw i32 %t2, %add1198 %add.2 = add nsw i32 %t3, %add.11199 store i32 %add.2, ptr %res, align 161200 ret void1201}1202 1203declare i32 @__gxx_personality_v0(...)1204