brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.0 KiB · 85072bf Raw
419 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt %s -S -passes='loop(loop-flatten),verify' -verify-loop-info -verify-dom-info -verify-scev -o - | FileCheck %s3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"5 6; We need to version the loop as the GEPs are not inbounds7define void @noinbounds_gep(i32 %N, ptr %A) {8; CHECK-LABEL: define void @noinbounds_gep(9; CHECK-SAME: i32 [[N:%.*]], ptr [[A:%.*]]) {10; CHECK-NEXT:  entry:11; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 0, [[N]]12; CHECK-NEXT:    br i1 [[CMP3]], label [[FOR_INNER_PREHEADER_LVER_CHECK:%.*]], label [[FOR_END:%.*]]13; CHECK:       for.inner.preheader.lver.check:14; CHECK-NEXT:    [[FLATTEN_MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 [[N]])15; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 016; CHECK-NEXT:    [[FLATTEN_OVERFLOW:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 117; CHECK-NEXT:    br i1 [[FLATTEN_OVERFLOW]], label [[FOR_INNER_PREHEADER_PH_LVER_ORIG:%.*]], label [[FOR_INNER_PREHEADER_PH:%.*]]18; CHECK:       for.inner.preheader.ph.lver.orig:19; CHECK-NEXT:    br label [[FOR_INNER_PREHEADER_LVER_ORIG:%.*]]20; CHECK:       for.inner.preheader.lver.orig:21; CHECK-NEXT:    [[I_LVER_ORIG:%.*]] = phi i32 [ 0, [[FOR_INNER_PREHEADER_PH_LVER_ORIG]] ], [ [[INC2_LVER_ORIG:%.*]], [[FOR_OUTER_LVER_ORIG:%.*]] ]22; CHECK-NEXT:    br label [[FOR_INNER_LVER_ORIG:%.*]]23; CHECK:       for.inner.lver.orig:24; CHECK-NEXT:    [[J_LVER_ORIG:%.*]] = phi i32 [ 0, [[FOR_INNER_PREHEADER_LVER_ORIG]] ], [ [[INC1_LVER_ORIG:%.*]], [[FOR_INNER_LVER_ORIG]] ]25; CHECK-NEXT:    [[MUL_LVER_ORIG:%.*]] = mul i32 [[I_LVER_ORIG]], [[N]]26; CHECK-NEXT:    [[GEP_LVER_ORIG:%.*]] = getelementptr i32, ptr [[A]], i32 [[MUL_LVER_ORIG]]27; CHECK-NEXT:    [[ARRAYIDX_LVER_ORIG:%.*]] = getelementptr i32, ptr [[GEP_LVER_ORIG]], i32 [[J_LVER_ORIG]]28; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_LVER_ORIG]], align 429; CHECK-NEXT:    [[INC1_LVER_ORIG]] = add nuw i32 [[J_LVER_ORIG]], 130; CHECK-NEXT:    [[CMP2_LVER_ORIG:%.*]] = icmp ult i32 [[INC1_LVER_ORIG]], [[N]]31; CHECK-NEXT:    br i1 [[CMP2_LVER_ORIG]], label [[FOR_INNER_LVER_ORIG]], label [[FOR_OUTER_LVER_ORIG]]32; CHECK:       for.outer.lver.orig:33; CHECK-NEXT:    [[INC2_LVER_ORIG]] = add i32 [[I_LVER_ORIG]], 134; CHECK-NEXT:    [[CMP1_LVER_ORIG:%.*]] = icmp ult i32 [[INC2_LVER_ORIG]], [[N]]35; CHECK-NEXT:    br i1 [[CMP1_LVER_ORIG]], label [[FOR_INNER_PREHEADER_LVER_ORIG]], label [[FOR_END_LOOPEXIT_LOOPEXIT:%.*]]36; CHECK:       for.inner.preheader.ph:37; CHECK-NEXT:    br label [[FOR_INNER_PREHEADER:%.*]]38; CHECK:       for.inner.preheader:39; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[FOR_INNER_PREHEADER_PH]] ], [ [[INC2:%.*]], [[FOR_OUTER:%.*]] ]40; CHECK-NEXT:    [[FLATTEN_ARRAYIDX:%.*]] = getelementptr i32, ptr [[A]], i32 [[I]]41; CHECK-NEXT:    br label [[FOR_INNER:%.*]]42; CHECK:       for.inner:43; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_INNER_PREHEADER]] ]44; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[N]]45; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[A]], i32 [[MUL]]46; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr i32, ptr [[GEP]], i32 [[J]]47; CHECK-NEXT:    store i32 0, ptr [[FLATTEN_ARRAYIDX]], align 448; CHECK-NEXT:    [[INC1:%.*]] = add nuw i32 [[J]], 149; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[INC1]], [[N]]50; CHECK-NEXT:    br label [[FOR_OUTER]]51; CHECK:       for.outer:52; CHECK-NEXT:    [[INC2]] = add i32 [[I]], 153; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[INC2]], [[FLATTEN_TRIPCOUNT]]54; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_INNER_PREHEADER]], label [[FOR_END_LOOPEXIT_LOOPEXIT1:%.*]]55; CHECK:       for.end.loopexit.loopexit:56; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT:%.*]]57; CHECK:       for.end.loopexit.loopexit1:58; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]59; CHECK:       for.end.loopexit:60; CHECK-NEXT:    br label [[FOR_END]]61; CHECK:       for.end:62; CHECK-NEXT:    ret void63;64entry:65  %cmp3 = icmp ult i32 0, %N66  br i1 %cmp3, label %for.outer.preheader, label %for.end67 68for.outer.preheader:69  br label %for.inner.preheader70 71for.inner.preheader:72  %i = phi i32 [ 0, %for.outer.preheader ], [ %inc2, %for.outer ]73  br label %for.inner74 75for.inner:76  %j = phi i32 [ 0, %for.inner.preheader ], [ %inc1, %for.inner ]77  %mul = mul i32 %i, %N78  %gep = getelementptr i32, ptr %A, i32 %mul79  %arrayidx = getelementptr i32, ptr %gep, i32 %j80  store i32 0, ptr %arrayidx, align 481  %inc1 = add nuw i32 %j, 182  %cmp2 = icmp ult i32 %inc1, %N83  br i1 %cmp2, label %for.inner, label %for.outer84 85for.outer:86  %inc2 = add i32 %i, 187  %cmp1 = icmp ult i32 %inc2, %N88  br i1 %cmp1, label %for.inner.preheader, label %for.end.loopexit89 90for.end.loopexit:91  br label %for.end92 93for.end:94  ret void95}96 97; We shouldn't version the loop here as the multiply would use an illegal type.98define void @noinbounds_gep_too_large_mul(i64 %N, ptr %A) {99; CHECK-LABEL: define void @noinbounds_gep_too_large_mul(100; CHECK-SAME: i64 [[N:%.*]], ptr [[A:%.*]]) {101; CHECK-NEXT:  entry:102; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i64 0, [[N]]103; CHECK-NEXT:    br i1 [[CMP3]], label [[FOR_OUTER_PREHEADER:%.*]], label [[FOR_END:%.*]]104; CHECK:       for.outer.preheader:105; CHECK-NEXT:    br label [[FOR_INNER_PREHEADER:%.*]]106; CHECK:       for.inner.preheader:107; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, [[FOR_OUTER_PREHEADER]] ], [ [[INC2:%.*]], [[FOR_OUTER:%.*]] ]108; CHECK-NEXT:    br label [[FOR_INNER:%.*]]109; CHECK:       for.inner:110; CHECK-NEXT:    [[J:%.*]] = phi i64 [ 0, [[FOR_INNER_PREHEADER]] ], [ [[INC1:%.*]], [[FOR_INNER]] ]111; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[I]], [[N]]112; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[MUL]]113; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr i32, ptr [[GEP]], i64 [[J]]114; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4115; CHECK-NEXT:    [[INC1]] = add nuw i64 [[J]], 1116; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[INC1]], [[N]]117; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_INNER]], label [[FOR_OUTER]]118; CHECK:       for.outer:119; CHECK-NEXT:    [[INC2]] = add i64 [[I]], 1120; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[INC2]], [[N]]121; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_INNER_PREHEADER]], label [[FOR_END_LOOPEXIT:%.*]]122; CHECK:       for.end.loopexit:123; CHECK-NEXT:    br label [[FOR_END]]124; CHECK:       for.end:125; CHECK-NEXT:    ret void126;127entry:128  %cmp3 = icmp ult i64 0, %N129  br i1 %cmp3, label %for.outer.preheader, label %for.end130 131for.outer.preheader:132  br label %for.inner.preheader133 134for.inner.preheader:135  %i = phi i64 [ 0, %for.outer.preheader ], [ %inc2, %for.outer ]136  br label %for.inner137 138for.inner:139  %j = phi i64 [ 0, %for.inner.preheader ], [ %inc1, %for.inner ]140  %mul = mul i64 %i, %N141  %gep = getelementptr i32, ptr %A, i64 %mul142  %arrayidx = getelementptr i32, ptr %gep, i64 %j143  store i32 0, ptr %arrayidx, align 4144  %inc1 = add nuw i64 %j, 1145  %cmp2 = icmp ult i64 %inc1, %N146  br i1 %cmp2, label %for.inner, label %for.outer147 148for.outer:149  %inc2 = add i64 %i, 1150  %cmp1 = icmp ult i64 %inc2, %N151  br i1 %cmp1, label %for.inner.preheader, label %for.end.loopexit152 153for.end.loopexit:154  br label %for.end155 156for.end:157  ret void158}159 160; A 3d loop corresponding to:161;162;   for (int k = 0; k < N; ++k)163;    for (int i = 0; i < N; ++i)164;      for (int j = 0; j < M; ++j)165;        f(&A[i*M+j]);166;167define void @d3_2(ptr %A, i32 %N, i32 %M) {168; CHECK-LABEL: define void @d3_2(169; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {170; CHECK-NEXT:  entry:171; CHECK-NEXT:    [[CMP30:%.*]] = icmp sgt i32 [[N]], 0172; CHECK-NEXT:    br i1 [[CMP30]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]173; CHECK:       for.cond1.preheader.lr.ph:174; CHECK-NEXT:    [[CMP625:%.*]] = icmp sgt i32 [[M]], 0175; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]176; CHECK:       for.cond1.preheader.us:177; CHECK-NEXT:    [[K_031_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_LR_PH]] ], [ [[INC13_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ]178; CHECK-NEXT:    br i1 [[CMP625]], label [[FOR_COND5_PREHEADER_US_US_LVER_CHECK:%.*]], label [[FOR_COND5_PREHEADER_US43_PREHEADER:%.*]]179; CHECK:       for.cond5.preheader.us43.preheader:180; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_LOOPEXIT50:%.*]]181; CHECK:       for.cond5.preheader.us.us.lver.check:182; CHECK-NEXT:    [[FLATTEN_MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 [[M]])183; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 0184; CHECK-NEXT:    [[FLATTEN_OVERFLOW:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 1185; CHECK-NEXT:    br i1 [[FLATTEN_OVERFLOW]], label [[FOR_COND5_PREHEADER_US_US_PH_LVER_ORIG:%.*]], label [[FOR_COND5_PREHEADER_US_US_PH:%.*]]186; CHECK:       for.cond5.preheader.us.us.ph.lver.orig:187; CHECK-NEXT:    br label [[FOR_COND5_PREHEADER_US_US_LVER_ORIG:%.*]]188; CHECK:       for.cond5.preheader.us.us.lver.orig:189; CHECK-NEXT:    [[I_028_US_US_LVER_ORIG:%.*]] = phi i32 [ [[INC10_US_US_LVER_ORIG:%.*]], [[FOR_COND5_FOR_COND_CLEANUP7_CRIT_EDGE_US_US_LVER_ORIG:%.*]] ], [ 0, [[FOR_COND5_PREHEADER_US_US_PH_LVER_ORIG]] ]190; CHECK-NEXT:    [[MUL_US_US_LVER_ORIG:%.*]] = mul nsw i32 [[I_028_US_US_LVER_ORIG]], [[M]]191; CHECK-NEXT:    br label [[FOR_BODY8_US_US_LVER_ORIG:%.*]]192; CHECK:       for.body8.us.us.lver.orig:193; CHECK-NEXT:    [[J_026_US_US_LVER_ORIG:%.*]] = phi i32 [ 0, [[FOR_COND5_PREHEADER_US_US_LVER_ORIG]] ], [ [[INC_US_US_LVER_ORIG:%.*]], [[FOR_BODY8_US_US_LVER_ORIG]] ]194; CHECK-NEXT:    [[ADD_US_US_LVER_ORIG:%.*]] = add nsw i32 [[J_026_US_US_LVER_ORIG]], [[MUL_US_US_LVER_ORIG]]195; CHECK-NEXT:    [[IDXPROM_US_US_LVER_ORIG:%.*]] = sext i32 [[ADD_US_US_LVER_ORIG]] to i64196; CHECK-NEXT:    [[ARRAYIDX_US_US_LVER_ORIG:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM_US_US_LVER_ORIG]]197; CHECK-NEXT:    tail call void @f(ptr [[ARRAYIDX_US_US_LVER_ORIG]])198; CHECK-NEXT:    [[INC_US_US_LVER_ORIG]] = add nuw nsw i32 [[J_026_US_US_LVER_ORIG]], 1199; CHECK-NEXT:    [[EXITCOND_LVER_ORIG:%.*]] = icmp ne i32 [[INC_US_US_LVER_ORIG]], [[M]]200; CHECK-NEXT:    br i1 [[EXITCOND_LVER_ORIG]], label [[FOR_BODY8_US_US_LVER_ORIG]], label [[FOR_COND5_FOR_COND_CLEANUP7_CRIT_EDGE_US_US_LVER_ORIG]]201; CHECK:       for.cond5.for.cond.cleanup7_crit_edge.us.us.lver.orig:202; CHECK-NEXT:    [[INC10_US_US_LVER_ORIG]] = add nuw nsw i32 [[I_028_US_US_LVER_ORIG]], 1203; CHECK-NEXT:    [[EXITCOND51_LVER_ORIG:%.*]] = icmp ne i32 [[INC10_US_US_LVER_ORIG]], [[N]]204; CHECK-NEXT:    br i1 [[EXITCOND51_LVER_ORIG]], label [[FOR_COND5_PREHEADER_US_US_LVER_ORIG]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_LOOPEXIT_LOOPEXIT:%.*]]205; CHECK:       for.cond5.preheader.us.us.ph:206; CHECK-NEXT:    br label [[FOR_COND5_PREHEADER_US_US:%.*]]207; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us.loopexit.loopexit:208; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_LOOPEXIT:%.*]]209; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us.loopexit.loopexit1:210; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_LOOPEXIT]]211; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us.loopexit:212; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]213; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us.loopexit50:214; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]215; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us:216; CHECK-NEXT:    [[INC13_US]] = add nuw nsw i32 [[K_031_US]], 1217; CHECK-NEXT:    [[EXITCOND52:%.*]] = icmp ne i32 [[INC13_US]], [[N]]218; CHECK-NEXT:    br i1 [[EXITCOND52]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]219; CHECK:       for.cond5.preheader.us.us:220; CHECK-NEXT:    [[I_028_US_US:%.*]] = phi i32 [ [[INC10_US_US:%.*]], [[FOR_COND5_FOR_COND_CLEANUP7_CRIT_EDGE_US_US:%.*]] ], [ 0, [[FOR_COND5_PREHEADER_US_US_PH]] ]221; CHECK-NEXT:    [[MUL_US_US:%.*]] = mul nsw i32 [[I_028_US_US]], [[M]]222; CHECK-NEXT:    br label [[FOR_BODY8_US_US:%.*]]223; CHECK:       for.cond5.for.cond.cleanup7_crit_edge.us.us:224; CHECK-NEXT:    [[INC10_US_US]] = add nuw nsw i32 [[I_028_US_US]], 1225; CHECK-NEXT:    [[EXITCOND51:%.*]] = icmp ne i32 [[INC10_US_US]], [[FLATTEN_TRIPCOUNT]]226; CHECK-NEXT:    br i1 [[EXITCOND51]], label [[FOR_COND5_PREHEADER_US_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_LOOPEXIT_LOOPEXIT1:%.*]]227; CHECK:       for.body8.us.us:228; CHECK-NEXT:    [[J_026_US_US:%.*]] = phi i32 [ 0, [[FOR_COND5_PREHEADER_US_US]] ]229; CHECK-NEXT:    [[ADD_US_US:%.*]] = add nsw i32 [[J_026_US_US]], [[MUL_US_US]]230; CHECK-NEXT:    [[IDXPROM_US_US:%.*]] = sext i32 [[I_028_US_US]] to i64231; CHECK-NEXT:    [[ARRAYIDX_US_US:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM_US_US]]232; CHECK-NEXT:    tail call void @f(ptr [[ARRAYIDX_US_US]])233; CHECK-NEXT:    [[INC_US_US:%.*]] = add nuw nsw i32 [[J_026_US_US]], 1234; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[INC_US_US]], [[M]]235; CHECK-NEXT:    br label [[FOR_COND5_FOR_COND_CLEANUP7_CRIT_EDGE_US_US]]236; CHECK:       for.cond.cleanup.loopexit:237; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]238; CHECK:       for.cond.cleanup:239; CHECK-NEXT:    ret void240;241entry:242  %cmp30 = icmp sgt i32 %N, 0243  br i1 %cmp30, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup244 245for.cond1.preheader.lr.ph:246  %cmp625 = icmp sgt i32 %M, 0247  br label %for.cond1.preheader.us248 249for.cond1.preheader.us:250  %k.031.us = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %inc13.us, %for.cond1.for.cond.cleanup3_crit_edge.us ]251  br i1 %cmp625, label %for.cond5.preheader.us.us.preheader, label %for.cond5.preheader.us43.preheader252 253for.cond5.preheader.us43.preheader:254  br label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit50255 256for.cond5.preheader.us.us.preheader:257  br label %for.cond5.preheader.us.us258 259for.cond1.for.cond.cleanup3_crit_edge.us.loopexit:260  br label %for.cond1.for.cond.cleanup3_crit_edge.us261 262for.cond1.for.cond.cleanup3_crit_edge.us.loopexit50:263  br label %for.cond1.for.cond.cleanup3_crit_edge.us264 265for.cond1.for.cond.cleanup3_crit_edge.us:266  %inc13.us = add nuw nsw i32 %k.031.us, 1267  %exitcond52 = icmp ne i32 %inc13.us, %N268  br i1 %exitcond52, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit269 270for.cond5.preheader.us.us:271  %i.028.us.us = phi i32 [ %inc10.us.us, %for.cond5.for.cond.cleanup7_crit_edge.us.us ], [ 0, %for.cond5.preheader.us.us.preheader ]272  %mul.us.us = mul nsw i32 %i.028.us.us, %M273  br label %for.body8.us.us274 275for.cond5.for.cond.cleanup7_crit_edge.us.us:276  %inc10.us.us = add nuw nsw i32 %i.028.us.us, 1277  %exitcond51 = icmp ne i32 %inc10.us.us, %N278  br i1 %exitcond51, label %for.cond5.preheader.us.us, label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit279 280for.body8.us.us:281  %j.026.us.us = phi i32 [ 0, %for.cond5.preheader.us.us ], [ %inc.us.us, %for.body8.us.us ]282  %add.us.us = add nsw i32 %j.026.us.us, %mul.us.us283  %idxprom.us.us = sext i32 %add.us.us to i64284  %arrayidx.us.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us.us285  tail call void @f(ptr %arrayidx.us.us) #2286  %inc.us.us = add nuw nsw i32 %j.026.us.us, 1287  %exitcond = icmp ne i32 %inc.us.us, %M288  br i1 %exitcond, label %for.body8.us.us, label %for.cond5.for.cond.cleanup7_crit_edge.us.us289 290for.cond.cleanup.loopexit:291  br label %for.cond.cleanup292 293for.cond.cleanup:294  ret void295}296 297; GEP doesn't dominate the loop latch so we need to check if N*M will overflow.298@first = global i32 1, align 4299@a = external global [0 x i8], align 1300define void @overflow(i32 %lim, ptr %a) {301; CHECK-LABEL: define void @overflow(302; CHECK-SAME: i32 [[LIM:%.*]], ptr [[A:%.*]]) {303; CHECK-NEXT:  entry:304; CHECK-NEXT:    [[CMP17_NOT:%.*]] = icmp eq i32 [[LIM]], 0305; CHECK-NEXT:    br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LVER_CHECK:%.*]]306; CHECK:       for.cond1.preheader.lver.check:307; CHECK-NEXT:    [[FLATTEN_MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[LIM]], i32 100000)308; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 0309; CHECK-NEXT:    [[FLATTEN_OVERFLOW:%.*]] = extractvalue { i32, i1 } [[FLATTEN_MUL]], 1310; CHECK-NEXT:    br i1 [[FLATTEN_OVERFLOW]], label [[FOR_COND1_PREHEADER_PH_LVER_ORIG:%.*]], label [[FOR_COND1_PREHEADER_PH:%.*]]311; CHECK:       for.cond1.preheader.ph.lver.orig:312; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_LVER_ORIG:%.*]]313; CHECK:       for.cond1.preheader.lver.orig:314; CHECK-NEXT:    [[I_018_LVER_ORIG:%.*]] = phi i32 [ [[INC6_LVER_ORIG:%.*]], [[FOR_COND_CLEANUP3_LVER_ORIG:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_PH_LVER_ORIG]] ]315; CHECK-NEXT:    [[MUL_LVER_ORIG:%.*]] = mul i32 [[I_018_LVER_ORIG]], 100000316; CHECK-NEXT:    br label [[FOR_BODY4_LVER_ORIG:%.*]]317; CHECK:       for.body4.lver.orig:318; CHECK-NEXT:    [[J_016_LVER_ORIG:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_LVER_ORIG]] ], [ [[INC_LVER_ORIG:%.*]], [[IF_END_LVER_ORIG:%.*]] ]319; CHECK-NEXT:    [[ADD_LVER_ORIG:%.*]] = add i32 [[J_016_LVER_ORIG]], [[MUL_LVER_ORIG]]320; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @first, align 4321; CHECK-NEXT:    [[TOBOOL_NOT_LVER_ORIG:%.*]] = icmp eq i32 [[TMP0]], 0322; CHECK-NEXT:    br i1 [[TOBOOL_NOT_LVER_ORIG]], label [[IF_END_LVER_ORIG]], label [[IF_THEN_LVER_ORIG:%.*]]323; CHECK:       if.then.lver.orig:324; CHECK-NEXT:    [[ARRAYIDX_LVER_ORIG:%.*]] = getelementptr inbounds [0 x i8], ptr @a, i32 0, i32 [[ADD_LVER_ORIG]]325; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX_LVER_ORIG]], align 1326; CHECK-NEXT:    tail call void asm sideeffect "", "r"(i8 [[TMP1]])327; CHECK-NEXT:    store i32 0, ptr @first, align 4328; CHECK-NEXT:    br label [[IF_END_LVER_ORIG]]329; CHECK:       if.end.lver.orig:330; CHECK-NEXT:    tail call void asm sideeffect "", "r"(i32 [[ADD_LVER_ORIG]])331; CHECK-NEXT:    [[INC_LVER_ORIG]] = add nuw nsw i32 [[J_016_LVER_ORIG]], 1332; CHECK-NEXT:    [[CMP2_LVER_ORIG:%.*]] = icmp ult i32 [[J_016_LVER_ORIG]], 99999333; CHECK-NEXT:    br i1 [[CMP2_LVER_ORIG]], label [[FOR_BODY4_LVER_ORIG]], label [[FOR_COND_CLEANUP3_LVER_ORIG]]334; CHECK:       for.cond.cleanup3.lver.orig:335; CHECK-NEXT:    [[INC6_LVER_ORIG]] = add i32 [[I_018_LVER_ORIG]], 1336; CHECK-NEXT:    [[CMP_LVER_ORIG:%.*]] = icmp ult i32 [[INC6_LVER_ORIG]], [[LIM]]337; CHECK-NEXT:    br i1 [[CMP_LVER_ORIG]], label [[FOR_COND1_PREHEADER_LVER_ORIG]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]]338; CHECK:       for.cond1.preheader.ph:339; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]340; CHECK:       for.cond1.preheader:341; CHECK-NEXT:    [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND_CLEANUP3:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_PH]] ]342; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I_018]], 100000343; CHECK-NEXT:    br label [[FOR_BODY4:%.*]]344; CHECK:       for.cond.cleanup.loopexit.loopexit:345; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]346; CHECK:       for.cond.cleanup.loopexit.loopexit1:347; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]348; CHECK:       for.cond.cleanup.loopexit:349; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]350; CHECK:       for.cond.cleanup:351; CHECK-NEXT:    ret void352; CHECK:       for.cond.cleanup3:353; CHECK-NEXT:    [[INC6]] = add i32 [[I_018]], 1354; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[INC6]], [[FLATTEN_TRIPCOUNT]]355; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT1:%.*]]356; CHECK:       for.body4:357; CHECK-NEXT:    [[J_016:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER]] ]358; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[J_016]], [[MUL]]359; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr @first, align 4360; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP2]], 0361; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]362; CHECK:       if.then:363; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr @a, i32 0, i32 [[I_018]]364; CHECK-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX]], align 1365; CHECK-NEXT:    tail call void asm sideeffect "", "r"(i8 [[TMP3]])366; CHECK-NEXT:    store i32 0, ptr @first, align 4367; CHECK-NEXT:    br label [[IF_END]]368; CHECK:       if.end:369; CHECK-NEXT:    tail call void asm sideeffect "", "r"(i32 [[I_018]])370; CHECK-NEXT:    [[INC:%.*]] = add nuw nsw i32 [[J_016]], 1371; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[J_016]], 99999372; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3]]373;374entry:375  %cmp17.not = icmp eq i32 %lim, 0376  br i1 %cmp17.not, label %for.cond.cleanup, label %for.cond1.preheader.preheader377 378for.cond1.preheader.preheader:379  br label %for.cond1.preheader380 381for.cond1.preheader:382  %i.018 = phi i32 [ %inc6, %for.cond.cleanup3 ], [ 0, %for.cond1.preheader.preheader ]383  %mul = mul i32 %i.018, 100000384  br label %for.body4385 386for.cond.cleanup.loopexit:387  br label %for.cond.cleanup388 389for.cond.cleanup:390  ret void391 392for.cond.cleanup3:393  %inc6 = add i32 %i.018, 1394  %cmp = icmp ult i32 %inc6, %lim395  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit396 397for.body4:398  %j.016 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %if.end ]399  %add = add i32 %j.016, %mul400  %0 = load i32, ptr @first, align 4401  %tobool.not = icmp eq i32 %0, 0402  br i1 %tobool.not, label %if.end, label %if.then403 404if.then:405  %arrayidx = getelementptr inbounds [0 x i8], ptr @a, i32 0, i32 %add406  %1 = load i8, ptr %arrayidx, align 1407  tail call void asm sideeffect "", "r"(i8 %1)408  store i32 0, ptr @first, align 4409  br label %if.end410 411if.end:412  tail call void asm sideeffect "", "r"(i32 %add)413  %inc = add nuw nsw i32 %j.016, 1414  %cmp2 = icmp ult i32 %j.016, 99999415  br i1 %cmp2, label %for.body4, label %for.cond.cleanup3416}417 418declare dso_local void @f(ptr)419