170 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=loop-vectorize -mtriple=x86_64-apple-darwin %s | FileCheck %s --check-prefixes=CHECK,SSE3; RUN: opt -S -passes=loop-vectorize -mtriple=x86_64-apple-darwin -mattr=+avx %s | FileCheck %s --check-prefixes=CHECK,AVX4 5; Two mostly identical functions. The only difference is the presence of6; fast-math flags on the second. The loop is a pretty simple reduction:7 8; for (int i = 0; i < 32; ++i)9; if (arr[i] != 42)10; tot += arr[i];11 12define double @sumIfScalar(ptr nocapture readonly %arr) {13; CHECK-LABEL: @sumIfScalar(14; CHECK-NEXT: entry:15; CHECK-NEXT: br label [[LOOP:%.*]]16; CHECK: loop:17; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[NEXT_ITER:%.*]] ]18; CHECK-NEXT: [[TOT:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[TOT_NEXT:%.*]], [[NEXT_ITER]] ]19; CHECK-NEXT: [[ADDR:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[I]]20; CHECK-NEXT: [[NEXTVAL:%.*]] = load double, ptr [[ADDR]], align 821; CHECK-NEXT: [[TST:%.*]] = fcmp une double [[NEXTVAL]], 4.200000e+0122; CHECK-NEXT: br i1 [[TST]], label [[DO_ADD:%.*]], label [[NO_ADD:%.*]]23; CHECK: do.add:24; CHECK-NEXT: [[TOT_NEW:%.*]] = fadd double [[TOT]], [[NEXTVAL]]25; CHECK-NEXT: br label [[NEXT_ITER]]26; CHECK: no.add:27; CHECK-NEXT: br label [[NEXT_ITER]]28; CHECK: next.iter:29; CHECK-NEXT: [[TOT_NEXT]] = phi double [ [[TOT]], [[NO_ADD]] ], [ [[TOT_NEW]], [[DO_ADD]] ]30; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 131; CHECK-NEXT: [[AGAIN:%.*]] = icmp ult i32 [[I_NEXT]], 3232; CHECK-NEXT: br i1 [[AGAIN]], label [[LOOP]], label [[DONE:%.*]]33; CHECK: done:34; CHECK-NEXT: [[TOT_NEXT_LCSSA:%.*]] = phi double [ [[TOT_NEXT]], [[NEXT_ITER]] ]35; CHECK-NEXT: ret double [[TOT_NEXT_LCSSA]]36;37entry:38 br label %loop39 40loop:41 %i = phi i32 [0, %entry], [%i.next, %next.iter]42 %tot = phi double [0.0, %entry], [%tot.next, %next.iter]43 44 %addr = getelementptr double, ptr %arr, i32 %i45 %nextval = load double, ptr %addr46 47 %tst = fcmp une double %nextval, 42.048 br i1 %tst, label %do.add, label %no.add49 50do.add:51 %tot.new = fadd double %tot, %nextval52 br label %next.iter53 54no.add:55 br label %next.iter56 57next.iter:58 %tot.next = phi double [%tot, %no.add], [%tot.new, %do.add]59 %i.next = add i32 %i, 160 %again = icmp ult i32 %i.next, 3261 br i1 %again, label %loop, label %done62 63done:64 ret double %tot.next65}66 67define double @sumIfVector(ptr nocapture readonly %arr) {68; SSE-LABEL: @sumIfVector(69; SSE-NEXT: entry:70; SSE-NEXT: br label [[VECTOR_PH:%.*]]71; SSE: vector.ph:72; SSE-NEXT: br label [[VECTOR_BODY:%.*]]73; SSE: vector.body:74; SSE-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]75; SSE-NEXT: [[VEC_PHI:%.*]] = phi <2 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[VECTOR_BODY]] ]76; SSE-NEXT: [[VEC_PHI1:%.*]] = phi <2 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI3:%.*]], [[VECTOR_BODY]] ]77; SSE-NEXT: [[TMP2:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[INDEX]]78; SSE-NEXT: [[TMP5:%.*]] = getelementptr double, ptr [[TMP2]], i64 279; SSE-NEXT: [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP2]], align 880; SSE-NEXT: [[WIDE_LOAD2:%.*]] = load <2 x double>, ptr [[TMP5]], align 881; SSE-NEXT: [[TMP6:%.*]] = fcmp fast une <2 x double> [[WIDE_LOAD]], splat (double 4.200000e+01)82; SSE-NEXT: [[TMP7:%.*]] = fcmp fast une <2 x double> [[WIDE_LOAD2]], splat (double 4.200000e+01)83; SSE-NEXT: [[TMP8:%.*]] = fadd fast <2 x double> [[VEC_PHI]], [[WIDE_LOAD]]84; SSE-NEXT: [[TMP9:%.*]] = fadd fast <2 x double> [[VEC_PHI1]], [[WIDE_LOAD2]]85; SSE-NEXT: [[PREDPHI]] = select <2 x i1> [[TMP6]], <2 x double> [[TMP8]], <2 x double> [[VEC_PHI]]86; SSE-NEXT: [[PREDPHI3]] = select <2 x i1> [[TMP7]], <2 x double> [[TMP9]], <2 x double> [[VEC_PHI1]]87; SSE-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 488; SSE-NEXT: [[TMP10:%.*]] = icmp eq i32 [[INDEX_NEXT]], 3289; SSE-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]90; SSE: middle.block:91; SSE-NEXT: [[BIN_RDX:%.*]] = fadd fast <2 x double> [[PREDPHI3]], [[PREDPHI]]92; SSE-NEXT: [[TMP11:%.*]] = call fast double @llvm.vector.reduce.fadd.v2f64(double 0.000000e+00, <2 x double> [[BIN_RDX]])93; SSE-NEXT: br label [[NEXT_ITER:%.*]]94; SSE: done:95; SSE-NEXT: ret double [[TMP11]]96;97; AVX-LABEL: @sumIfVector(98; AVX-NEXT: entry:99; AVX-NEXT: br label [[VECTOR_PH:%.*]]100; AVX: vector.ph:101; AVX-NEXT: br label [[VECTOR_BODY:%.*]]102; AVX: vector.body:103; AVX-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]104; AVX-NEXT: [[VEC_PHI:%.*]] = phi <4 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[VECTOR_BODY]] ]105; AVX-NEXT: [[VEC_PHI1:%.*]] = phi <4 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI7:%.*]], [[VECTOR_BODY]] ]106; AVX-NEXT: [[VEC_PHI2:%.*]] = phi <4 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI8:%.*]], [[VECTOR_BODY]] ]107; AVX-NEXT: [[VEC_PHI3:%.*]] = phi <4 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI9:%.*]], [[VECTOR_BODY]] ]108; AVX-NEXT: [[TMP4:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[INDEX]]109; AVX-NEXT: [[TMP9:%.*]] = getelementptr double, ptr [[TMP4]], i64 4110; AVX-NEXT: [[TMP10:%.*]] = getelementptr double, ptr [[TMP4]], i64 8111; AVX-NEXT: [[TMP11:%.*]] = getelementptr double, ptr [[TMP4]], i64 12112; AVX-NEXT: [[WIDE_LOAD:%.*]] = load <4 x double>, ptr [[TMP4]], align 8113; AVX-NEXT: [[WIDE_LOAD4:%.*]] = load <4 x double>, ptr [[TMP9]], align 8114; AVX-NEXT: [[WIDE_LOAD5:%.*]] = load <4 x double>, ptr [[TMP10]], align 8115; AVX-NEXT: [[WIDE_LOAD6:%.*]] = load <4 x double>, ptr [[TMP11]], align 8116; AVX-NEXT: [[TMP12:%.*]] = fcmp fast une <4 x double> [[WIDE_LOAD]], splat (double 4.200000e+01)117; AVX-NEXT: [[TMP13:%.*]] = fcmp fast une <4 x double> [[WIDE_LOAD4]], splat (double 4.200000e+01)118; AVX-NEXT: [[TMP14:%.*]] = fcmp fast une <4 x double> [[WIDE_LOAD5]], splat (double 4.200000e+01)119; AVX-NEXT: [[TMP15:%.*]] = fcmp fast une <4 x double> [[WIDE_LOAD6]], splat (double 4.200000e+01)120; AVX-NEXT: [[TMP16:%.*]] = fadd fast <4 x double> [[VEC_PHI]], [[WIDE_LOAD]]121; AVX-NEXT: [[TMP17:%.*]] = fadd fast <4 x double> [[VEC_PHI1]], [[WIDE_LOAD4]]122; AVX-NEXT: [[TMP18:%.*]] = fadd fast <4 x double> [[VEC_PHI2]], [[WIDE_LOAD5]]123; AVX-NEXT: [[TMP19:%.*]] = fadd fast <4 x double> [[VEC_PHI3]], [[WIDE_LOAD6]]124; AVX-NEXT: [[PREDPHI]] = select <4 x i1> [[TMP12]], <4 x double> [[TMP16]], <4 x double> [[VEC_PHI]]125; AVX-NEXT: [[PREDPHI7]] = select <4 x i1> [[TMP13]], <4 x double> [[TMP17]], <4 x double> [[VEC_PHI1]]126; AVX-NEXT: [[PREDPHI8]] = select <4 x i1> [[TMP14]], <4 x double> [[TMP18]], <4 x double> [[VEC_PHI2]]127; AVX-NEXT: [[PREDPHI9]] = select <4 x i1> [[TMP15]], <4 x double> [[TMP19]], <4 x double> [[VEC_PHI3]]128; AVX-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 16129; AVX-NEXT: [[TMP20:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32130; AVX-NEXT: br i1 [[TMP20]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]131; AVX: middle.block:132; AVX-NEXT: [[BIN_RDX:%.*]] = fadd fast <4 x double> [[PREDPHI7]], [[PREDPHI]]133; AVX-NEXT: [[BIN_RDX10:%.*]] = fadd fast <4 x double> [[PREDPHI8]], [[BIN_RDX]]134; AVX-NEXT: [[BIN_RDX11:%.*]] = fadd fast <4 x double> [[PREDPHI9]], [[BIN_RDX10]]135; AVX-NEXT: [[TMP21:%.*]] = call fast double @llvm.vector.reduce.fadd.v4f64(double 0.000000e+00, <4 x double> [[BIN_RDX11]])136; AVX-NEXT: br label [[NEXT_ITER:%.*]]137; AVX: done:138; AVX-NEXT: ret double [[TMP21]]139;140entry:141 br label %loop142 143loop:144 %i = phi i32 [0, %entry], [%i.next, %next.iter]145 %tot = phi double [0.0, %entry], [%tot.next, %next.iter]146 147 %addr = getelementptr double, ptr %arr, i32 %i148 %nextval = load double, ptr %addr149 150 %tst = fcmp fast une double %nextval, 42.0151 br i1 %tst, label %do.add, label %no.add152 153do.add:154 %tot.new = fadd fast double %tot, %nextval155 br label %next.iter156 157no.add:158 br label %next.iter159 160next.iter:161 %tot.next = phi double [%tot, %no.add], [%tot.new, %do.add]162 %i.next = add i32 %i, 1163 %again = icmp ult i32 %i.next, 32164 br i1 %again, label %loop, label %done165 166done:167 ret double %tot.next168}169 170