brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.3 KiB · f7829c4 Raw
570 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=licm -S | FileCheck %s3; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s4 5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"6target triple = "x86_64-unknown-linux-gnu"7 8; Make sure we don't hoist the store out of the loop; %a would9; have the wrong value if f() unwinds10define void @test1(ptr nocapture noalias %a, i1 zeroext %y) uwtable {11; CHECK-LABEL: @test1(12; CHECK-NEXT:  entry:13; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 414; CHECK-NEXT:    br label [[FOR_BODY:%.*]]15; CHECK:       for.body:16; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]17; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]18; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 119; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 420; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]21; CHECK:       if.then:22; CHECK-NEXT:    tail call void @f()23; CHECK-NEXT:    br label [[FOR_INC]]24; CHECK:       for.inc:25; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 126; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000027; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]28; CHECK:       for.cond.cleanup:29; CHECK-NEXT:    ret void30;31entry:32  br label %for.body33 34for.body:35  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]36  %0 = load i32, ptr %a, align 437  %add = add nsw i32 %0, 138  store i32 %add, ptr %a, align 439  br i1 %y, label %if.then, label %for.inc40 41 42if.then:43  tail call void @f()44  br label %for.inc45 46for.inc:47  %inc = add nuw nsw i32 %i.03, 148  %exitcond = icmp eq i32 %inc, 1000049  br i1 %exitcond, label %for.cond.cleanup, label %for.body50 51for.cond.cleanup:52  ret void53}54 55; We can hoist the store out of the loop here; if f() unwinds,56; the lifetime of %a ends.57define void @test_alloca(i1 zeroext %y) uwtable {58; CHECK-LABEL: @test_alloca(59; CHECK-NEXT:  entry:60; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 461; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 462; CHECK-NEXT:    br label [[FOR_BODY:%.*]]63; CHECK:       for.body:64; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]65; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]66; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 167; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]68; CHECK:       if.then:69; CHECK-NEXT:    tail call void @f()70; CHECK-NEXT:    br label [[FOR_INC]]71; CHECK:       for.inc:72; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 173; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000074; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]75; CHECK:       for.cond.cleanup:76; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]77; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 478; CHECK-NEXT:    ret void79;80entry:81  %a = alloca i3282  br label %for.body83 84for.body:85  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]86  %0 = load i32, ptr %a, align 487  %add = add nsw i32 %0, 188  store i32 %add, ptr %a, align 489  br i1 %y, label %if.then, label %for.inc90 91if.then:92  tail call void @f()93  br label %for.inc94 95for.inc:96  %inc = add nuw nsw i32 %i.03, 197  %exitcond = icmp eq i32 %inc, 1000098  br i1 %exitcond, label %for.cond.cleanup, label %for.body99 100for.cond.cleanup:101  ret void102}103 104; byval memory cannot be accessed on unwind either.105define void @test_byval(ptr byval(i32) %a, i1 zeroext %y) uwtable {106; CHECK-LABEL: @test_byval(107; CHECK-NEXT:  entry:108; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4109; CHECK-NEXT:    br label [[FOR_BODY:%.*]]110; CHECK:       for.body:111; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]112; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]113; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1114; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]115; CHECK:       if.then:116; CHECK-NEXT:    tail call void @f()117; CHECK-NEXT:    br label [[FOR_INC]]118; CHECK:       for.inc:119; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1120; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000121; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]122; CHECK:       for.cond.cleanup:123; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]124; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4125; CHECK-NEXT:    ret void126;127entry:128  br label %for.body129 130for.body:131  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]132  %0 = load i32, ptr %a, align 4133  %add = add nsw i32 %0, 1134  store i32 %add, ptr %a, align 4135  br i1 %y, label %if.then, label %for.inc136 137if.then:138  tail call void @f()139  br label %for.inc140 141for.inc:142  %inc = add nuw nsw i32 %i.03, 1143  %exitcond = icmp eq i32 %inc, 10000144  br i1 %exitcond, label %for.cond.cleanup, label %for.body145 146for.cond.cleanup:147  ret void148}149 150define void @test_dead_on_unwind(ptr noalias dead_on_unwind %a, i1 zeroext %y) uwtable {151; CHECK-LABEL: @test_dead_on_unwind(152; CHECK-NEXT:  entry:153; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4154; CHECK-NEXT:    br label [[FOR_BODY:%.*]]155; CHECK:       for.body:156; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]157; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]158; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1159; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]160; CHECK:       if.then:161; CHECK-NEXT:    tail call void @f()162; CHECK-NEXT:    br label [[FOR_INC]]163; CHECK:       for.inc:164; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1165; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000166; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]167; CHECK:       for.cond.cleanup:168; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]169; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4170; CHECK-NEXT:    ret void171;172entry:173  br label %for.body174 175for.body:176  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]177  %0 = load i32, ptr %a, align 4178  %add = add nsw i32 %0, 1179  store i32 %add, ptr %a, align 4180  br i1 %y, label %if.then, label %for.inc181 182if.then:183  tail call void @f()184  br label %for.inc185 186for.inc:187  %inc = add nuw nsw i32 %i.03, 1188  %exitcond = icmp eq i32 %inc, 10000189  br i1 %exitcond, label %for.cond.cleanup, label %for.body190 191for.cond.cleanup:192  ret void193}194 195;; We can promote if the load can be proven safe to speculate, and the196;; store safe to sink, even if the the store *isn't* must execute.197define void @test3(i1 zeroext %y) uwtable {198; CHECK-LABEL: @test3(199; CHECK-NEXT:  entry:200; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4201; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4202; CHECK-NEXT:    br label [[FOR_BODY:%.*]]203; CHECK:       for.body:204; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]205; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]206; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1207; CHECK-NEXT:    tail call void @f()208; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1209; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000210; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]211; CHECK:       for.cond.cleanup:212; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]213; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4214; CHECK-NEXT:    ret void215;216entry:217  %a = alloca i32218  br label %for.body219 220for.body:221  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]222  %0 = load i32, ptr %a, align 4223  %add = add nsw i32 %0, 1224  tail call void @f()225  store i32 %add, ptr %a, align 4226  %inc = add nuw nsw i32 %i.03, 1227  %exitcond = icmp eq i32 %inc, 10000228  br i1 %exitcond, label %for.cond.cleanup, label %for.body229 230for.cond.cleanup:231  ret void232}233 234;; Same as test3, but with unordered atomics235define void @test3b(i1 zeroext %y) uwtable {236; CHECK-LABEL: @test3b(237; CHECK-NEXT:  entry:238; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4239; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load atomic i32, ptr [[A]] unordered, align 4240; CHECK-NEXT:    br label [[FOR_BODY:%.*]]241; CHECK:       for.body:242; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]243; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]244; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1245; CHECK-NEXT:    tail call void @f()246; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1247; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000248; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]249; CHECK:       for.cond.cleanup:250; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]251; CHECK-NEXT:    store atomic i32 [[ADD_LCSSA]], ptr [[A]] unordered, align 4252; CHECK-NEXT:    ret void253;254entry:255  %a = alloca i32256  br label %for.body257 258for.body:259  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]260  %0 = load atomic i32, ptr %a unordered, align 4261  %add = add nsw i32 %0, 1262  tail call void @f()263  store atomic i32 %add, ptr %a unordered, align 4264  %inc = add nuw nsw i32 %i.03, 1265  %exitcond = icmp eq i32 %inc, 10000266  br i1 %exitcond, label %for.cond.cleanup, label %for.body267 268for.cond.cleanup:269  ret void270}271 272@_ZTIi = external constant ptr273 274; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop.275; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as276; expected277define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 {278; CHECK-LABEL: @loop_within_tryblock(279; CHECK-NEXT:  entry:280; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4281; CHECK-NEXT:    store i32 0, ptr [[A]], align 4282; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4283; CHECK-NEXT:    br label [[FOR_COND:%.*]]284; CHECK:       for.cond:285; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]286; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]287; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024288; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]289; CHECK:       for.body:290; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1291; CHECK-NEXT:    invoke void @boo()292; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]293; CHECK:       invoke.cont:294; CHECK-NEXT:    br label [[FOR_INC]]295; CHECK:       for.inc:296; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_0]], 1297; CHECK-NEXT:    br label [[FOR_COND]]298; CHECK:       lpad:299; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]300; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }301; CHECK-NEXT:    catch ptr @_ZTIi302; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4303; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0304; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1305; CHECK-NEXT:    br label [[CATCH_DISPATCH:%.*]]306; CHECK:       catch.dispatch:307; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)308; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]309; CHECK-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]310; CHECK:       catch:311; CHECK-NEXT:    [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])312; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4313; CHECK-NEXT:    call void @__cxa_end_catch()314; CHECK-NEXT:    br label [[TRY_CONT:%.*]]315; CHECK:       try.cont:316; CHECK-NEXT:    ret void317; CHECK:       for.end:318; CHECK-NEXT:    [[ADD1_LCSSA:%.*]] = phi i32 [ [[ADD1]], [[FOR_COND]] ]319; CHECK-NEXT:    store i32 [[ADD1_LCSSA]], ptr [[A]], align 4320; CHECK-NEXT:    br label [[TRY_CONT]]321; CHECK:       eh.resume:322; CHECK-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } undef, ptr [[TMP1]], 0323; CHECK-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[TMP2]], 1324; CHECK-NEXT:    resume { ptr, i32 } [[LPAD_VAL3]]325;326entry:327  %a = alloca i32, align 4328  store i32 0, ptr %a, align 4329  br label %for.cond330 331for.cond:332  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]333  %cmp = icmp slt i32 %i.0, 1024334  br i1 %cmp, label %for.body, label %for.end335 336for.body:337  %0 = load i32, ptr %a, align 4338  %add = add nsw i32 %0, 1339  store i32 %add, ptr %a, align 4340  invoke void @boo()341  to label %invoke.cont unwind label %lpad342 343invoke.cont:344  br label %for.inc345 346for.inc:347  %inc = add nsw i32 %i.0, 1348  br label %for.cond349 350lpad:351  %1 = landingpad { ptr, i32 }352  catch ptr @_ZTIi353  %2 = extractvalue { ptr, i32 } %1, 0354  %3 = extractvalue { ptr, i32 } %1, 1355  br label %catch.dispatch356 357catch.dispatch:358  %4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #3359  %matches = icmp eq i32 %3, %4360  br i1 %matches, label %catch, label %eh.resume361 362catch:363  %5 = call ptr @__cxa_begin_catch(ptr %2) #3364  %6 = load i32, ptr %5, align 4365  call void @__cxa_end_catch() #3366  br label %try.cont367 368try.cont:369  ret void370 371for.end:372  br label %try.cont373 374eh.resume:375  %lpad.val = insertvalue { ptr, i32 } undef, ptr %2, 0376  %lpad.val3 = insertvalue { ptr, i32 } %lpad.val, i32 %3, 1377  resume { ptr, i32 } %lpad.val3378}379 380 381; The malloc'ed memory is not capture and therefore promoted.382define void @malloc_no_capture() #0 personality ptr @__gxx_personality_v0 {383; CHECK-LABEL: @malloc_no_capture(384; CHECK-NEXT:  entry:385; CHECK-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 4)386; CHECK-NEXT:    [[CALL_PROMOTED:%.*]] = load i32, ptr [[CALL]], align 4387; CHECK-NEXT:    br label [[FOR_BODY:%.*]]388; CHECK:       for.body:389; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[CALL_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ]390; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ]391; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1392; CHECK-NEXT:    br label [[FOR_CALL:%.*]]393; CHECK:       for.call:394; CHECK-NEXT:    invoke void @boo()395; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]396; CHECK:       invoke.cont:397; CHECK-NEXT:    br label [[FOR_LATCH]]398; CHECK:       for.latch:399; CHECK-NEXT:    [[INC]] = add i32 [[I_0]], 1400; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024401; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]402; CHECK:       for.end:403; CHECK-NEXT:    [[ADD_LCSSA2:%.*]] = phi i32 [ [[ADD]], [[FOR_LATCH]] ]404; CHECK-NEXT:    store i32 [[ADD_LCSSA2]], ptr [[CALL]], align 4405; CHECK-NEXT:    br label [[FUN_RET:%.*]]406; CHECK:       lpad:407; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_CALL]] ]408; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }409; CHECK-NEXT:    catch ptr null410; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[CALL]], align 4411; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0412; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1413; CHECK-NEXT:    br label [[CATCH:%.*]]414; CHECK:       catch:415; CHECK-NEXT:    [[TMP3:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])416; CHECK-NEXT:    call void @free(ptr [[CALL]])417; CHECK-NEXT:    call void @__cxa_end_catch()418; CHECK-NEXT:    br label [[FUN_RET]]419; CHECK:       fun.ret:420; CHECK-NEXT:    ret void421;422entry:423  %call = call ptr @malloc(i64 4)424  br label %for.body425 426for.body:427  %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]428  %0 = load i32, ptr %call, align 4429  %add = add nsw i32 %0, 1430  store i32 %add, ptr %call, align 4431  br label %for.call432 433for.call:434  invoke void @boo()435  to label %invoke.cont unwind label %lpad436 437invoke.cont:438  br label %for.latch439 440for.latch:441  %inc = add i32 %i.0, 1442  %cmp = icmp slt i32 %i.0, 1024443  br i1 %cmp, label %for.body, label %for.end444 445for.end:446  br label %fun.ret447 448lpad:449  %1 = landingpad { ptr, i32 }450  catch ptr null451  %2 = extractvalue { ptr, i32 } %1, 0452  %3 = extractvalue { ptr, i32 } %1, 1453  br label %catch454 455catch:456  %4 = call ptr @__cxa_begin_catch(ptr %2) #4457  call void @free(ptr %call)458  call void @__cxa_end_catch()459  br label %fun.ret460 461fun.ret:462  ret void463}464 465; The malloc'ed memory can be captured and therefore only loads can be promoted.466define void @malloc_capture(ptr noalias %A) personality ptr @__gxx_personality_v0 {467; CHECK-LABEL: @malloc_capture(468; CHECK-NEXT:  entry:469; CHECK-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 4)470; CHECK-NEXT:    [[CALL_PROMOTED:%.*]] = load i32, ptr [[CALL]], align 4471; CHECK-NEXT:    br label [[FOR_BODY:%.*]]472; CHECK:       for.body:473; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[CALL_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ]474; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ]475; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1476; CHECK-NEXT:    store i32 [[ADD]], ptr [[CALL]], align 4477; CHECK-NEXT:    br label [[FOR_CALL:%.*]]478; CHECK:       for.call:479; CHECK-NEXT:    invoke void @boo_readnone()480; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]481; CHECK:       invoke.cont:482; CHECK-NEXT:    br label [[FOR_LATCH]]483; CHECK:       for.latch:484; CHECK-NEXT:    store ptr [[CALL]], ptr [[A:%.*]], align 8485; CHECK-NEXT:    [[INC]] = add i32 [[I_0]], 1486; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024487; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]488; CHECK:       for.end:489; CHECK-NEXT:    br label [[FUN_RET:%.*]]490; CHECK:       lpad:491; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }492; CHECK-NEXT:    catch ptr null493; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0494; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1495; CHECK-NEXT:    br label [[CATCH:%.*]]496; CHECK:       catch:497; CHECK-NEXT:    [[TMP3:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])498; CHECK-NEXT:    call void @free(ptr [[CALL]])499; CHECK-NEXT:    call void @__cxa_end_catch()500; CHECK-NEXT:    br label [[FUN_RET]]501; CHECK:       fun.ret:502; CHECK-NEXT:    ret void503;504entry:505  %call = call ptr @malloc(i64 4)506  br label %for.body507 508for.body:509  %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]510  %0 = load i32, ptr %call, align 4511  %add = add nsw i32 %0, 1512  store i32 %add, ptr %call, align 4513  br label %for.call514 515for.call:516  invoke void @boo_readnone()517  to label %invoke.cont unwind label %lpad518 519invoke.cont:520  br label %for.latch521 522for.latch:523  store ptr %call, ptr %A524  %inc = add i32 %i.0, 1525  %cmp = icmp slt i32 %i.0, 1024526  br i1 %cmp, label %for.body, label %for.end527 528for.end:529  br label %fun.ret530 531lpad:532  %1 = landingpad { ptr, i32 }533  catch ptr null534  %2 = extractvalue { ptr, i32 } %1, 0535  %3 = extractvalue { ptr, i32 } %1, 1536  br label %catch537 538catch:539  %4 = call ptr @__cxa_begin_catch(ptr %2) #4540  call void @free(ptr %call)541  call void @__cxa_end_catch()542  br label %fun.ret543 544fun.ret:545  ret void546}547 548; Function Attrs: nounwind549declare noalias ptr @malloc(i64)550 551; Function Attrs: nounwind552declare void @free(ptr nocapture)553 554declare void @boo()555 556; This is an artifical example, readnone functions by definition cannot unwind557; exceptions by calling the C++ exception throwing methods558; This function should only be used to test malloc_capture.559declare void @boo_readnone() readnone560 561declare i32 @__gxx_personality_v0(...)562 563declare ptr @__cxa_begin_catch(ptr)564 565declare void @__cxa_end_catch()566 567declare i32 @llvm.eh.typeid.for.p0(ptr)568 569declare void @f() uwtable570