brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.5 KiB · 41249c5 Raw
420 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; RUN: opt -passes=loop-vectorize -mcpu=core-avx2 -mtriple=x86_64-unknown-linux-gnu -S %s | FileCheck --check-prefix AUTO_VEC %s3 4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"5 6; This test checks auto-vectorization with FP induction variable.7; FMF is required on the IR instructions.8 9;void fp_iv_loop1(ptr __restrict__ A, int N) {10;  float x = 1.0;11;  for (int i=0; i < N; ++i) {12;    A[i] = x;13;    x += 0.5;14;  }15;}16 17define void @fp_iv_loop1(ptr noalias nocapture %A, i32 %N) #0 {18; AUTO_VEC-LABEL: define void @fp_iv_loop1(19; AUTO_VEC-SAME: ptr noalias captures(none) [[A:%.*]], i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {20; AUTO_VEC-NEXT:  [[ENTRY:.*:]]21; AUTO_VEC-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[N]], 022; AUTO_VEC-NEXT:    br i1 [[CMP4]], label %[[ITER_CHECK:.*]], label %[[FOR_END:.*]]23; AUTO_VEC:       [[ITER_CHECK]]:24; AUTO_VEC-NEXT:    [[TMP0:%.*]] = zext i32 [[N]] to i6425; AUTO_VEC-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 426; AUTO_VEC-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[VEC_EPILOG_SCALAR_PH:.*]], label %[[VECTOR_MAIN_LOOP_ITER_CHECK:.*]]27; AUTO_VEC:       [[VECTOR_MAIN_LOOP_ITER_CHECK]]:28; AUTO_VEC-NEXT:    [[MIN_ITERS_CHECK1:%.*]] = icmp ult i64 [[TMP0]], 3229; AUTO_VEC-NEXT:    br i1 [[MIN_ITERS_CHECK1]], label %[[VEC_EPILOG_PH:.*]], label %[[VECTOR_PH:.*]]30; AUTO_VEC:       [[VECTOR_PH]]:31; AUTO_VEC-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 3232; AUTO_VEC-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]33; AUTO_VEC-NEXT:    [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float34; AUTO_VEC-NEXT:    [[TMP6:%.*]] = fmul fast float 5.000000e-01, [[DOTCAST]]35; AUTO_VEC-NEXT:    [[IND_END:%.*]] = fadd fast float 1.000000e+00, [[TMP6]]36; AUTO_VEC-NEXT:    br label %[[VECTOR_BODY:.*]]37; AUTO_VEC:       [[VECTOR_BODY]]:38; AUTO_VEC-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]39; AUTO_VEC-NEXT:    [[VEC_IND:%.*]] = phi <8 x float> [ <float 1.000000e+00, float 1.500000e+00, float 2.000000e+00, float 2.500000e+00, float 3.000000e+00, float 3.500000e+00, float 4.000000e+00, float 4.500000e+00>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]40; AUTO_VEC-NEXT:    [[STEP_ADD:%.*]] = fadd fast <8 x float> [[VEC_IND]], splat (float 4.000000e+00)41; AUTO_VEC-NEXT:    [[STEP_ADD2:%.*]] = fadd fast <8 x float> [[STEP_ADD]], splat (float 4.000000e+00)42; AUTO_VEC-NEXT:    [[STEP_ADD3:%.*]] = fadd fast <8 x float> [[STEP_ADD2]], splat (float 4.000000e+00)43; AUTO_VEC-NEXT:    [[TMP1:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX]]44; AUTO_VEC-NEXT:    [[TMP2:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i64 845; AUTO_VEC-NEXT:    [[TMP3:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i64 1646; AUTO_VEC-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i64 2447; AUTO_VEC-NEXT:    store <8 x float> [[VEC_IND]], ptr [[TMP1]], align 448; AUTO_VEC-NEXT:    store <8 x float> [[STEP_ADD]], ptr [[TMP2]], align 449; AUTO_VEC-NEXT:    store <8 x float> [[STEP_ADD2]], ptr [[TMP3]], align 450; AUTO_VEC-NEXT:    store <8 x float> [[STEP_ADD3]], ptr [[TMP4]], align 451; AUTO_VEC-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 3252; AUTO_VEC-NEXT:    [[VEC_IND_NEXT]] = fadd fast <8 x float> [[STEP_ADD3]], splat (float 4.000000e+00)53; AUTO_VEC-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]54; AUTO_VEC-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]55; AUTO_VEC:       [[MIDDLE_BLOCK]]:56; AUTO_VEC-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]57; AUTO_VEC-NEXT:    br i1 [[CMP_N]], label %[[FOR_END_LOOPEXIT:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]]58; AUTO_VEC:       [[VEC_EPILOG_ITER_CHECK]]:59; AUTO_VEC-NEXT:    [[DOTCAST12:%.*]] = sitofp i64 [[N_VEC]] to float60; AUTO_VEC-NEXT:    [[TMP11:%.*]] = fmul fast float 5.000000e-01, [[DOTCAST12]]61; AUTO_VEC-NEXT:    [[IND_END1:%.*]] = fadd fast float 1.000000e+00, [[TMP11]]62; AUTO_VEC-NEXT:    [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp ult i64 [[N_MOD_VF]], 463; AUTO_VEC-NEXT:    br i1 [[MIN_EPILOG_ITERS_CHECK]], label %[[VEC_EPILOG_SCALAR_PH]], label %[[VEC_EPILOG_PH]], !prof [[PROF3:![0-9]+]]64; AUTO_VEC:       [[VEC_EPILOG_PH]]:65; AUTO_VEC-NEXT:    [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 0, %[[VECTOR_MAIN_LOOP_ITER_CHECK]] ]66; AUTO_VEC-NEXT:    [[BC_RESUME_VAL:%.*]] = phi float [ [[IND_END]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 1.000000e+00, %[[VECTOR_MAIN_LOOP_ITER_CHECK]] ]67; AUTO_VEC-NEXT:    [[N_MOD_VF2:%.*]] = urem i64 [[TMP0]], 468; AUTO_VEC-NEXT:    [[N_VEC3:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF2]]69; AUTO_VEC-NEXT:    [[DOTCAST4:%.*]] = sitofp i64 [[N_VEC3]] to float70; AUTO_VEC-NEXT:    [[TMP12:%.*]] = fmul fast float 5.000000e-01, [[DOTCAST4]]71; AUTO_VEC-NEXT:    [[TMP10:%.*]] = fadd fast float 1.000000e+00, [[TMP12]]72; AUTO_VEC-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[BC_RESUME_VAL]], i64 073; AUTO_VEC-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <4 x float> [[DOTSPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer74; AUTO_VEC-NEXT:    [[INDUCTION:%.*]] = fadd fast <4 x float> [[DOTSPLAT]], <float 0.000000e+00, float 5.000000e-01, float 1.000000e+00, float 1.500000e+00>75; AUTO_VEC-NEXT:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]76; AUTO_VEC:       [[VEC_EPILOG_VECTOR_BODY]]:77; AUTO_VEC-NEXT:    [[INDEX10:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], %[[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT13:%.*]], %[[VEC_EPILOG_VECTOR_BODY]] ]78; AUTO_VEC-NEXT:    [[VEC_IND11:%.*]] = phi <4 x float> [ [[INDUCTION]], %[[VEC_EPILOG_PH]] ], [ [[VEC_IND_NEXT12:%.*]], %[[VEC_EPILOG_VECTOR_BODY]] ]79; AUTO_VEC-NEXT:    [[TMP8:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX10]]80; AUTO_VEC-NEXT:    store <4 x float> [[VEC_IND11]], ptr [[TMP8]], align 481; AUTO_VEC-NEXT:    [[INDEX_NEXT13]] = add nuw i64 [[INDEX10]], 482; AUTO_VEC-NEXT:    [[VEC_IND_NEXT12]] = fadd fast <4 x float> [[VEC_IND11]], splat (float 2.000000e+00)83; AUTO_VEC-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT13]], [[N_VEC3]]84; AUTO_VEC-NEXT:    br i1 [[TMP9]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]85; AUTO_VEC:       [[VEC_EPILOG_MIDDLE_BLOCK]]:86; AUTO_VEC-NEXT:    [[CMP_N9:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC3]]87; AUTO_VEC-NEXT:    br i1 [[CMP_N9]], label %[[FOR_END_LOOPEXIT]], label %[[VEC_EPILOG_SCALAR_PH]]88; AUTO_VEC:       [[VEC_EPILOG_SCALAR_PH]]:89; AUTO_VEC-NEXT:    [[BC_RESUME_VAL10:%.*]] = phi i64 [ [[N_VEC3]], %[[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[N_VEC]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 0, %[[ITER_CHECK]] ]90; AUTO_VEC-NEXT:    [[BC_RESUME_VAL11:%.*]] = phi float [ [[TMP10]], %[[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END1]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 1.000000e+00, %[[ITER_CHECK]] ]91; AUTO_VEC-NEXT:    br label %[[LOOP:.*]]92; AUTO_VEC:       [[LOOP]]:93; AUTO_VEC-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL10]], %[[VEC_EPILOG_SCALAR_PH]] ]94; AUTO_VEC-NEXT:    [[X_06:%.*]] = phi float [ [[CONV1:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL11]], %[[VEC_EPILOG_SCALAR_PH]] ]95; AUTO_VEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDVARS_IV]]96; AUTO_VEC-NEXT:    store float [[X_06]], ptr [[ARRAYIDX]], align 497; AUTO_VEC-NEXT:    [[CONV1]] = fadd fast float [[X_06]], 5.000000e-0198; AUTO_VEC-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 199; AUTO_VEC-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32100; AUTO_VEC-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]101; AUTO_VEC-NEXT:    br i1 [[EXITCOND]], label %[[FOR_END_LOOPEXIT]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]102; AUTO_VEC:       [[FOR_END_LOOPEXIT]]:103; AUTO_VEC-NEXT:    br label %[[FOR_END]]104; AUTO_VEC:       [[FOR_END]]:105; AUTO_VEC-NEXT:    ret void106;107entry:108  %cmp4 = icmp sgt i32 %N, 0109  br i1 %cmp4, label %loop.preheader, label %for.end110 111loop.preheader:                               ; preds = %entry112  br label %loop113 114loop:                                         ; preds = %loop.preheader, %loop115  %iv = phi i64 [ %iv.next, %loop ], [ 0, %loop.preheader ]116  %x.06 = phi float [ %conv1, %loop ], [ 1.000000e+00, %loop.preheader ]117  %arrayidx = getelementptr inbounds float, ptr %A, i64 %iv118  store float %x.06, ptr %arrayidx, align 4119  %conv1 = fadd fast float %x.06, 5.000000e-01120  %iv.next = add nuw nsw i64 %iv, 1121  %lftr.wideiv = trunc i64 %iv.next to i32122  %exitcond = icmp eq i32 %lftr.wideiv, %N123  br i1 %exitcond, label %for.end.loopexit, label %loop124 125for.end.loopexit:                                 ; preds = %loop126  br label %for.end127 128for.end:                                          ; preds = %for.end.loopexit, %entry129  ret void130}131 132; The same as the previous, but FP operation has no FMF.133; Vectorization should be rejected.134;void fp_iv_loop2(ptr __restrict__ A, int N) {135;  float x = 1.0;136;  for (int i=0; i < N; ++i) {137;    A[i] = x;138;    x += 0.5;139;  }140;}141 142define void @fp_iv_loop2(ptr noalias nocapture %A, i32 %N) {143; AUTO_VEC-LABEL: define void @fp_iv_loop2(144; AUTO_VEC-SAME: ptr noalias captures(none) [[A:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {145; AUTO_VEC-NEXT:  [[ENTRY:.*:]]146; AUTO_VEC-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[N]], 0147; AUTO_VEC-NEXT:    br i1 [[CMP4]], label %[[LOOP_PREHEADER:.*]], label %[[FOR_END:.*]]148; AUTO_VEC:       [[LOOP_PREHEADER]]:149; AUTO_VEC-NEXT:    br label %[[LOOP:.*]]150; AUTO_VEC:       [[LOOP]]:151; AUTO_VEC-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], %[[LOOP]] ], [ 0, %[[LOOP_PREHEADER]] ]152; AUTO_VEC-NEXT:    [[X_06_EPIL:%.*]] = phi float [ [[CONV1_EPIL:%.*]], %[[LOOP]] ], [ 1.000000e+00, %[[LOOP_PREHEADER]] ]153; AUTO_VEC-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDVARS_IV_EPIL]]154; AUTO_VEC-NEXT:    store float [[X_06_EPIL]], ptr [[ARRAYIDX_EPIL]], align 4155; AUTO_VEC-NEXT:    [[CONV1_EPIL]] = fadd float [[X_06_EPIL]], 5.000000e-01156; AUTO_VEC-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add nuw nsw i64 [[INDVARS_IV_EPIL]], 1157; AUTO_VEC-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT_EPIL]] to i32158; AUTO_VEC-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]159; AUTO_VEC-NEXT:    br i1 [[EXITCOND]], label %[[FOR_END_LOOPEXIT:.*]], label %[[LOOP]]160; AUTO_VEC:       [[FOR_END_LOOPEXIT]]:161; AUTO_VEC-NEXT:    br label %[[FOR_END]]162; AUTO_VEC:       [[FOR_END]]:163; AUTO_VEC-NEXT:    ret void164;165entry:166  %cmp4 = icmp sgt i32 %N, 0167  br i1 %cmp4, label %loop.preheader, label %for.end168 169loop.preheader:                               ; preds = %entry170  br label %loop171 172loop:                                         ; preds = %loop.preheader, %loop173  %iv = phi i64 [ %iv.next, %loop ], [ 0, %loop.preheader ]174  %x.06 = phi float [ %conv1, %loop ], [ 1.000000e+00, %loop.preheader ]175  %arrayidx = getelementptr inbounds float, ptr %A, i64 %iv176  store float %x.06, ptr %arrayidx, align 4177  %conv1 = fadd float %x.06, 5.000000e-01178  %iv.next = add nuw nsw i64 %iv, 1179  %lftr.wideiv = trunc i64 %iv.next to i32180  %exitcond = icmp eq i32 %lftr.wideiv, %N181  br i1 %exitcond, label %for.end.loopexit, label %loop182 183for.end.loopexit:                                 ; preds = %loop184  br label %for.end185 186for.end:                                          ; preds = %for.end.loopexit, %entry187  ret void188}189 190define double @external_use_with_fast_math(ptr %a, i64 %n) {191; AUTO_VEC-LABEL: define double @external_use_with_fast_math(192; AUTO_VEC-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {193; AUTO_VEC-NEXT:  [[ENTRY:.*]]:194; AUTO_VEC-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 1)195; AUTO_VEC-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[SMAX]], 16196; AUTO_VEC-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]197; AUTO_VEC:       [[VECTOR_PH]]:198; AUTO_VEC-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[SMAX]], 16199; AUTO_VEC-NEXT:    [[N_VEC:%.*]] = sub i64 [[SMAX]], [[N_MOD_VF]]200; AUTO_VEC-NEXT:    [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to double201; AUTO_VEC-NEXT:    [[TMP0:%.*]] = fmul fast double 3.000000e+00, [[DOTCAST]]202; AUTO_VEC-NEXT:    [[TMP6:%.*]] = fadd fast double 0.000000e+00, [[TMP0]]203; AUTO_VEC-NEXT:    br label %[[VECTOR_BODY:.*]]204; AUTO_VEC:       [[VECTOR_BODY]]:205; AUTO_VEC-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]206; AUTO_VEC-NEXT:    [[VEC_IND:%.*]] = phi <4 x double> [ <double 0.000000e+00, double 3.000000e+00, double 6.000000e+00, double 9.000000e+00>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]207; AUTO_VEC-NEXT:    [[STEP_ADD:%.*]] = fadd fast <4 x double> [[VEC_IND]], splat (double 1.200000e+01)208; AUTO_VEC-NEXT:    [[STEP_ADD_2:%.*]] = fadd fast <4 x double> [[STEP_ADD]], splat (double 1.200000e+01)209; AUTO_VEC-NEXT:    [[STEP_ADD_3:%.*]] = fadd fast <4 x double> [[STEP_ADD_2]], splat (double 1.200000e+01)210; AUTO_VEC-NEXT:    [[TMP1:%.*]] = getelementptr double, ptr [[A]], i64 [[INDEX]]211; AUTO_VEC-NEXT:    [[TMP2:%.*]] = getelementptr double, ptr [[TMP1]], i64 4212; AUTO_VEC-NEXT:    [[TMP3:%.*]] = getelementptr double, ptr [[TMP1]], i64 8213; AUTO_VEC-NEXT:    [[TMP4:%.*]] = getelementptr double, ptr [[TMP1]], i64 12214; AUTO_VEC-NEXT:    store <4 x double> [[VEC_IND]], ptr [[TMP1]], align 8215; AUTO_VEC-NEXT:    store <4 x double> [[STEP_ADD]], ptr [[TMP2]], align 8216; AUTO_VEC-NEXT:    store <4 x double> [[STEP_ADD_2]], ptr [[TMP3]], align 8217; AUTO_VEC-NEXT:    store <4 x double> [[STEP_ADD_3]], ptr [[TMP4]], align 8218; AUTO_VEC-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16219; AUTO_VEC-NEXT:    [[VEC_IND_NEXT]] = fadd fast <4 x double> [[STEP_ADD_3]], splat (double 1.200000e+01)220; AUTO_VEC-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]221; AUTO_VEC-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]222; AUTO_VEC:       [[MIDDLE_BLOCK]]:223; AUTO_VEC-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[SMAX]], [[N_VEC]]224; AUTO_VEC-NEXT:    [[TMP7:%.*]] = fsub fast double [[TMP6]], 3.000000e+00225; AUTO_VEC-NEXT:    br i1 [[CMP_N]], label %[[FOR_END:.*]], label %[[SCALAR_PH]]226; AUTO_VEC:       [[SCALAR_PH]]:227; AUTO_VEC-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]228; AUTO_VEC-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi double [ [[TMP6]], %[[MIDDLE_BLOCK]] ], [ 0.000000e+00, %[[ENTRY]] ]229; AUTO_VEC-NEXT:    br label %[[LOOP:.*]]230; AUTO_VEC:       [[LOOP]]:231; AUTO_VEC-NEXT:    [[I:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]232; AUTO_VEC-NEXT:    [[J:%.*]] = phi double [ [[BC_RESUME_VAL1]], %[[SCALAR_PH]] ], [ [[J_NEXT:%.*]], %[[LOOP]] ]233; AUTO_VEC-NEXT:    [[T0:%.*]] = getelementptr double, ptr [[A]], i64 [[I]]234; AUTO_VEC-NEXT:    store double [[J]], ptr [[T0]], align 8235; AUTO_VEC-NEXT:    [[I_NEXT]] = add i64 [[I]], 1236; AUTO_VEC-NEXT:    [[J_NEXT]] = fadd fast double [[J]], 3.000000e+00237; AUTO_VEC-NEXT:    [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]238; AUTO_VEC-NEXT:    br i1 [[COND]], label %[[LOOP]], label %[[FOR_END]], !llvm.loop [[LOOP7:![0-9]+]]239; AUTO_VEC:       [[FOR_END]]:240; AUTO_VEC-NEXT:    [[J_LCSSA:%.*]] = phi double [ [[J]], %[[LOOP]] ], [ [[TMP7]], %[[MIDDLE_BLOCK]] ]241; AUTO_VEC-NEXT:    ret double [[J_LCSSA]]242;243entry:244  br label %loop245 246loop:247  %i = phi i64 [ 0, %entry ], [%i.next, %loop]248  %j = phi double [ 0.0, %entry ], [ %j.next, %loop ]249  %t0 = getelementptr double, ptr %a, i64 %i250  store double %j, ptr %t0251  %i.next = add i64 %i, 1252  %j.next = fadd fast double %j, 3.0253  %cond = icmp slt i64 %i.next, %n254  br i1 %cond, label %loop, label %for.end255 256for.end:257  %t1 = phi double [ %j, %loop ]258  ret double %t1259}260 261define double @external_use_without_fast_math(ptr %a, i64 %n) {262; AUTO_VEC-LABEL: define double @external_use_without_fast_math(263; AUTO_VEC-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {264; AUTO_VEC-NEXT:  [[ENTRY:.*]]:265; AUTO_VEC-NEXT:    br label %[[LOOP:.*]]266; AUTO_VEC:       [[LOOP]]:267; AUTO_VEC-NEXT:    [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_NEXT_7:%.*]], %[[LOOP]] ]268; AUTO_VEC-NEXT:    [[J:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[J_NEXT_7:%.*]], %[[LOOP]] ]269; AUTO_VEC-NEXT:    [[TMP7:%.*]] = getelementptr double, ptr [[A]], i64 [[I]]270; AUTO_VEC-NEXT:    store double [[J]], ptr [[TMP7]], align 8271; AUTO_VEC-NEXT:    [[I_NEXT_7]] = add i64 [[I]], 1272; AUTO_VEC-NEXT:    [[J_NEXT_7]] = fadd double [[J]], 3.000000e+00273; AUTO_VEC-NEXT:    [[COND:%.*]] = icmp slt i64 [[I_NEXT_7]], [[N]]274; AUTO_VEC-NEXT:    br i1 [[COND]], label %[[LOOP]], label %[[FOR_END:.*]]275; AUTO_VEC:       [[FOR_END]]:276; AUTO_VEC-NEXT:    [[J_LCSSA:%.*]] = phi double [ [[J]], %[[LOOP]] ]277; AUTO_VEC-NEXT:    ret double [[J_LCSSA]]278;279entry:280  br label %loop281 282loop:283  %i = phi i64 [ 0, %entry ], [%i.next, %loop]284  %j = phi double [ 0.0, %entry ], [ %j.next, %loop ]285  %t0 = getelementptr double, ptr %a, i64 %i286  store double %j, ptr %t0287  %i.next = add i64 %i, 1288  %j.next = fadd double %j, 3.0289  %cond = icmp slt i64 %i.next, %n290  br i1 %cond, label %loop, label %for.end291 292for.end:293  %t1 = phi double [ %j, %loop ]294  ret double %t1295}296 297;;  void fadd_induction(ptr p, unsigned N) {298;;    float x = 1.0f;299;;    for (unsigned i=0; i!=N; ++i) {300;;      p[i] = p[i] + x;301;;      x += 42.0f;302;;    }303;;  }304 305define void @fadd_reassoc_FMF(ptr nocapture %p, i32 %N) {306; AUTO_VEC-LABEL: define void @fadd_reassoc_FMF(307; AUTO_VEC-SAME: ptr captures(none) [[P:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {308; AUTO_VEC-NEXT:  [[ITER_CHECK:.*]]:309; AUTO_VEC-NEXT:    [[TMP0:%.*]] = zext i32 [[N]] to i64310; AUTO_VEC-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4311; AUTO_VEC-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[VEC_EPILOG_SCALAR_PH:.*]], label %[[VECTOR_MAIN_LOOP_ITER_CHECK:.*]]312; AUTO_VEC:       [[VECTOR_MAIN_LOOP_ITER_CHECK]]:313; AUTO_VEC-NEXT:    [[MIN_ITERS_CHECK1:%.*]] = icmp ult i64 [[TMP0]], 32314; AUTO_VEC-NEXT:    br i1 [[MIN_ITERS_CHECK1]], label %[[VEC_EPILOG_PH:.*]], label %[[VECTOR_PH:.*]]315; AUTO_VEC:       [[VECTOR_PH]]:316; AUTO_VEC-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 32317; AUTO_VEC-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]318; AUTO_VEC-NEXT:    [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float319; AUTO_VEC-NEXT:    [[TMP1:%.*]] = fmul reassoc float 4.200000e+01, [[DOTCAST]]320; AUTO_VEC-NEXT:    [[IND_END:%.*]] = fadd reassoc float 1.000000e+00, [[TMP1]]321; AUTO_VEC-NEXT:    br label %[[VECTOR_BODY:.*]]322; AUTO_VEC:       [[VECTOR_BODY]]:323; AUTO_VEC-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]324; AUTO_VEC-NEXT:    [[VEC_IND:%.*]] = phi <8 x float> [ <float 1.000000e+00, float 4.300000e+01, float 8.500000e+01, float 1.270000e+02, float 1.690000e+02, float 2.110000e+02, float 2.530000e+02, float 2.950000e+02>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]325; AUTO_VEC-NEXT:    [[STEP_ADD:%.*]] = fadd reassoc <8 x float> [[VEC_IND]], splat (float 3.360000e+02)326; AUTO_VEC-NEXT:    [[STEP_ADD2:%.*]] = fadd reassoc <8 x float> [[STEP_ADD]], splat (float 3.360000e+02)327; AUTO_VEC-NEXT:    [[STEP_ADD3:%.*]] = fadd reassoc <8 x float> [[STEP_ADD2]], splat (float 3.360000e+02)328; AUTO_VEC-NEXT:    [[TMP2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 [[INDEX]]329; AUTO_VEC-NEXT:    [[TMP3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i64 8330; AUTO_VEC-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i64 16331; AUTO_VEC-NEXT:    [[TMP5:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i64 24332; AUTO_VEC-NEXT:    [[WIDE_LOAD:%.*]] = load <8 x float>, ptr [[TMP2]], align 4333; AUTO_VEC-NEXT:    [[WIDE_LOAD2:%.*]] = load <8 x float>, ptr [[TMP3]], align 4334; AUTO_VEC-NEXT:    [[WIDE_LOAD3:%.*]] = load <8 x float>, ptr [[TMP4]], align 4335; AUTO_VEC-NEXT:    [[WIDE_LOAD4:%.*]] = load <8 x float>, ptr [[TMP5]], align 4336; AUTO_VEC-NEXT:    [[TMP6:%.*]] = fadd reassoc <8 x float> [[VEC_IND]], [[WIDE_LOAD]]337; AUTO_VEC-NEXT:    [[TMP7:%.*]] = fadd reassoc <8 x float> [[STEP_ADD]], [[WIDE_LOAD2]]338; AUTO_VEC-NEXT:    [[TMP8:%.*]] = fadd reassoc <8 x float> [[STEP_ADD2]], [[WIDE_LOAD3]]339; AUTO_VEC-NEXT:    [[TMP9:%.*]] = fadd reassoc <8 x float> [[STEP_ADD3]], [[WIDE_LOAD4]]340; AUTO_VEC-NEXT:    store <8 x float> [[TMP6]], ptr [[TMP2]], align 4341; AUTO_VEC-NEXT:    store <8 x float> [[TMP7]], ptr [[TMP3]], align 4342; AUTO_VEC-NEXT:    store <8 x float> [[TMP8]], ptr [[TMP4]], align 4343; AUTO_VEC-NEXT:    store <8 x float> [[TMP9]], ptr [[TMP5]], align 4344; AUTO_VEC-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32345; AUTO_VEC-NEXT:    [[VEC_IND_NEXT]] = fadd reassoc <8 x float> [[STEP_ADD3]], splat (float 3.360000e+02)346; AUTO_VEC-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]347; AUTO_VEC-NEXT:    br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]348; AUTO_VEC:       [[MIDDLE_BLOCK]]:349; AUTO_VEC-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]350; AUTO_VEC-NEXT:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]]351; AUTO_VEC:       [[VEC_EPILOG_ITER_CHECK]]:352; AUTO_VEC-NEXT:    [[DOTCAST16:%.*]] = sitofp i64 [[N_VEC]] to float353; AUTO_VEC-NEXT:    [[TMP12:%.*]] = fmul reassoc float 4.200000e+01, [[DOTCAST16]]354; AUTO_VEC-NEXT:    [[IND_END1:%.*]] = fadd reassoc float 1.000000e+00, [[TMP12]]355; AUTO_VEC-NEXT:    [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp ult i64 [[N_MOD_VF]], 4356; AUTO_VEC-NEXT:    br i1 [[MIN_EPILOG_ITERS_CHECK]], label %[[VEC_EPILOG_SCALAR_PH]], label %[[VEC_EPILOG_PH]], !prof [[PROF3]]357; AUTO_VEC:       [[VEC_EPILOG_PH]]:358; AUTO_VEC-NEXT:    [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 0, %[[VECTOR_MAIN_LOOP_ITER_CHECK]] ]359; AUTO_VEC-NEXT:    [[BC_RESUME_VAL:%.*]] = phi float [ [[IND_END]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 1.000000e+00, %[[VECTOR_MAIN_LOOP_ITER_CHECK]] ]360; AUTO_VEC-NEXT:    [[N_MOD_VF5:%.*]] = urem i64 [[TMP0]], 4361; AUTO_VEC-NEXT:    [[N_VEC6:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF5]]362; AUTO_VEC-NEXT:    [[DOTCAST7:%.*]] = sitofp i64 [[N_VEC6]] to float363; AUTO_VEC-NEXT:    [[TMP17:%.*]] = fmul reassoc float 4.200000e+01, [[DOTCAST7]]364; AUTO_VEC-NEXT:    [[TMP18:%.*]] = fadd reassoc float 1.000000e+00, [[TMP17]]365; AUTO_VEC-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[BC_RESUME_VAL]], i64 0366; AUTO_VEC-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <4 x float> [[DOTSPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer367; AUTO_VEC-NEXT:    [[INDUCTION:%.*]] = fadd reassoc <4 x float> [[DOTSPLAT]], <float 0.000000e+00, float 4.200000e+01, float 8.400000e+01, float 1.260000e+02>368; AUTO_VEC-NEXT:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]369; AUTO_VEC:       [[VEC_EPILOG_VECTOR_BODY]]:370; AUTO_VEC-NEXT:    [[INDEX13:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], %[[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT17:%.*]], %[[VEC_EPILOG_VECTOR_BODY]] ]371; AUTO_VEC-NEXT:    [[VEC_IND14:%.*]] = phi <4 x float> [ [[INDUCTION]], %[[VEC_EPILOG_PH]] ], [ [[VEC_IND_NEXT15:%.*]], %[[VEC_EPILOG_VECTOR_BODY]] ]372; AUTO_VEC-NEXT:    [[TMP13:%.*]] = getelementptr inbounds float, ptr [[P]], i64 [[INDEX13]]373; AUTO_VEC-NEXT:    [[WIDE_LOAD16:%.*]] = load <4 x float>, ptr [[TMP13]], align 4374; AUTO_VEC-NEXT:    [[TMP14:%.*]] = fadd reassoc <4 x float> [[VEC_IND14]], [[WIDE_LOAD16]]375; AUTO_VEC-NEXT:    store <4 x float> [[TMP14]], ptr [[TMP13]], align 4376; AUTO_VEC-NEXT:    [[INDEX_NEXT17]] = add nuw i64 [[INDEX13]], 4377; AUTO_VEC-NEXT:    [[VEC_IND_NEXT15]] = fadd reassoc <4 x float> [[VEC_IND14]], splat (float 1.680000e+02)378; AUTO_VEC-NEXT:    [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT17]], [[N_VEC6]]379; AUTO_VEC-NEXT:    br i1 [[TMP15]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]380; AUTO_VEC:       [[VEC_EPILOG_MIDDLE_BLOCK]]:381; AUTO_VEC-NEXT:    [[CMP_N18:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC6]]382; AUTO_VEC-NEXT:    br i1 [[CMP_N18]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]]383; AUTO_VEC:       [[VEC_EPILOG_SCALAR_PH]]:384; AUTO_VEC-NEXT:    [[BC_RESUME_VAL14:%.*]] = phi i64 [ [[N_VEC6]], %[[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[N_VEC]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 0, %[[ITER_CHECK]] ]385; AUTO_VEC-NEXT:    [[BC_RESUME_VAL15:%.*]] = phi float [ [[TMP18]], %[[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END1]], %[[VEC_EPILOG_ITER_CHECK]] ], [ 1.000000e+00, %[[ITER_CHECK]] ]386; AUTO_VEC-NEXT:    br label %[[LOOP:.*]]387; AUTO_VEC:       [[LOOP]]:388; AUTO_VEC-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL14]], %[[VEC_EPILOG_SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[LOOP]] ]389; AUTO_VEC-NEXT:    [[X_012:%.*]] = phi float [ [[BC_RESUME_VAL15]], %[[VEC_EPILOG_SCALAR_PH]] ], [ [[ADD3:%.*]], %[[LOOP]] ]390; AUTO_VEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[P]], i64 [[INDVARS_IV]]391; AUTO_VEC-NEXT:    [[TMP16:%.*]] = load float, ptr [[ARRAYIDX]], align 4392; AUTO_VEC-NEXT:    [[ADD:%.*]] = fadd reassoc float [[X_012]], [[TMP16]]393; AUTO_VEC-NEXT:    store float [[ADD]], ptr [[ARRAYIDX]], align 4394; AUTO_VEC-NEXT:    [[ADD3]] = fadd reassoc float [[X_012]], 4.200000e+01395; AUTO_VEC-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1396; AUTO_VEC-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[TMP0]]397; AUTO_VEC-NEXT:    br i1 [[CMP_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP10:![0-9]+]]398; AUTO_VEC:       [[EXIT]]:399; AUTO_VEC-NEXT:    ret void400;401entry:402  %0 = zext i32 %N to i64403  br label %loop404 405loop:406  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]407  %x.012 = phi float [ 1.000000e+00, %entry ], [ %add3, %loop ]408  %arrayidx = getelementptr inbounds float, ptr %p, i64 %iv409  %1 = load float, ptr %arrayidx, align 4410  %add = fadd reassoc float %x.012, %1411  store float %add, ptr %arrayidx, align 4412  %add3 = fadd reassoc float %x.012, 4.200000e+01413  %iv.next = add nuw nsw i64 %iv, 1414  %cmp.not = icmp eq i64 %iv.next, %0415  br i1 %cmp.not, label %exit, label %loop416 417exit:418  ret void419}420