395 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "scalar.ph:" --version 52; RUN: opt -p loop-vectorize -force-widen-divrem-via-safe-divisor=false -force-vector-width=2 -S %s | FileCheck %s3 4target datalayout="p:16:16"5 6@src = global [16 x i64] zeroinitializer7 8; Test cases for https://github.com/llvm/llvm-project/issues/1429579 10; Cannot speculatively execute %l, because %div may trigger UB and must be11; predicated.12define void @ptr_depends_on_sdiv(ptr noalias %dst, i16 noundef %off) {13; CHECK-LABEL: define void @ptr_depends_on_sdiv(14; CHECK-SAME: ptr noalias [[DST:%.*]], i16 noundef [[OFF:%.*]]) {15; CHECK-NEXT: [[ENTRY:.*:]]16; CHECK-NEXT: br label %[[VECTOR_PH:.*]]17; CHECK: [[VECTOR_PH]]:18; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]19; CHECK: [[VECTOR_BODY]]:20; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE4:.*]] ]21; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 9, i16 10>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE4]] ]22; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[INDEX]] to i1623; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i16 9, [[DOTCAST]]24; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <2 x i16> [[VEC_IND]], splat (i16 10)25; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP0]], i32 026; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_SDIV_IF:.*]], label %[[PRED_SDIV_CONTINUE:.*]]27; CHECK: [[PRED_SDIV_IF]]:28; CHECK-NEXT: [[TMP2:%.*]] = sdiv i16 24316, [[OFF]]29; CHECK-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i32 030; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE]]31; CHECK: [[PRED_SDIV_CONTINUE]]:32; CHECK-NEXT: [[TMP4:%.*]] = phi <2 x i16> [ poison, %[[VECTOR_BODY]] ], [ [[TMP3]], %[[PRED_SDIV_IF]] ]33; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x i1> [[TMP0]], i32 134; CHECK-NEXT: br i1 [[TMP14]], label %[[PRED_SDIV_IF1:.*]], label %[[PRED_SDIV_CONTINUE2:.*]]35; CHECK: [[PRED_SDIV_IF1]]:36; CHECK-NEXT: [[TMP18:%.*]] = sdiv i16 24316, [[OFF]]37; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i16> [[TMP4]], i16 [[TMP18]], i32 138; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE2]]39; CHECK: [[PRED_SDIV_CONTINUE2]]:40; CHECK-NEXT: [[TMP8:%.*]] = phi <2 x i16> [ [[TMP4]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP7]], %[[PRED_SDIV_IF1]] ]41; CHECK-NEXT: [[TMP21:%.*]] = add <2 x i16> [[VEC_IND]], splat (i16 16383)42; CHECK-NEXT: [[TMP22:%.*]] = shl <2 x i16> [[TMP8]], splat (i16 14)43; CHECK-NEXT: [[TMP23:%.*]] = sub <2 x i16> [[TMP21]], [[TMP22]]44; CHECK-NEXT: [[TMP19:%.*]] = extractelement <2 x i1> [[TMP0]], i32 045; CHECK-NEXT: br i1 [[TMP19]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]46; CHECK: [[PRED_STORE_IF]]:47; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i16> [[TMP23]], i32 048; CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP13]]49; CHECK-NEXT: [[TMP9:%.*]] = load i64, ptr [[TMP24]], align 150; CHECK-NEXT: [[TMP10:%.*]] = add i16 [[OFFSET_IDX]], 051; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP10]]52; CHECK-NEXT: store i64 [[TMP9]], ptr [[TMP11]], align 153; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]54; CHECK: [[PRED_STORE_CONTINUE]]:55; CHECK-NEXT: [[TMP12:%.*]] = extractelement <2 x i1> [[TMP0]], i32 156; CHECK-NEXT: br i1 [[TMP12]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4]]57; CHECK: [[PRED_STORE_IF3]]:58; CHECK-NEXT: [[TMP25:%.*]] = extractelement <2 x i16> [[TMP23]], i32 159; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP25]]60; CHECK-NEXT: [[TMP15:%.*]] = load i64, ptr [[TMP20]], align 161; CHECK-NEXT: [[TMP16:%.*]] = add i16 [[OFFSET_IDX]], 162; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP16]]63; CHECK-NEXT: store i64 [[TMP15]], ptr [[TMP17]], align 164; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE4]]65; CHECK: [[PRED_STORE_CONTINUE4]]:66; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 267; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], splat (i16 2)68; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]69; CHECK: [[MIDDLE_BLOCK]]:70; CHECK-NEXT: br [[EXIT:label %.*]]71; CHECK: [[SCALAR_PH:.*:]]72;73entry:74 br label %loop.header75 76loop.header:77 %iv = phi i16 [ 9, %entry ], [ %iv.next, %loop.latch ]78 %cmp1 = icmp eq i16 %iv, 1079 br i1 %cmp1, label %if.then, label %loop.latch80 81if.then:82 %div = sdiv i16 24316, %off83 %add.iv = add i16 %iv, 1638384 %s = shl i16 %div, 1485 %sub6 = sub i16 %add.iv, %s86 %gep.src = getelementptr inbounds i64, ptr @src, i16 %sub687 %l = load i64, ptr %gep.src, align 188 %gep.dst = getelementptr inbounds i64, ptr %dst, i16 %iv89 store i64 %l, ptr %gep.dst, align 190 br label %loop.latch91 92loop.latch:93 %iv.next = add i16 %iv, 194 %ec = icmp eq i16 %iv.next, 1195 br i1 %ec, label %exit, label %loop.header96 97exit:98 ret void99}100 101; Cannot speculatively execute %l, because %off may be poison.102define void @ptr_depends_on_possibly_poison_value(ptr noalias %dst, i16 %off) {103; CHECK-LABEL: define void @ptr_depends_on_possibly_poison_value(104; CHECK-SAME: ptr noalias [[DST:%.*]], i16 [[OFF:%.*]]) {105; CHECK-NEXT: [[ENTRY:.*:]]106; CHECK-NEXT: br label %[[VECTOR_PH:.*]]107; CHECK: [[VECTOR_PH]]:108; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i16> poison, i16 [[OFF]], i64 0109; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT]], <2 x i16> poison, <2 x i32> zeroinitializer110; CHECK-NEXT: [[TMP0:%.*]] = sub <2 x i16> splat (i16 1), [[BROADCAST_SPLAT]]111; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i16> [[TMP0]], [[BROADCAST_SPLAT]]112; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]113; CHECK: [[VECTOR_BODY]]:114; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ]115; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 9, i16 10>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE2]] ]116; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[INDEX]] to i16117; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i16 9, [[DOTCAST]]118; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i16> [[VEC_IND]], splat (i16 10)119; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i16> [[VEC_IND]], [[TMP1]]120; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP2]], i32 0121; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]122; CHECK: [[PRED_STORE_IF]]:123; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i16> [[TMP3]], i32 0124; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP5]]125; CHECK-NEXT: [[TMP9:%.*]] = load i64, ptr [[TMP14]], align 1126; CHECK-NEXT: [[TMP7:%.*]] = add i16 [[OFFSET_IDX]], 0127; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP7]]128; CHECK-NEXT: store i64 [[TMP9]], ptr [[TMP8]], align 1129; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]130; CHECK: [[PRED_STORE_CONTINUE]]:131; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP2]], i32 1132; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2]]133; CHECK: [[PRED_STORE_IF1]]:134; CHECK-NEXT: [[TMP15:%.*]] = extractelement <2 x i16> [[TMP3]], i32 1135; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP15]]136; CHECK-NEXT: [[TMP13:%.*]] = load i64, ptr [[TMP16]], align 1137; CHECK-NEXT: [[TMP11:%.*]] = add i16 [[OFFSET_IDX]], 1138; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP11]]139; CHECK-NEXT: store i64 [[TMP13]], ptr [[TMP12]], align 1140; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE2]]141; CHECK: [[PRED_STORE_CONTINUE2]]:142; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2143; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], splat (i16 2)144; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]145; CHECK: [[MIDDLE_BLOCK]]:146; CHECK-NEXT: br [[EXIT:label %.*]]147; CHECK: [[SCALAR_PH:.*:]]148;149entry:150 br label %loop.header151 152loop.header:153 %iv = phi i16 [ 9, %entry ], [ %iv.next, %loop.latch ]154 %cmp1 = icmp eq i16 %iv, 10155 br i1 %cmp1, label %if.then, label %loop.latch156 157if.then:158 %sub = sub i16 1, %off159 %add = add i16 %sub, %off160 %add.iv = add i16 %iv, %add161 %gep.src = getelementptr inbounds i64, ptr @src, i16 %add.iv162 %l = load i64, ptr %gep.src, align 1163 %gep.dst = getelementptr inbounds i64, ptr %dst, i16 %iv164 store i64 %l, ptr %gep.dst, align 1165 br label %loop.latch166 167loop.latch:168 %iv.next = add i16 %iv, 1169 %ec = icmp eq i16 %iv.next, 11170 br i1 %ec, label %exit, label %loop.header171 172exit:173 ret void174}175 176define void @ptr_doesnt_depend_on_poison_or_ub(ptr noalias %dst, i16 noundef %off) {177; CHECK-LABEL: define void @ptr_doesnt_depend_on_poison_or_ub(178; CHECK-SAME: ptr noalias [[DST:%.*]], i16 noundef [[OFF:%.*]]) {179; CHECK-NEXT: [[ENTRY:.*:]]180; CHECK-NEXT: br label %[[VECTOR_PH:.*]]181; CHECK: [[VECTOR_PH]]:182; CHECK-NEXT: [[TMP0:%.*]] = sub i16 1, [[OFF]]183; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], [[OFF]]184; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]185; CHECK: [[VECTOR_BODY]]:186; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ]187; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 9, i16 10>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE2]] ]188; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[INDEX]] to i16189; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i16 9, [[DOTCAST]]190; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i16> [[VEC_IND]], splat (i16 10)191; CHECK-NEXT: [[TMP3:%.*]] = add i16 [[OFFSET_IDX]], [[TMP1]]192; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i64, ptr @src, i16 [[TMP3]]193; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP4]], align 1194; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP2]], i32 0195; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]196; CHECK: [[PRED_STORE_IF]]:197; CHECK-NEXT: [[TMP7:%.*]] = add i16 [[OFFSET_IDX]], 0198; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP7]]199; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 0200; CHECK-NEXT: store i64 [[TMP9]], ptr [[TMP8]], align 1201; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]202; CHECK: [[PRED_STORE_CONTINUE]]:203; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP2]], i32 1204; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2]]205; CHECK: [[PRED_STORE_IF1]]:206; CHECK-NEXT: [[TMP11:%.*]] = add i16 [[OFFSET_IDX]], 1207; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP11]]208; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 1209; CHECK-NEXT: store i64 [[TMP13]], ptr [[TMP12]], align 1210; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE2]]211; CHECK: [[PRED_STORE_CONTINUE2]]:212; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2213; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], splat (i16 2)214; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]215; CHECK: [[MIDDLE_BLOCK]]:216; CHECK-NEXT: br [[EXIT:label %.*]]217; CHECK: [[SCALAR_PH:.*:]]218;219entry:220 br label %loop.header221 222loop.header:223 %iv = phi i16 [ 9, %entry ], [ %iv.next, %loop.latch ]224 %cmp1 = icmp eq i16 %iv, 10225 br i1 %cmp1, label %if.then, label %loop.latch226 227if.then:228 %sub = sub i16 1, %off229 %add = add i16 %sub, %off230 %add.iv = add i16 %iv, %add231 %gep.src = getelementptr inbounds i64, ptr @src, i16 %add.iv232 %l = load i64, ptr %gep.src, align 1233 %gep.dst = getelementptr inbounds i64, ptr %dst, i16 %iv234 store i64 %l, ptr %gep.dst, align 1235 br label %loop.latch236 237loop.latch:238 %iv.next = add i16 %iv, 1239 %ec = icmp eq i16 %iv.next, 11240 br i1 %ec, label %exit, label %loop.header241 242exit:243 ret void244}245 246; Cannot speculatively execute %l, because %off may be poison.247define void @ptr_depends_on_possibly_poison_value_from_load(ptr noalias %dst) {248; CHECK-LABEL: define void @ptr_depends_on_possibly_poison_value_from_load(249; CHECK-SAME: ptr noalias [[DST:%.*]]) {250; CHECK-NEXT: [[ENTRY:.*:]]251; CHECK-NEXT: br label %[[VECTOR_PH:.*]]252; CHECK: [[VECTOR_PH]]:253; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]254; CHECK: [[VECTOR_BODY]]:255; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ]256; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 9, i16 10>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE2]] ]257; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[INDEX]] to i16258; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i16 9, [[DOTCAST]]259; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @src, align 1260; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i16> poison, i16 [[TMP0]], i64 0261; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT]], <2 x i16> poison, <2 x i32> zeroinitializer262; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i16> [[VEC_IND]], splat (i16 10)263; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i16> splat (i16 1), [[BROADCAST_SPLAT]]264; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i16> [[TMP2]], [[BROADCAST_SPLAT]]265; CHECK-NEXT: [[TMP4:%.*]] = add <2 x i16> [[VEC_IND]], [[TMP3]]266; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP1]], i32 0267; CHECK-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]268; CHECK: [[PRED_STORE_IF]]:269; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i16> [[TMP4]], i32 0270; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP6]]271; CHECK-NEXT: [[TMP10:%.*]] = load i64, ptr [[TMP15]], align 1272; CHECK-NEXT: [[TMP8:%.*]] = add i16 [[OFFSET_IDX]], 0273; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP8]]274; CHECK-NEXT: store i64 [[TMP10]], ptr [[TMP9]], align 1275; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]276; CHECK: [[PRED_STORE_CONTINUE]]:277; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP1]], i32 1278; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2]]279; CHECK: [[PRED_STORE_IF1]]:280; CHECK-NEXT: [[TMP16:%.*]] = extractelement <2 x i16> [[TMP4]], i32 1281; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i64, ptr @src, i16 [[TMP16]]282; CHECK-NEXT: [[TMP14:%.*]] = load i64, ptr [[TMP17]], align 1283; CHECK-NEXT: [[TMP12:%.*]] = add i16 [[OFFSET_IDX]], 1284; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP12]]285; CHECK-NEXT: store i64 [[TMP14]], ptr [[TMP13]], align 1286; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE2]]287; CHECK: [[PRED_STORE_CONTINUE2]]:288; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2289; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], splat (i16 2)290; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]291; CHECK: [[MIDDLE_BLOCK]]:292; CHECK-NEXT: br [[EXIT:label %.*]]293; CHECK: [[SCALAR_PH:.*:]]294;295entry:296 br label %loop.header297 298loop.header:299 %iv = phi i16 [ 9, %entry ], [ %iv.next, %loop.latch ]300 %off = load i16, ptr @src, align 1301 %cmp1 = icmp eq i16 %iv, 10302 br i1 %cmp1, label %if.then, label %loop.latch303 304if.then:305 %sub = sub i16 1, %off306 %add = add i16 %sub, %off307 %add.iv = add i16 %iv, %add308 %gep.src = getelementptr inbounds i64, ptr @src, i16 %add.iv309 %l = load i64, ptr %gep.src, align 1310 %gep.dst = getelementptr inbounds i64, ptr %dst, i16 %iv311 store i64 %l, ptr %gep.dst, align 1312 br label %loop.latch313 314loop.latch:315 %iv.next = add i16 %iv, 1316 %ec = icmp eq i16 %iv.next, 11317 br i1 %ec, label %exit, label %loop.header318 319exit:320 ret void321}322 323; Can speculatively execute %l, because %off cannot be poison due to !noundef.324define void @ptr_depends_on_noundef_load(ptr noalias %dst) {325; CHECK-LABEL: define void @ptr_depends_on_noundef_load(326; CHECK-SAME: ptr noalias [[DST:%.*]]) {327; CHECK-NEXT: [[ENTRY:.*:]]328; CHECK-NEXT: br label %[[VECTOR_PH:.*]]329; CHECK: [[VECTOR_PH]]:330; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]331; CHECK: [[VECTOR_BODY]]:332; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ]333; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 9, i16 10>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE2]] ]334; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[INDEX]] to i16335; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i16 9, [[DOTCAST]]336; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @src, align 1, !noundef [[META10:![0-9]+]]337; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i16> [[VEC_IND]], splat (i16 10)338; CHECK-NEXT: [[TMP2:%.*]] = sub i16 1, [[TMP0]]339; CHECK-NEXT: [[TMP3:%.*]] = add i16 [[TMP2]], [[TMP0]]340; CHECK-NEXT: [[TMP4:%.*]] = add i16 [[OFFSET_IDX]], [[TMP3]]341; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i64, ptr @src, i16 [[TMP4]]342; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP5]], align 1343; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP1]], i32 0344; CHECK-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]345; CHECK: [[PRED_STORE_IF]]:346; CHECK-NEXT: [[TMP8:%.*]] = add i16 [[OFFSET_IDX]], 0347; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP8]]348; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 0349; CHECK-NEXT: store i64 [[TMP10]], ptr [[TMP9]], align 1350; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]351; CHECK: [[PRED_STORE_CONTINUE]]:352; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP1]], i32 1353; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2]]354; CHECK: [[PRED_STORE_IF1]]:355; CHECK-NEXT: [[TMP12:%.*]] = add i16 [[OFFSET_IDX]], 1356; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[DST]], i16 [[TMP12]]357; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 1358; CHECK-NEXT: store i64 [[TMP14]], ptr [[TMP13]], align 1359; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE2]]360; CHECK: [[PRED_STORE_CONTINUE2]]:361; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2362; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], splat (i16 2)363; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]364; CHECK: [[MIDDLE_BLOCK]]:365; CHECK-NEXT: br [[EXIT:label %.*]]366; CHECK: [[SCALAR_PH:.*:]]367;368entry:369 br label %loop.header370 371loop.header:372 %iv = phi i16 [ 9, %entry ], [ %iv.next, %loop.latch ]373 %off = load i16, ptr @src, align 1, !noundef !{}374 %cmp1 = icmp eq i16 %iv, 10375 br i1 %cmp1, label %if.then, label %loop.latch376 377if.then:378 %sub = sub i16 1, %off379 %add = add i16 %sub, %off380 %add.iv = add i16 %iv, %add381 %gep.src = getelementptr inbounds i64, ptr @src, i16 %add.iv382 %l = load i64, ptr %gep.src, align 1383 %gep.dst = getelementptr inbounds i64, ptr %dst, i16 %iv384 store i64 %l, ptr %gep.dst, align 1385 br label %loop.latch386 387loop.latch:388 %iv.next = add i16 %iv, 1389 %ec = icmp eq i16 %iv.next, 11390 br i1 %ec, label %exit, label %loop.header391 392exit:393 ret void394}395