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