brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.4 KiB · 9acb391 Raw
1026 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; REQUIRES: asserts3; RUN: opt -S -passes=licm -ipt-expensive-asserts=true < %s | FileCheck %s4 5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"6 7declare void @f() nounwind8declare void @llvm.experimental.guard(i1,...)9 10; constant fold on first ieration11define i32 @test1(ptr noalias nocapture readonly %a) nounwind uwtable {12; CHECK-LABEL: define i32 @test1(13; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1:[0-9]+]] {14; CHECK-NEXT:  entry:15; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 416; CHECK-NEXT:    br label [[FOR_BODY:%.*]]17; CHECK:       for.body:18; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]19; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]20; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], 200021; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL:%.*]]22; CHECK:       continue:23; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]24; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 125; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 100026; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]27; CHECK:       for.cond.cleanup:28; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]29; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]30; CHECK:       fail:31; CHECK-NEXT:    call void @f()32; CHECK-NEXT:    ret i32 -133;34entry:35  br label %for.body36 37for.body:38  %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]39  %acc = phi i32 [ 0, %entry ], [ %add, %continue ]40  %r.chk = icmp ult i32 %iv, 200041  br i1 %r.chk, label %continue, label %fail42continue:43  %i1 = load i32, ptr %a, align 444  %add = add nsw i32 %i1, %acc45  %inc = add nuw nsw i32 %iv, 146  %exitcond = icmp eq i32 %inc, 100047  br i1 %exitcond, label %for.cond.cleanup, label %for.body48 49for.cond.cleanup:50  ret i32 %add51 52fail:53  call void @f()54  ret i32 -155}56 57; Same as test1, but with a floating point IR and fcmp58define i32 @test_fcmp(ptr noalias nocapture readonly %a) nounwind uwtable {59; CHECK-LABEL: define i32 @test_fcmp(60; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {61; CHECK-NEXT:  entry:62; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 463; CHECK-NEXT:    br label [[FOR_BODY:%.*]]64; CHECK:       for.body:65; CHECK-NEXT:    [[IV:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]66; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]67; CHECK-NEXT:    [[R_CHK:%.*]] = fcmp olt float [[IV]], 2.000000e+0368; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL:%.*]]69; CHECK:       continue:70; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]71; CHECK-NEXT:    [[INC]] = fadd float [[IV]], 1.000000e+0072; CHECK-NEXT:    [[EXITCOND:%.*]] = fcmp ogt float [[INC]], 1.000000e+0373; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]74; CHECK:       for.cond.cleanup:75; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]76; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]77; CHECK:       fail:78; CHECK-NEXT:    call void @f()79; CHECK-NEXT:    ret i32 -180;81entry:82  br label %for.body83 84for.body:85  %iv = phi float [ 0.0, %entry ], [ %inc, %continue ]86  %acc = phi i32 [ 0, %entry ], [ %add, %continue ]87  %r.chk = fcmp olt float %iv, 2000.088  br i1 %r.chk, label %continue, label %fail89continue:90  %i1 = load i32, ptr %a, align 491  %add = add nsw i32 %i1, %acc92  %inc = fadd float %iv, 1.093  %exitcond = fcmp ogt float %inc, 1000.094  br i1 %exitcond, label %for.cond.cleanup, label %for.body95 96for.cond.cleanup:97  ret i32 %add98 99fail:100  call void @f()101  ret i32 -1102}103 104; Count down from a.length w/entry guard105; TODO: currently unable to prove the following:106; ule i32 (add nsw i32 %len, -1), %len where len is [0, 512]107define i32 @test2(ptr noalias nocapture readonly %a) nounwind uwtable {108; CHECK-LABEL: define i32 @test2(109; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {110; CHECK-NEXT:  entry:111; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0:![0-9]+]]112; CHECK-NEXT:    [[IS_NON_POS:%.*]] = icmp eq i32 [[LEN]], 0113; CHECK-NEXT:    br i1 [[IS_NON_POS]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]114; CHECK:       preheader:115; CHECK-NEXT:    [[LENMINUSONE:%.*]] = add nsw i32 [[LEN]], -1116; CHECK-NEXT:    br label [[FOR_BODY:%.*]]117; CHECK:       for.body:118; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LENMINUSONE]], [[PREHEADER]] ], [ [[DEC:%.*]], [[CONTINUE:%.*]] ]119; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]120; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ule i32 [[IV]], [[LEN]]121; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]122; CHECK:       continue:123; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4124; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]125; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1126; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[DEC]], 0127; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]128; CHECK:       for.cond.cleanup:129; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]130; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]131; CHECK:       fail.loopexit:132; CHECK-NEXT:    br label [[FAIL]]133; CHECK:       fail:134; CHECK-NEXT:    call void @f()135; CHECK-NEXT:    ret i32 -1136;137entry:138  %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}139  %is.non.pos = icmp eq i32 %len, 0140  br i1 %is.non.pos, label %fail, label %preheader141preheader:142  %lenminusone = add nsw i32 %len, -1143  br label %for.body144for.body:145  %iv = phi i32 [ %lenminusone, %preheader ], [ %dec, %continue ]146  %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]147  %r.chk = icmp ule i32 %iv, %len148  br i1 %r.chk, label %continue, label %fail149continue:150  %i1 = load i32, ptr %a, align 4151  %add = add nsw i32 %i1, %acc152  %dec = add nsw i32 %iv, -1153  %exitcond = icmp eq i32 %dec, 0154  br i1 %exitcond, label %for.cond.cleanup, label %for.body155 156for.cond.cleanup:157  ret i32 %add158 159fail:160  call void @f()161  ret i32 -1162}163 164; trivially true for zero165define i32 @test3(ptr noalias nocapture readonly %a) nounwind uwtable {166; CHECK-LABEL: define i32 @test3(167; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {168; CHECK-NEXT:  entry:169; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]170; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0171; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]172; CHECK:       preheader:173; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4174; CHECK-NEXT:    br label [[FOR_BODY:%.*]]175; CHECK:       for.body:176; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]177; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]178; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ule i32 [[IV]], [[LEN]]179; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]180; CHECK:       continue:181; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]182; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1183; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000184; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]185; CHECK:       for.cond.cleanup:186; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]187; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]188; CHECK:       fail.loopexit:189; CHECK-NEXT:    br label [[FAIL]]190; CHECK:       fail:191; CHECK-NEXT:    call void @f()192; CHECK-NEXT:    ret i32 -1193;194entry:195  %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}196  %is.zero = icmp eq i32 %len, 0197  br i1 %is.zero, label %fail, label %preheader198preheader:199  br label %for.body200for.body:201  %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]202  %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]203  %r.chk = icmp ule i32 %iv, %len204  br i1 %r.chk, label %continue, label %fail205continue:206  %i1 = load i32, ptr %a, align 4207  %add = add nsw i32 %i1, %acc208  %inc = add nuw nsw i32 %iv, 1209  %exitcond = icmp eq i32 %inc, 1000210  br i1 %exitcond, label %for.cond.cleanup, label %for.body211 212for.cond.cleanup:213  ret i32 %add214 215fail:216  call void @f()217  ret i32 -1218}219 220; Same as previous case, with commuted icmp.221define i32 @test3_commuted(ptr noalias nocapture readonly %a) nounwind uwtable {222; CHECK-LABEL: define i32 @test3_commuted(223; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {224; CHECK-NEXT:  entry:225; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]226; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0227; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]228; CHECK:       preheader:229; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4230; CHECK-NEXT:    br label [[FOR_BODY:%.*]]231; CHECK:       for.body:232; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]233; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]234; CHECK-NEXT:    [[R_CHK:%.*]] = icmp uge i32 [[LEN]], [[IV]]235; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]236; CHECK:       continue:237; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]238; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1239; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000240; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]241; CHECK:       for.cond.cleanup:242; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]243; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]244; CHECK:       fail.loopexit:245; CHECK-NEXT:    br label [[FAIL]]246; CHECK:       fail:247; CHECK-NEXT:    call void @f()248; CHECK-NEXT:    ret i32 -1249;250entry:251  %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}252  %is.zero = icmp eq i32 %len, 0253  br i1 %is.zero, label %fail, label %preheader254preheader:255  br label %for.body256for.body:257  %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]258  %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]259  %r.chk = icmp uge i32 %len, %iv260  br i1 %r.chk, label %continue, label %fail261continue:262  %i1 = load i32, ptr %a, align 4263  %add = add nsw i32 %i1, %acc264  %inc = add nuw nsw i32 %iv, 1265  %exitcond = icmp eq i32 %inc, 1000266  br i1 %exitcond, label %for.cond.cleanup, label %for.body267 268for.cond.cleanup:269  ret i32 %add270 271fail:272  call void @f()273  ret i32 -1274}275 276; requires fact length is non-zero277define i32 @test4(ptr noalias nocapture readonly %a) nounwind uwtable {278; CHECK-LABEL: define i32 @test4(279; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {280; CHECK-NEXT:  entry:281; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]282; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0283; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]284; CHECK:       preheader:285; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4286; CHECK-NEXT:    br label [[FOR_BODY:%.*]]287; CHECK:       for.body:288; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]289; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]290; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], [[LEN]]291; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]292; CHECK:       continue:293; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]294; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1295; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000296; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]297; CHECK:       for.cond.cleanup:298; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]299; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]300; CHECK:       fail.loopexit:301; CHECK-NEXT:    br label [[FAIL]]302; CHECK:       fail:303; CHECK-NEXT:    call void @f()304; CHECK-NEXT:    ret i32 -1305;306entry:307  %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}308  %is.zero = icmp eq i32 %len, 0309  br i1 %is.zero, label %fail, label %preheader310preheader:311  br label %for.body312for.body:313  %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]314  %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]315  %r.chk = icmp ult i32 %iv, %len316  br i1 %r.chk, label %continue, label %fail317continue:318  %i1 = load i32, ptr %a, align 4319  %add = add nsw i32 %i1, %acc320  %inc = add nuw nsw i32 %iv, 1321  %exitcond = icmp eq i32 %inc, 1000322  br i1 %exitcond, label %for.cond.cleanup, label %for.body323 324for.cond.cleanup:325  ret i32 %add326 327fail:328  call void @f()329  ret i32 -1330}331 332; variation on test1 with branch swapped333define i32 @test-brswap(ptr noalias nocapture readonly %a) nounwind uwtable {334; CHECK-LABEL: define i32 @test-brswap(335; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {336; CHECK-NEXT:  entry:337; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4338; CHECK-NEXT:    br label [[FOR_BODY:%.*]]339; CHECK:       for.body:340; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]341; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]342; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[IV]], 2000343; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]344; CHECK:       continue:345; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]346; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1347; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000348; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]349; CHECK:       for.cond.cleanup:350; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]351; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]352; CHECK:       fail:353; CHECK-NEXT:    call void @f()354; CHECK-NEXT:    ret i32 -1355;356entry:357  br label %for.body358 359for.body:360  %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]361  %acc = phi i32 [ 0, %entry ], [ %add, %continue ]362  %r.chk = icmp ugt i32 %iv, 2000363  br i1 %r.chk, label %fail, label %continue364continue:365  %i1 = load i32, ptr %a, align 4366  %add = add nsw i32 %i1, %acc367  %inc = add nuw nsw i32 %iv, 1368  %exitcond = icmp eq i32 %inc, 1000369  br i1 %exitcond, label %for.cond.cleanup, label %for.body370 371for.cond.cleanup:372  ret i32 %add373 374fail:375  call void @f()376  ret i32 -1377}378 379define i32 @test-nonphi(ptr noalias nocapture readonly %a) nounwind uwtable {380; CHECK-LABEL: define i32 @test-nonphi(381; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {382; CHECK-NEXT:  entry:383; CHECK-NEXT:    br label [[FOR_BODY:%.*]]384; CHECK:       for.body:385; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]386; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]387; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[IV]], 72388; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[XOR]], 2000389; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]390; CHECK:       continue:391; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4392; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]393; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1394; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000395; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]396; CHECK:       for.cond.cleanup:397; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]398; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]399; CHECK:       fail:400; CHECK-NEXT:    call void @f()401; CHECK-NEXT:    ret i32 -1402;403entry:404  br label %for.body405 406for.body:407  %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]408  %acc = phi i32 [ 0, %entry ], [ %add, %continue ]409  %xor = xor i32 %iv, 72410  %r.chk = icmp ugt i32 %xor, 2000411  br i1 %r.chk, label %fail, label %continue412continue:413  %i1 = load i32, ptr %a, align 4414  %add = add nsw i32 %i1, %acc415  %inc = add nuw nsw i32 %iv, 1416  %exitcond = icmp eq i32 %inc, 1000417  br i1 %exitcond, label %for.cond.cleanup, label %for.body418 419for.cond.cleanup:420  ret i32 %add421 422fail:423  call void @f()424  ret i32 -1425}426 427define i32 @test-wrongphi(ptr noalias nocapture readonly %a) nounwind uwtable {428; CHECK-LABEL: define i32 @test-wrongphi(429; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {430; CHECK-NEXT:  entry:431; CHECK-NEXT:    br label [[FOR_BODY:%.*]]432; CHECK:       for.body:433; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]434; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]435; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[IV]], 500436; CHECK-NEXT:    br i1 [[COND]], label [[DUMMY_BLOCK1:%.*]], label [[DUMMY_BLOCK2:%.*]]437; CHECK:       dummy_block1:438; CHECK-NEXT:    br label [[DUMMY_BLOCK2]]439; CHECK:       dummy_block2:440; CHECK-NEXT:    [[WRONGPHI:%.*]] = phi i32 [ 11, [[FOR_BODY]] ], [ 12, [[DUMMY_BLOCK1]] ]441; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[WRONGPHI]], 2000442; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]443; CHECK:       continue:444; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4445; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]446; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1447; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000448; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]449; CHECK:       for.cond.cleanup:450; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]451; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]452; CHECK:       fail:453; CHECK-NEXT:    call void @f()454; CHECK-NEXT:    ret i32 -1455;456entry:457  br label %for.body458 459for.body:460  %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]461  %acc = phi i32 [ 0, %entry ], [ %add, %continue ]462  %cond = icmp ult i32 %iv, 500463  br i1 %cond, label %dummy_block1, label %dummy_block2464 465dummy_block1:466  br label %dummy_block2467 468dummy_block2:469  %wrongphi = phi i32 [11, %for.body], [12, %dummy_block1]470  %r.chk = icmp ugt i32 %wrongphi, 2000471  br i1 %r.chk, label %fail, label %continue472continue:473  %i1 = load i32, ptr %a, align 4474  %add = add nsw i32 %i1, %acc475  %inc = add nuw nsw i32 %iv, 1476  %exitcond = icmp eq i32 %inc, 1000477  br i1 %exitcond, label %for.cond.cleanup, label %for.body478 479for.cond.cleanup:480  ret i32 %add481 482fail:483  call void @f()484  ret i32 -1485}486 487; This works because loop-simplify is run implicitly, but test for it anyways488define i32 @test-multiple-latch(ptr noalias nocapture readonly %a) nounwind uwtable {489; CHECK-LABEL: define i32 @test-multiple-latch(490; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]]) #[[ATTR1]] {491; CHECK-NEXT:  entry:492; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4493; CHECK-NEXT:    br label [[FOR_BODY:%.*]]494; CHECK:       for.body:495; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]496; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY_BACKEDGE]] ]497; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], 2000498; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE1:%.*]], label [[FAIL:%.*]]499; CHECK:       continue1:500; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]501; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1502; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], 0503; CHECK-NEXT:    br i1 [[CMP]], label [[CONTINUE2:%.*]], label [[FOR_BODY_BACKEDGE]]504; CHECK:       for.body.backedge:505; CHECK-NEXT:    br label [[FOR_BODY]]506; CHECK:       continue2:507; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000508; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_BACKEDGE]]509; CHECK:       for.cond.cleanup:510; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE2]] ]511; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]512; CHECK:       fail:513; CHECK-NEXT:    call void @f()514; CHECK-NEXT:    ret i32 -1515;516entry:517  br label %for.body518 519for.body:520  %iv = phi i32 [ 0, %entry ], [ %inc, %continue1 ], [ %inc, %continue2 ]521  %acc = phi i32 [ 0, %entry ], [ %add, %continue1 ], [ %add, %continue2 ]522  %r.chk = icmp ult i32 %iv, 2000523  br i1 %r.chk, label %continue1, label %fail524continue1:525  %i1 = load i32, ptr %a, align 4526  %add = add nsw i32 %i1, %acc527  %inc = add nuw nsw i32 %iv, 1528  %cmp = icmp eq i32 %add, 0529  br i1 %cmp, label %continue2, label %for.body530continue2:531  %exitcond = icmp eq i32 %inc, 1000532  br i1 %exitcond, label %for.cond.cleanup, label %for.body533 534for.cond.cleanup:535  ret i32 %add536 537fail:538  call void @f()539  ret i32 -1540}541 542define void @test-hoisting-in-presence-of-guards(i1 %c, ptr %p) {543; CHECK-LABEL: define void @test-hoisting-in-presence-of-guards(544; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) {545; CHECK-NEXT:  entry:546; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 4547; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100548; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]549; CHECK-NEXT:    br label [[LOOP:%.*]]550; CHECK:       loop:551; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]552; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1553; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000554; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]555; CHECK:       exit:556; CHECK-NEXT:    ret void557;558 559entry:560  br label %loop561 562loop:563  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]564  %iv.next = add i32 %iv, 1565  %a = load i32, ptr %p566  %invariant_cond = icmp ne i32 %a, 100567  call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]568  %loop_cond = icmp slt i32 %iv.next, 1000569  br i1 %loop_cond, label %loop, label %exit570 571exit:572  ret void573}574 575 576declare void @may_throw() inaccessiblememonly577 578; Test that we can sink a mustexecute load from loop header even in presence of579; throwing instructions after it.580define void @test_hoist_from_header_01(ptr %p, i32 %n) {581; CHECK-LABEL: define void @test_hoist_from_header_01(582; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {583; CHECK-NEXT:  entry:584; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4585; CHECK-NEXT:    br label [[LOOP:%.*]]586; CHECK:       loop:587; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]588; CHECK-NEXT:    call void @may_throw()589; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]590; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]591; CHECK:       if.true:592; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]593; CHECK-NEXT:    br label [[BACKEDGE]]594; CHECK:       if.false:595; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]596; CHECK-NEXT:    br label [[BACKEDGE]]597; CHECK:       backedge:598; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]599; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]600; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]601; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]602; CHECK:       exit:603; CHECK-NEXT:    ret void604;605 606entry:607  br label %loop608 609loop:610  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]611  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]612  %load = load i32, ptr %p613  call void @may_throw()614  %cond = icmp slt i32 %iv, %n615  br i1 %cond, label %if.true, label %if.false616 617if.true:618  %a = add i32 %iv, %iv619  br label %backedge620 621if.false:622  %b = mul i32 %iv, %iv623  br label %backedge624 625backedge:626  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]627  %iv.next = add i32 %iv, %merge628  %loop.cond = icmp ult i32 %iv.next, %load629  br i1 %loop.cond, label %loop, label %exit630 631exit:632  ret void633}634 635define void @test_hoist_from_header_02(ptr %p, i32 %n) {636; CHECK-LABEL: define void @test_hoist_from_header_02(637; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {638; CHECK-NEXT:  entry:639; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4640; CHECK-NEXT:    br label [[LOOP:%.*]]641; CHECK:       loop:642; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]643; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]644; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]645; CHECK:       if.true:646; CHECK-NEXT:    call void @may_throw()647; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]648; CHECK-NEXT:    br label [[BACKEDGE]]649; CHECK:       if.false:650; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]651; CHECK-NEXT:    br label [[BACKEDGE]]652; CHECK:       backedge:653; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]654; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]655; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]656; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]657; CHECK:       exit:658; CHECK-NEXT:    ret void659;660 661entry:662  br label %loop663 664loop:665  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]666  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]667  %load = load i32, ptr %p668  %cond = icmp slt i32 %iv, %n669  br i1 %cond, label %if.true, label %if.false670 671if.true:672  call void @may_throw()673  %a = add i32 %iv, %iv674  br label %backedge675 676if.false:677  %b = mul i32 %iv, %iv678  br label %backedge679 680backedge:681  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]682  %iv.next = add i32 %iv, %merge683  %loop.cond = icmp ult i32 %iv.next, %load684  br i1 %loop.cond, label %loop, label %exit685 686exit:687  ret void688}689 690define void @test_hoist_from_header_03(ptr %p, i32 %n) {691; CHECK-LABEL: define void @test_hoist_from_header_03(692; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {693; CHECK-NEXT:  entry:694; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4695; CHECK-NEXT:    br label [[LOOP:%.*]]696; CHECK:       loop:697; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]698; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]699; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]700; CHECK:       if.true:701; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]702; CHECK-NEXT:    br label [[BACKEDGE]]703; CHECK:       if.false:704; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]705; CHECK-NEXT:    br label [[BACKEDGE]]706; CHECK:       backedge:707; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]708; CHECK-NEXT:    call void @may_throw()709; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]710; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]711; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]712; CHECK:       exit:713; CHECK-NEXT:    ret void714;715 716entry:717  br label %loop718 719loop:720  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]721  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]722  %load = load i32, ptr %p723  %cond = icmp slt i32 %iv, %n724  br i1 %cond, label %if.true, label %if.false725 726if.true:727  %a = add i32 %iv, %iv728  br label %backedge729 730if.false:731  %b = mul i32 %iv, %iv732  br label %backedge733 734backedge:735  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]736  call void @may_throw()737  %iv.next = add i32 %iv, %merge738  %loop.cond = icmp ult i32 %iv.next, %load739  br i1 %loop.cond, label %loop, label %exit740 741exit:742  ret void743}744 745; Check that a throwing instruction prohibits hoisting across it.746define void @test_hoist_from_header_04(ptr %p, i32 %n) {747; CHECK-LABEL: define void @test_hoist_from_header_04(748; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {749; CHECK-NEXT:  entry:750; CHECK-NEXT:    br label [[LOOP:%.*]]751; CHECK:       loop:752; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]753; CHECK-NEXT:    call void @may_throw()754; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4755; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]756; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]757; CHECK:       if.true:758; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]759; CHECK-NEXT:    br label [[BACKEDGE]]760; CHECK:       if.false:761; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]762; CHECK-NEXT:    br label [[BACKEDGE]]763; CHECK:       backedge:764; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]765; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]766; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]767; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]768; CHECK:       exit:769; CHECK-NEXT:    ret void770;771 772entry:773  br label %loop774 775loop:776  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]777  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]778  call void @may_throw()779  %load = load i32, ptr %p780  %cond = icmp slt i32 %iv, %n781  br i1 %cond, label %if.true, label %if.false782 783if.true:784  %a = add i32 %iv, %iv785  br label %backedge786 787if.false:788  %b = mul i32 %iv, %iv789  br label %backedge790 791backedge:792  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]793  %iv.next = add i32 %iv, %merge794  %loop.cond = icmp ult i32 %iv.next, %load795  br i1 %loop.cond, label %loop, label %exit796 797exit:798  ret void799}800 801; Check that we can hoist a mustexecute load from backedge even if something802; throws after it.803define void @test_hoist_from_backedge_01(ptr %p, i32 %n) {804; CHECK-LABEL: define void @test_hoist_from_backedge_01(805; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {806; CHECK-NEXT:  entry:807; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4808; CHECK-NEXT:    br label [[LOOP:%.*]]809; CHECK:       loop:810; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]811; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]812; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]813; CHECK:       if.true:814; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]815; CHECK-NEXT:    br label [[BACKEDGE]]816; CHECK:       if.false:817; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]818; CHECK-NEXT:    br label [[BACKEDGE]]819; CHECK:       backedge:820; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]821; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]822; CHECK-NEXT:    call void @may_throw()823; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]824; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]825; CHECK:       exit:826; CHECK-NEXT:    ret void827;828 829entry:830  br label %loop831 832loop:833  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]834  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]835  %cond = icmp slt i32 %iv, %n836  br i1 %cond, label %if.true, label %if.false837 838if.true:839  %a = add i32 %iv, %iv840  br label %backedge841 842if.false:843  %b = mul i32 %iv, %iv844  br label %backedge845 846backedge:847  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]848  %iv.next = add i32 %iv, %merge849  %load = load i32, ptr %p850  call void @may_throw()851  %loop.cond = icmp ult i32 %iv.next, %load852  br i1 %loop.cond, label %loop, label %exit853 854exit:855  ret void856}857 858; Check that we don't hoist the load if something before it can throw.859define void @test_hoist_from_backedge_02(ptr %p, i32 %n) {860; CHECK-LABEL: define void @test_hoist_from_backedge_02(861; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {862; CHECK-NEXT:  entry:863; CHECK-NEXT:    br label [[LOOP:%.*]]864; CHECK:       loop:865; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]866; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]867; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]868; CHECK:       if.true:869; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]870; CHECK-NEXT:    br label [[BACKEDGE]]871; CHECK:       if.false:872; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]873; CHECK-NEXT:    br label [[BACKEDGE]]874; CHECK:       backedge:875; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]876; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]877; CHECK-NEXT:    call void @may_throw()878; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4879; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]880; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]881; CHECK:       exit:882; CHECK-NEXT:    ret void883;884 885entry:886  br label %loop887 888loop:889  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]890  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]891  %cond = icmp slt i32 %iv, %n892  br i1 %cond, label %if.true, label %if.false893 894if.true:895  %a = add i32 %iv, %iv896  br label %backedge897 898if.false:899  %b = mul i32 %iv, %iv900  br label %backedge901 902backedge:903  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]904  %iv.next = add i32 %iv, %merge905  call void @may_throw()906  %load = load i32, ptr %p907  %loop.cond = icmp ult i32 %iv.next, %load908  br i1 %loop.cond, label %loop, label %exit909 910exit:911  ret void912}913 914define void @test_hoist_from_backedge_03(ptr %p, i32 %n) {915; CHECK-LABEL: define void @test_hoist_from_backedge_03(916; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {917; CHECK-NEXT:  entry:918; CHECK-NEXT:    br label [[LOOP:%.*]]919; CHECK:       loop:920; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]921; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]922; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]923; CHECK:       if.true:924; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]925; CHECK-NEXT:    br label [[BACKEDGE]]926; CHECK:       if.false:927; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]928; CHECK-NEXT:    call void @may_throw()929; CHECK-NEXT:    br label [[BACKEDGE]]930; CHECK:       backedge:931; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]932; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]933; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4934; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]935; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]936; CHECK:       exit:937; CHECK-NEXT:    ret void938;939 940entry:941  br label %loop942 943loop:944  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]945  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]946  %cond = icmp slt i32 %iv, %n947  br i1 %cond, label %if.true, label %if.false948 949if.true:950  %a = add i32 %iv, %iv951  br label %backedge952 953if.false:954  %b = mul i32 %iv, %iv955  call void @may_throw()956  br label %backedge957 958backedge:959  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]960  %iv.next = add i32 %iv, %merge961  %load = load i32, ptr %p962  %loop.cond = icmp ult i32 %iv.next, %load963  br i1 %loop.cond, label %loop, label %exit964 965exit:966  ret void967}968 969define void @test_hoist_from_backedge_04(ptr %p, i32 %n) {970; CHECK-LABEL: define void @test_hoist_from_backedge_04(971; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {972; CHECK-NEXT:  entry:973; CHECK-NEXT:    br label [[LOOP:%.*]]974; CHECK:       loop:975; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]976; CHECK-NEXT:    call void @may_throw()977; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]978; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]979; CHECK:       if.true:980; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]981; CHECK-NEXT:    br label [[BACKEDGE]]982; CHECK:       if.false:983; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]984; CHECK-NEXT:    br label [[BACKEDGE]]985; CHECK:       backedge:986; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]987; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]988; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4989; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]990; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]991; CHECK:       exit:992; CHECK-NEXT:    ret void993;994 995entry:996  br label %loop997 998loop:999  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]1000  %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]1001  call void @may_throw()1002  %cond = icmp slt i32 %iv, %n1003  br i1 %cond, label %if.true, label %if.false1004 1005if.true:1006  %a = add i32 %iv, %iv1007  br label %backedge1008 1009if.false:1010  %b = mul i32 %iv, %iv1011  br label %backedge1012 1013backedge:1014  %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]1015  %iv.next = add i32 %iv, %merge1016  %load = load i32, ptr %p1017  %loop.cond = icmp ult i32 %iv.next, %load1018  br i1 %loop.cond, label %loop, label %exit1019 1020exit:1021  ret void1022}1023;.1024; CHECK: [[RNG0]] = !{i32 0, i32 512}1025;.1026