brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.5 KiB · 4423b89 Raw
845 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^middle.block" --version 52; RUN: opt %s -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S | FileCheck %s3 4; Make sure that integer poison-generating flags (i.e., nuw/nsw, exact and inbounds)5; are dropped from instructions in blocks that need predication and are linearized6; and masked after vectorization. We only drop flags from scalar instructions that7; contribute to the address computation of a masked vector load/store. After8; linearizing the control flow and removing their guarding condition, these9; instructions could generate a poison value which would be used as base address of10; the masked vector load/store (see PR52111). For gather/scatter cases,11; posiong-generating flags can be preserved since poison addresses in the vector GEP12; reaching the gather/scatter instruction will be masked-out by the gather/scatter13; instruction itself and won't be used.14; We need AVX512 target features for the loop to be vectorized with masks instead of15; predicates.16 17target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"18target triple = "x86_64-pc-linux-gnu"19 20; Drop poison-generating flags from 'sub' and 'getelementptr' feeding a masked load.21; Test for PR52111.22define void @drop_scalar_nuw_nsw(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {23; CHECK-LABEL: define void @drop_scalar_nuw_nsw(24; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {25; CHECK-NEXT:  [[ENTRY:.*:]]26; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]27; CHECK:       [[VECTOR_PH]]:28; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]29; CHECK:       [[VECTOR_BODY]]:30; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[INPUT]], i64 -131; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP0]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0:![0-9]+]]32; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer33; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 434; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]35; CHECK:       [[MIDDLE_BLOCK]]:36;37entry:38  br label %loop.header39 40loop.header:41  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]42  %i23 = icmp eq i64 %iv, 043  br i1 %i23, label %if.end, label %if.then44 45if.then:46  %i27 = sub nuw nsw i64 %iv, 147  %i29 = getelementptr inbounds float, ptr %input, i64 %i2748  %i30 = load float, ptr %i29, align 4, !invariant.load !049  br label %if.end50 51if.end:52  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]53  %i35 = getelementptr inbounds float, ptr %output, i64 %iv54  store float %i34, ptr %i35, align 455  %iv.inc = add nuw nsw i64 %iv, 156  %exitcond = icmp eq i64 %iv.inc, 457  br i1 %exitcond, label %loop.exit, label %loop.header58 59loop.exit:60  ret void61}62 63; Variant with getelementptr nusw.64define void @drop_scalar_gep_nusw(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {65; CHECK-LABEL: define void @drop_scalar_gep_nusw(66; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {67; CHECK-NEXT:  [[ENTRY:.*:]]68; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]69; CHECK:       [[VECTOR_PH]]:70; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]71; CHECK:       [[VECTOR_BODY]]:72; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[INPUT]], i64 -173; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP0]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]74; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer75; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 476; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]77; CHECK:       [[MIDDLE_BLOCK]]:78;79entry:80  br label %loop.header81 82loop.header:83  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]84  %i23 = icmp eq i64 %iv, 085  br i1 %i23, label %if.end, label %if.then86 87if.then:88  %i27 = sub nuw nsw i64 %iv, 189  %i29 = getelementptr nusw float, ptr %input, i64 %i2790  %i30 = load float, ptr %i29, align 4, !invariant.load !091  br label %if.end92 93if.end:94  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]95  %i35 = getelementptr nusw float, ptr %output, i64 %iv96  store float %i34, ptr %i35, align 497  %iv.inc = add nuw nsw i64 %iv, 198  %exitcond = icmp eq i64 %iv.inc, 499  br i1 %exitcond, label %loop.exit, label %loop.header100 101loop.exit:102  ret void103}104 105; Variant with getelementptr nuw.106define void @drop_scalar_gep_nuw(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {107; CHECK-LABEL: define void @drop_scalar_gep_nuw(108; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {109; CHECK-NEXT:  [[ENTRY:.*:]]110; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]111; CHECK:       [[VECTOR_PH]]:112; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]113; CHECK:       [[VECTOR_BODY]]:114; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[INPUT]], i64 -1115; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP0]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]116; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer117; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4118; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]119; CHECK:       [[MIDDLE_BLOCK]]:120;121entry:122  br label %loop.header123 124loop.header:125  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]126  %i23 = icmp eq i64 %iv, 0127  br i1 %i23, label %if.end, label %if.then128 129if.then:130  %i27 = sub nuw nsw i64 %iv, 1131  %i29 = getelementptr nuw float, ptr %input, i64 %i27132  %i30 = load float, ptr %i29, align 4, !invariant.load !0133  br label %if.end134 135if.end:136  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]137  %i35 = getelementptr nuw float, ptr %output, i64 %iv138  store float %i34, ptr %i35, align 4139  %iv.inc = add nuw nsw i64 %iv, 1140  %exitcond = icmp eq i64 %iv.inc, 4141  br i1 %exitcond, label %loop.exit, label %loop.header142 143loop.exit:144  ret void145}146 147; Drop poison-generating flags from 'sub' and 'getelementptr' feeding a masked load.148; In this case, 'sub' and 'getelementptr' are not guarded by the predicate.149define void @drop_nonpred_scalar_nuw_nsw(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {150; CHECK-LABEL: define void @drop_nonpred_scalar_nuw_nsw(151; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {152; CHECK-NEXT:  [[ENTRY:.*:]]153; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]154; CHECK:       [[VECTOR_PH]]:155; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]156; CHECK:       [[VECTOR_BODY]]:157; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[INPUT]], i64 -1158; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP0]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]159; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer160; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4161; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]162; CHECK:       [[MIDDLE_BLOCK]]:163;164entry:165  br label %loop.header166 167loop.header:168  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]169  %i27 = sub i64 %iv, 1170  %i29 = getelementptr float, ptr %input, i64 %i27171  %i23 = icmp eq i64 %iv, 0172  br i1 %i23, label %if.end, label %if.then173 174if.then:175  %i30 = load float, ptr %i29, align 4, !invariant.load !0176  br label %if.end177 178if.end:179  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]180  %i35 = getelementptr inbounds float, ptr %output, i64 %iv181  store float %i34, ptr %i35, align 4182  %iv.inc = add nuw nsw i64 %iv, 1183  %exitcond = icmp eq i64 %iv.inc, 4184  br i1 %exitcond, label %loop.exit, label %loop.header185 186loop.exit:187  ret void188}189 190; Preserve poison-generating flags from vector 'sub', 'mul' and 'getelementptr' feeding a masked gather.191define void @preserve_vector_nuw_nsw(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {192; CHECK-LABEL: define void @preserve_vector_nuw_nsw(193; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {194; CHECK-NEXT:  [[ENTRY:.*:]]195; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]196; CHECK:       [[VECTOR_PH]]:197; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]198; CHECK:       [[VECTOR_BODY]]:199; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, ptr [[INPUT]], <4 x i64> <i64 -2, i64 0, i64 2, i64 4>200; CHECK-NEXT:    [[WIDE_MASKED_GATHER:%.*]] = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> align 4 [[TMP0]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]201; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_GATHER]], <4 x float> zeroinitializer202; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4203; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]204; CHECK:       [[MIDDLE_BLOCK]]:205;206entry:207  br label %loop.header208 209loop.header:210  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]211  %i23 = icmp eq i64 %iv, 0212  br i1 %i23, label %if.end, label %if.then213 214if.then:215  %i27 = sub nuw nsw i64 %iv, 1216  %i28 = mul nuw nsw i64 %i27, 2217  %i29 = getelementptr inbounds float, ptr %input, i64 %i28218  %i30 = load float, ptr %i29, align 4, !invariant.load !0219  br label %if.end220 221if.end:222  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]223  %i35 = getelementptr inbounds float, ptr %output, i64 %iv224  store float %i34, ptr %i35, align 4225  %iv.inc = add nuw nsw i64 %iv, 1226  %exitcond = icmp eq i64 %iv.inc, 4227  br i1 %exitcond, label %loop.exit, label %loop.header228 229loop.exit:230  ret void231}232 233; Drop poison-generating flags from vector 'sub' and 'gep' feeding a masked load.234define void @drop_vector_nuw_nsw(ptr noalias nocapture readonly %input, ptr %output, ptr noalias %ptrs) local_unnamed_addr #0 {235; CHECK-LABEL: define void @drop_vector_nuw_nsw(236; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]], ptr noalias [[PTRS:%.*]]) local_unnamed_addr #[[ATTR0]] {237; CHECK-NEXT:  [[ENTRY:.*:]]238; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]239; CHECK:       [[VECTOR_PH]]:240; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]241; CHECK:       [[VECTOR_BODY]]:242; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr float, ptr [[INPUT]], <4 x i64> <i64 -1, i64 0, i64 1, i64 2>243; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x ptr> [[TMP3]], i32 0244; CHECK-NEXT:    store <4 x ptr> [[TMP3]], ptr [[PTRS]], align 8245; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP6]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]246; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer247; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4248; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]249; CHECK:       [[MIDDLE_BLOCK]]:250;251entry:252  br label %loop.header253 254loop.header:255  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]256  %i23 = icmp eq i64 %iv, 0257  %gep = getelementptr inbounds ptr, ptr %ptrs, i64 %iv258  %i27 = sub nuw nsw i64 %iv, 1259  %i29 = getelementptr inbounds float, ptr %input, i64 %i27260  store ptr %i29, ptr %gep261  br i1 %i23, label %if.end, label %if.then262 263if.then:264  %i30 = load float, ptr %i29, align 4, !invariant.load !0265  br label %if.end266 267if.end:268  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]269  %i35 = getelementptr inbounds float, ptr %output, i64 %iv270  store float %i34, ptr %i35, align 4271  %iv.inc = add nuw nsw i64 %iv, 1272  %exitcond = icmp eq i64 %iv.inc, 4273  br i1 %exitcond, label %loop.exit, label %loop.header274 275loop.exit:276  ret void277}278 279; Same as @drop_vector_nuw_nsw, except built with avx1; in this case,280; we make scalar clones of the 'sub' operation. These clones also need281; cleared flags.282define void @drop_nonvector_nuw_nsw_avx1(ptr noalias nocapture readonly %input, ptr %output, ptr noalias %ptrs) local_unnamed_addr #1 {283; CHECK-LABEL: define void @drop_nonvector_nuw_nsw_avx1(284; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]], ptr noalias [[PTRS:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {285; CHECK-NEXT:  [[ENTRY:.*:]]286; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]287; CHECK:       [[VECTOR_PH]]:288; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]289; CHECK:       [[VECTOR_BODY]]:290; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds ptr, ptr [[PTRS]], i64 0291; CHECK-NEXT:    [[TMP6:%.*]] = sub i64 0, 1292; CHECK-NEXT:    [[TMP7:%.*]] = sub i64 1, 1293; CHECK-NEXT:    [[TMP8:%.*]] = sub i64 2, 1294; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 3, 1295; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr float, ptr [[INPUT]], i64 [[TMP6]]296; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr float, ptr [[INPUT]], i64 [[TMP7]]297; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr float, ptr [[INPUT]], i64 [[TMP8]]298; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr float, ptr [[INPUT]], i64 [[TMP9]]299; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <4 x ptr> poison, ptr [[TMP10]], i32 0300; CHECK-NEXT:    [[TMP15:%.*]] = insertelement <4 x ptr> [[TMP14]], ptr [[TMP11]], i32 1301; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x ptr> [[TMP15]], ptr [[TMP12]], i32 2302; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x ptr> [[TMP16]], ptr [[TMP13]], i32 3303; CHECK-NEXT:    store <4 x ptr> [[TMP17]], ptr [[TMP5]], align 8304; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[TMP10]], <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> poison), !invariant.load [[META0]]305; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> [[WIDE_MASKED_LOAD]], <4 x float> zeroinitializer306; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds float, ptr [[OUTPUT]], i64 0307; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[TMP21]], align 4308; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]309; CHECK:       [[MIDDLE_BLOCK]]:310;311entry:312  br label %loop.header313 314loop.header:315  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]316  %i23 = icmp eq i64 %iv, 0317  %gep = getelementptr inbounds ptr, ptr %ptrs, i64 %iv318  %i27 = sub nuw nsw i64 %iv, 1319  %i29 = getelementptr inbounds float, ptr %input, i64 %i27320  store ptr %i29, ptr %gep321  br i1 %i23, label %if.end, label %if.then322 323if.then:324  %i30 = load float, ptr %i29, align 4, !invariant.load !0325  br label %if.end326 327if.end:328  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]329  %i35 = getelementptr inbounds float, ptr %output, i64 %iv330  store float %i34, ptr %i35, align 4331  %iv.inc = add nuw nsw i64 %iv, 1332  %exitcond = icmp eq i64 %iv.inc, 4333  br i1 %exitcond, label %loop.exit, label %loop.header334 335loop.exit:336  ret void337}338 339; Preserve poison-generating flags from 'sub', which is not contributing to any address computation340; of any masked load/store/gather/scatter.341define void @preserve_nuw_nsw_no_addr(ptr %output) local_unnamed_addr #0 {342; CHECK-LABEL: define void @preserve_nuw_nsw_no_addr(343; CHECK-SAME: ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {344; CHECK-NEXT:  [[ENTRY:.*:]]345; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]346; CHECK:       [[VECTOR_PH]]:347; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]348; CHECK:       [[VECTOR_BODY]]:349; CHECK-NEXT:    store <4 x i64> <i64 0, i64 0, i64 1, i64 2>, ptr [[OUTPUT]], align 4350; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]351; CHECK:       [[MIDDLE_BLOCK]]:352;353entry:354  br label %loop.header355 356loop.header:357  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]358  %i23 = icmp eq i64 %iv, 0359  br i1 %i23, label %if.end, label %if.then360 361if.then:362  %i27 = sub nuw nsw i64 %iv, 1363  br label %if.end364 365if.end:366  %i34 = phi i64 [ 0, %loop.header ], [ %i27, %if.then ]367  %i35 = getelementptr inbounds i64, ptr %output, i64 %iv368  store i64 %i34, ptr %i35, align 4369  %iv.inc = add nuw nsw i64 %iv, 1370  %exitcond = icmp eq i64 %iv.inc, 4371  br i1 %exitcond, label %loop.exit, label %loop.header372 373loop.exit:374  ret void375}376 377; Drop poison-generating flags from 'sdiv' and 'getelementptr' feeding a masked load.378define void @drop_scalar_exact(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {379; CHECK-LABEL: define void @drop_scalar_exact(380; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {381; CHECK-NEXT:  [[ENTRY:.*:]]382; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]383; CHECK:       [[VECTOR_PH]]:384; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]385; CHECK:       [[VECTOR_BODY]]:386; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 4 [[INPUT]], <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x float> poison), !invariant.load [[META0]]387; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x float> zeroinitializer, <4 x float> [[WIDE_MASKED_LOAD]]388; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4389; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]390; CHECK:       [[MIDDLE_BLOCK]]:391;392entry:393  br label %loop.header394 395loop.header:396  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]397  %i7 = icmp ne i64 %iv, 0398  %i8 = and i64 %iv, 1399  %i9 = icmp eq i64 %i8, 0400  %i10 = and i1 %i7, %i9401  br i1 %i10, label %if.end, label %if.then402 403if.then:404  %i26 = sdiv exact i64 %iv, 1405  %i29 = getelementptr inbounds float, ptr %input, i64 %i26406  %i30 = load float, ptr %i29, align 4, !invariant.load !0407  br label %if.end408 409if.end:410  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]411  %i35 = getelementptr inbounds float, ptr %output, i64 %iv412  store float %i34, ptr %i35, align 4413  %iv.inc = add nuw nsw i64 %iv, 1414  %exitcond = icmp eq i64 %iv.inc, 4415  br i1 %exitcond, label %loop.exit, label %loop.header416 417loop.exit:418  ret void419}420 421define void @drop_zext_nneg(ptr noalias %p, ptr noalias %p1) #0 {422; CHECK-LABEL: define void @drop_zext_nneg(423; CHECK-SAME: ptr noalias [[P:%.*]], ptr noalias [[P1:%.*]]) #[[ATTR0]] {424; CHECK-NEXT:  [[ENTRY:.*:]]425; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]426; CHECK:       [[VECTOR_PH]]:427; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]428; CHECK:       [[VECTOR_BODY]]:429; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]430; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]431; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq <4 x i32> [[VEC_IND]], zeroinitializer432; CHECK-NEXT:    [[TMP1:%.*]] = zext <4 x i32> [[VEC_IND]] to <4 x i64>433; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i64> [[TMP1]], i32 0434; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP2]]435; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x double> @llvm.masked.load.v4f64.p0(ptr align 8 [[TMP3]], <4 x i1> [[TMP0]], <4 x double> poison)436; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP0]], <4 x double> [[WIDE_MASKED_LOAD]], <4 x double> zeroinitializer437; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x double> [[PREDPHI]], i32 3438; CHECK-NEXT:    store double [[TMP5]], ptr [[P1]], align 8439; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4440; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], splat (i32 4)441; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024442; CHECK-NEXT:    br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP1:![0-9]+]]443; CHECK:       [[MIDDLE_BLOCK]]:444;445entry:446  br label %body447 448body:449  %iv = phi i64 [ %next, %else ], [ 0, %entry ]450  %0 = trunc i64 %iv to i32451  %c = icmp eq i32 %0, 0452  br i1 %c, label %then, label %else453 454then:455  %zext = zext nneg i32 %0 to i64456  %idx1 = getelementptr double, ptr %p, i64 %zext457  %idx2 = getelementptr double, ptr %p, i64 %zext458  %1 = load double, ptr %idx2, align 8459  br label %else460 461else:462  %phi = phi double [ %1, %then ], [ 0.000000e+00, %body ]463  store double %phi, ptr %p1, align 8464  %next = add i64 %iv, 1465  %cmp = icmp eq i64 %next, 1024466  br i1 %cmp, label %exit, label %body467 468exit:469  ret void470}471 472; Preserve poison-generating flags from 'sdiv' and 'getelementptr' feeding a masked gather.473define void @preserve_vector_exact_no_addr(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {474; CHECK-LABEL: define void @preserve_vector_exact_no_addr(475; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {476; CHECK-NEXT:  [[ENTRY:.*:]]477; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]478; CHECK:       [[VECTOR_PH]]:479; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]480; CHECK:       [[VECTOR_BODY]]:481; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, ptr [[INPUT]], <4 x i64> <i64 0, i64 0, i64 1, i64 1>482; CHECK-NEXT:    [[WIDE_MASKED_GATHER:%.*]] = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> align 4 [[TMP0]], <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x float> poison), !invariant.load [[META0]]483; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x float> zeroinitializer, <4 x float> [[WIDE_MASKED_GATHER]]484; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[OUTPUT]], align 4485; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]486; CHECK:       [[MIDDLE_BLOCK]]:487;488entry:489  br label %loop.header490 491loop.header:492  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]493  %i7 = icmp ne i64 %iv, 0494  %i8 = and i64 %iv, 1495  %i9 = icmp eq i64 %i8, 0496  %i10 = and i1 %i7, %i9497  br i1 %i10, label %if.end, label %if.then498 499if.then:500  %i26 = sdiv exact i64 %iv, 2501  %i29 = getelementptr inbounds float, ptr %input, i64 %i26502  %i30 = load float, ptr %i29, align 4, !invariant.load !0503  br label %if.end504 505if.end:506  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]507  %i35 = getelementptr inbounds float, ptr %output, i64 %iv508  store float %i34, ptr %i35, align 4509  %iv.inc = add nuw nsw i64 %iv, 1510  %exitcond = icmp eq i64 %iv.inc, 4511  br i1 %exitcond, label %loop.exit, label %loop.header512 513loop.exit:514  ret void515}516 517; Preserve poison-generating flags from 'sdiv', which is not contributing to any address computation518; of any masked load/store/gather/scatter.519define void @preserve_exact_no_addr(ptr %output) local_unnamed_addr #0 {520; CHECK-LABEL: define void @preserve_exact_no_addr(521; CHECK-SAME: ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {522; CHECK-NEXT:  [[ENTRY:.*:]]523; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]524; CHECK:       [[VECTOR_PH]]:525; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]526; CHECK:       [[VECTOR_BODY]]:527; CHECK-NEXT:    store <4 x i64> <i64 0, i64 0, i64 1, i64 1>, ptr [[OUTPUT]], align 4528; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]529; CHECK:       [[MIDDLE_BLOCK]]:530;531entry:532  br label %loop.header533 534loop.header:535  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]536  %i23 = icmp eq i64 %iv, 0537  br i1 %i23, label %if.end, label %if.then538 539if.then:540  %i27 = sdiv exact i64 %iv, 2541  br label %if.end542 543if.end:544  %i34 = phi i64 [ 0, %loop.header ], [ %i27, %if.then ]545  %i35 = getelementptr inbounds i64, ptr %output, i64 %iv546  store i64 %i34, ptr %i35, align 4547  %iv.inc = add nuw nsw i64 %iv, 1548  %exitcond = icmp eq i64 %iv.inc, 4549  br i1 %exitcond, label %loop.exit, label %loop.header550 551loop.exit:552  ret void553}554 555; Make sure we don't vectorize a loop with a phi feeding a poison value to556; a masked load/gather.557define void @dont_vectorize_poison_phi(ptr noalias nocapture readonly %input, ptr %output) local_unnamed_addr #0 {558; CHECK-LABEL: define void @dont_vectorize_poison_phi(559; CHECK-SAME: ptr noalias readonly captures(none) [[INPUT:%.*]], ptr [[OUTPUT:%.*]]) local_unnamed_addr #[[ATTR0]] {560; CHECK-NEXT:  [[ENTRY:.*]]:561; CHECK-NEXT:    br label %[[LOOP_HEADER:.*]]562; CHECK:       [[LOOP_HEADER]]:563; CHECK-NEXT:    [[POISON:%.*]] = phi i64 [ poison, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[IF_END:.*]] ]564; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_INC]], %[[IF_END]] ]565; CHECK-NEXT:    [[I23:%.*]] = icmp eq i64 [[IV]], 0566; CHECK-NEXT:    br i1 [[I23]], label %[[IF_END]], label %[[IF_THEN:.*]]567; CHECK:       [[IF_THEN]]:568; CHECK-NEXT:    [[I29:%.*]] = getelementptr inbounds float, ptr [[INPUT]], i64 [[POISON]]569; CHECK-NEXT:    [[I30:%.*]] = load float, ptr [[I29]], align 4, !invariant.load [[META0]]570; CHECK-NEXT:    br label %[[IF_END]]571; CHECK:       [[IF_END]]:572; CHECK-NEXT:    [[I34:%.*]] = phi float [ 0.000000e+00, %[[LOOP_HEADER]] ], [ [[I30]], %[[IF_THEN]] ]573; CHECK-NEXT:    [[I35:%.*]] = getelementptr inbounds float, ptr [[OUTPUT]], i64 [[IV]]574; CHECK-NEXT:    store float [[I34]], ptr [[I35]], align 4575; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i64 [[IV]], 1576; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_INC]], 4577; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[LOOP_EXIT:.*]], label %[[LOOP_HEADER]]578; CHECK:       [[LOOP_EXIT]]:579; CHECK-NEXT:    ret void580;581entry:582  br label %loop.header583 584loop.header:585  %poison = phi i64 [ poison, %entry ], [ %iv.inc, %if.end ]586  %iv = phi i64 [ 0, %entry ], [ %iv.inc, %if.end ]587  %i23 = icmp eq i64 %iv, 0588  br i1 %i23, label %if.end, label %if.then589 590if.then:591  %i29 = getelementptr inbounds float, ptr %input, i64 %poison592  %i30 = load float, ptr %i29, align 4, !invariant.load !0593  br label %if.end594 595if.end:596  %i34 = phi float [ 0.000000e+00, %loop.header ], [ %i30, %if.then ]597  %i35 = getelementptr inbounds float, ptr %output, i64 %iv598  store float %i34, ptr %i35, align 4599  %iv.inc = add nuw nsw i64 %iv, 1600  %exitcond = icmp eq i64 %iv.inc, 4601  br i1 %exitcond, label %loop.exit, label %loop.header602 603loop.exit:604  ret void605}606 607@c = external global [5 x i8]608 609; Test case for https://github.com/llvm/llvm-project/issues/70590.610; Note that the then block has UB, but I could not find any other way to611; construct a suitable test case.612define void @pr70590_recipe_without_underlying_instr(i64 %n, ptr noalias %dst) {613; CHECK-LABEL: define void @pr70590_recipe_without_underlying_instr(614; CHECK-SAME: i64 [[N:%.*]], ptr noalias [[DST:%.*]]) {615; CHECK-NEXT:  [[ENTRY:.*:]]616; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]617; CHECK:       [[VECTOR_PH]]:618; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[N]], i64 0619; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer620; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]621; CHECK:       [[VECTOR_BODY]]:622; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <4 x i64> <i64 0, i64 1, i64 2, i64 3>, [[BROADCAST_SPLAT]]623; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0624; CHECK-NEXT:    br i1 [[TMP2]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]625; CHECK:       [[PRED_LOAD_IF]]:626; CHECK-NEXT:    [[TMP4:%.*]] = add i64 0, poison627; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP4]]628; CHECK-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP23]], align 1629; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i8> poison, i8 [[TMP6]], i32 0630; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE]]631; CHECK:       [[PRED_LOAD_CONTINUE]]:632; CHECK-NEXT:    [[TMP8:%.*]] = phi <4 x i8> [ poison, %[[VECTOR_BODY]] ], [ [[TMP24]], %[[PRED_LOAD_IF]] ]633; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1634; CHECK-NEXT:    br i1 [[TMP5]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2:.*]]635; CHECK:       [[PRED_LOAD_IF1]]:636; CHECK-NEXT:    [[TMP11:%.*]] = add i64 1, poison637; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP11]]638; CHECK-NEXT:    [[TMP26:%.*]] = load i8, ptr [[TMP25]], align 1639; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <4 x i8> [[TMP8]], i8 [[TMP26]], i32 1640; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE2]]641; CHECK:       [[PRED_LOAD_CONTINUE2]]:642; CHECK-NEXT:    [[TMP29:%.*]] = phi <4 x i8> [ [[TMP8]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]643; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2644; CHECK-NEXT:    br i1 [[TMP7]], label %[[PRED_LOAD_IF3:.*]], label %[[PRED_LOAD_CONTINUE4:.*]]645; CHECK:       [[PRED_LOAD_IF3]]:646; CHECK-NEXT:    [[TMP18:%.*]] = add i64 2, poison647; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP18]]648; CHECK-NEXT:    [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1649; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP29]], i8 [[TMP20]], i32 2650; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE4]]651; CHECK:       [[PRED_LOAD_CONTINUE4]]:652; CHECK-NEXT:    [[TMP22:%.*]] = phi <4 x i8> [ [[TMP29]], %[[PRED_LOAD_CONTINUE2]] ], [ [[TMP21]], %[[PRED_LOAD_IF3]] ]653; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3654; CHECK-NEXT:    br i1 [[TMP9]], label %[[PRED_LOAD_IF5:.*]], label %[[PRED_LOAD_CONTINUE6:.*]]655; CHECK:       [[PRED_LOAD_IF5]]:656; CHECK-NEXT:    [[TMP12:%.*]] = add i64 3, poison657; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP12]]658; CHECK-NEXT:    [[TMP27:%.*]] = load i8, ptr [[TMP13]], align 1659; CHECK-NEXT:    [[TMP28:%.*]] = insertelement <4 x i8> [[TMP22]], i8 [[TMP27]], i32 3660; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE6]]661; CHECK:       [[PRED_LOAD_CONTINUE6]]:662; CHECK-NEXT:    [[TMP30:%.*]] = phi <4 x i8> [ [[TMP22]], %[[PRED_LOAD_CONTINUE4]] ], [ [[TMP28]], %[[PRED_LOAD_IF5]] ]663; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> [[TMP30]], <4 x i8> zeroinitializer664; CHECK-NEXT:    store <4 x i8> [[PREDPHI]], ptr [[DST]], align 4665; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]666; CHECK:       [[MIDDLE_BLOCK]]:667;668 669entry:670  br label %loop.header671 672loop.header:673  %iv = phi i64 [ 0, %entry ], [ %inc, %loop.latch ]674  %cmp = icmp eq i64 %iv, %n675  br i1 %cmp, label %loop.latch, label %then676 677then:678  %rem = srem i64 3, 0679  %add3 = add i64 %rem, -3680  %add5 = add i64 %iv, %add3681  %gep = getelementptr [5 x i8], ptr @c, i64 0, i64 %add5682  %l = load i8, ptr %gep, align 1683  br label %loop.latch684 685loop.latch:686  %sr = phi i8 [ 0, %loop.header ], [ %l , %then ]687  %gep.dst = getelementptr i8, ptr %dst, i64 %iv688  store i8 %sr, ptr %gep.dst, align 4689  %inc = add i64 %iv, 1690  %exitcond.not = icmp eq i64 %inc, 4691  br i1 %exitcond.not, label %exit, label %loop.header692 693exit:694  ret void695}696 697; Variation of the above test with the poison value being used in all lanes.698define void @recipe_without_underlying_instr_lanes_used(i64 %n, ptr noalias %dst, ptr noalias %aux) {699; CHECK-LABEL: define void @recipe_without_underlying_instr_lanes_used(700; CHECK-SAME: i64 [[N:%.*]], ptr noalias [[DST:%.*]], ptr noalias [[AUX:%.*]]) {701; CHECK-NEXT:  [[ENTRY:.*:]]702; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]703; CHECK:       [[VECTOR_PH]]:704; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[N]], i64 0705; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer706; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]707; CHECK:       [[VECTOR_BODY]]:708; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <4 x i64> <i64 0, i64 1, i64 2, i64 3>, [[BROADCAST_SPLAT]]709; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0710; CHECK-NEXT:    br i1 [[TMP2]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]711; CHECK:       [[PRED_LOAD_IF]]:712; CHECK-NEXT:    [[TMP16:%.*]] = add i64 0, poison713; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP16]]714; CHECK-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP23]], align 1715; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i8> poison, i8 [[TMP6]], i32 0716; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE]]717; CHECK:       [[PRED_LOAD_CONTINUE]]:718; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i8> [ poison, %[[VECTOR_BODY]] ], [ [[TMP24]], %[[PRED_LOAD_IF]] ]719; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1720; CHECK-NEXT:    br i1 [[TMP3]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2:.*]]721; CHECK:       [[PRED_LOAD_IF1]]:722; CHECK-NEXT:    [[TMP29:%.*]] = add i64 1, poison723; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP29]]724; CHECK-NEXT:    [[TMP13:%.*]] = load i8, ptr [[TMP30]], align 1725; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <4 x i8> [[TMP25]], i8 [[TMP13]], i32 1726; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE2]]727; CHECK:       [[PRED_LOAD_CONTINUE2]]:728; CHECK-NEXT:    [[TMP15:%.*]] = phi <4 x i8> [ [[TMP25]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]729; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2730; CHECK-NEXT:    br i1 [[TMP4]], label %[[PRED_LOAD_IF3:.*]], label %[[PRED_LOAD_CONTINUE4:.*]]731; CHECK:       [[PRED_LOAD_IF3]]:732; CHECK-NEXT:    [[TMP18:%.*]] = add i64 2, poison733; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP18]]734; CHECK-NEXT:    [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1735; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP15]], i8 [[TMP20]], i32 2736; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE4]]737; CHECK:       [[PRED_LOAD_CONTINUE4]]:738; CHECK-NEXT:    [[TMP22:%.*]] = phi <4 x i8> [ [[TMP15]], %[[PRED_LOAD_CONTINUE2]] ], [ [[TMP21]], %[[PRED_LOAD_IF3]] ]739; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3740; CHECK-NEXT:    br i1 [[TMP5]], label %[[PRED_LOAD_IF5:.*]], label %[[PRED_LOAD_CONTINUE6:.*]]741; CHECK:       [[PRED_LOAD_IF5]]:742; CHECK-NEXT:    [[TMP7:%.*]] = add i64 3, poison743; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr [5 x i8], ptr @c, i64 0, i64 [[TMP7]]744; CHECK-NEXT:    [[TMP27:%.*]] = load i8, ptr [[TMP8]], align 1745; CHECK-NEXT:    [[TMP28:%.*]] = insertelement <4 x i8> [[TMP22]], i8 [[TMP27]], i32 3746; CHECK-NEXT:    br label %[[PRED_LOAD_CONTINUE6]]747; CHECK:       [[PRED_LOAD_CONTINUE6]]:748; CHECK-NEXT:    [[TMP26:%.*]] = phi <4 x i8> [ [[TMP22]], %[[PRED_LOAD_CONTINUE4]] ], [ [[TMP28]], %[[PRED_LOAD_IF5]] ]749; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> [[TMP26]], <4 x i8> zeroinitializer750; CHECK-NEXT:    [[PREDPHI7:%.*]] = select <4 x i1> [[TMP1]], <4 x i64> poison, <4 x i64> zeroinitializer751; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <4 x i64> [[PREDPHI7]], i32 3752; CHECK-NEXT:    store i64 [[TMP12]], ptr [[AUX]], align 8753; CHECK-NEXT:    store <4 x i8> [[PREDPHI]], ptr [[DST]], align 4754; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]755; CHECK:       [[MIDDLE_BLOCK]]:756;757 758entry:759  br label %loop.header760 761loop.header:762  %iv = phi i64 [ 0, %entry ], [ %inc, %loop.latch ]763  %cmp = icmp eq i64 %iv, %n764  br i1 %cmp, label %loop.latch, label %then765 766then:767  %rem = srem i64 3, 0768  %add3 = add i64 %rem, -3769  %add5 = add i64 %iv, %add3770  %gep = getelementptr [5 x i8], ptr @c, i64 0, i64 %add5771  %l = load i8, ptr %gep, align 1772  br label %loop.latch773 774loop.latch:775  %sr = phi i8 [ 0, %loop.header ], [ %l , %then ]776  %p = phi i64 [ 0, %loop.header ], [ %rem, %then ]777  store i64 %p, ptr %aux778  %gep.dst = getelementptr i8, ptr %dst, i64 %iv779  store i8 %sr, ptr %gep.dst, align 4780  %inc = add i64 %iv, 1781  %exitcond.not = icmp eq i64 %inc, 4782  br i1 %exitcond.not, label %exit, label %loop.header783 784exit:785  ret void786}787 788; %B.gep.0 and pointers based on it can preserve inbounds, as the inbounds789; versionused unconditionally in the store in the latch.790; FIXME: at the moment, inbounds is dropped from both the GEP feeding the vector load ans tore791define void @Bgep_inbounds_unconditionally_due_to_store(ptr noalias %B, ptr readonly %C) #0 {792; CHECK-LABEL: define void @Bgep_inbounds_unconditionally_due_to_store(793; CHECK-SAME: ptr noalias [[B:%.*]], ptr readonly [[C:%.*]]) #[[ATTR0]] {794; CHECK-NEXT:  [[ENTRY:.*:]]795; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]796; CHECK:       [[VECTOR_PH]]:797; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]798; CHECK:       [[VECTOR_BODY]]:799; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]800; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[INDEX]]801; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4802; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], splat (i32 20)803; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr float, ptr [[B]], i64 [[INDEX]]804; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x float>, ptr [[TMP3]], align 4805; CHECK-NEXT:    [[TMP5:%.*]] = fadd <4 x float> [[WIDE_LOAD1]], splat (float 2.000000e+00)806; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP2]], <4 x float> splat (float 3.300000e+01), <4 x float> [[TMP5]]807; CHECK-NEXT:    store <4 x float> [[PREDPHI]], ptr [[TMP3]], align 4808; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4809; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 10000810; CHECK-NEXT:    br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]811; CHECK:       [[MIDDLE_BLOCK]]:812;813 814entry:815  br label %loop.body816 817loop.body:818  %iv1 = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]819  %C.gep = getelementptr inbounds i32, ptr %C, i64 %iv1820  %C.lv = load i32, ptr %C.gep, align 4821  %cmp = icmp eq i32 %C.lv, 20822  %B.gep.0 = getelementptr inbounds float, ptr %B, i64 %iv1823  br i1 %cmp, label %loop.latch, label %else824 825else:826  %B.lv = load float, ptr %B.gep.0, align 4827  %add = fadd float %B.lv, 2.0828  br label %loop.latch829 830loop.latch:831  %add.sink = phi float [ %add, %else ], [ 33.0, %loop.body ]832  store float %add.sink, ptr %B.gep.0, align 4833  %iv.next = add nuw nsw i64 %iv1, 1834  %exitcond.not = icmp eq i64 %iv.next, 10000835  br i1 %exitcond.not, label %exit, label %loop.body836 837exit:838  ret void839}840 841attributes #0 = { noinline nounwind uwtable "target-features"="+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl" }842attributes #1 = { "target-features"="+avx" }843 844!0 = !{}845