Loading llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +4 −17 Original line number Diff line number Diff line Loading @@ -2330,21 +2330,13 @@ static bool isAllocSiteRemovable(Instruction *AI, return false; LLVM_FALLTHROUGH; } case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::objectsize: Users.emplace_back(I); continue; case Intrinsic::invariant_start: // Only delete this if it has no uses or a single 'end' use. if (I->use_empty()) Users.emplace_back(I); else if (I->hasOneUse() && match(I->user_back(), m_Intrinsic<Intrinsic::invariant_end>())) Users.emplace_back(I); continue; } } Loading Loading @@ -2392,13 +2384,14 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { if (isAllocSiteRemovable(&MI, Users, &TLI)) { for (unsigned i = 0, e = Users.size(); i != e; ++i) { // Lowering all @llvm.objectsize calls first because they may // use a bitcast/GEP of the alloca we are removing. if (!Users[i]) continue; Instruction *I = cast<Instruction>(&*Users[i]); if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { // Lowering all @llvm.objectsize calls first because they may // use a bitcast/GEP of the alloca we are removing. if (II->getIntrinsicID() == Intrinsic::objectsize) { Value *Result = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/true); Loading @@ -2406,12 +2399,6 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { eraseInstFromFunction(*I); Users[i] = nullptr; // Skip examining in the next loop. } // Erase llvm.invariant.end because we expect that it uses an // llvm.invariant.start that we will remove below. if (II->getIntrinsicID() == Intrinsic::invariant_end) { eraseInstFromFunction(*I); Users[i] = nullptr; // Skip examining in the next loop. } } } for (unsigned i = 0, e = Users.size(); i != e; ++i) { Loading llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll +0 −35 Original line number Diff line number Diff line Loading @@ -28,41 +28,6 @@ define i32 @foo() #0 { ret i32 %conv } ; This used to crash while erasing instructions: ; https://bugs.llvm.org/show_bug.cgi?id=43723 define void @PR43723() { ; CHECK-LABEL: @PR43723( ; CHECK-NEXT: ret void ; %tab = alloca [10 x i8], align 16 %t0 = bitcast [10 x i8]* %tab to i8* call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) ret void uselistorder i8* %t0, { 1, 0, 2 } } define void @unknown_use_of_invariant_start({}** %p) { ; CHECK-LABEL: @unknown_use_of_invariant_start( ; CHECK-NEXT: [[T1:%.*]] = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 undef) ; CHECK-NEXT: store {}* [[T1]], {}** [[P:%.*]], align 8 ; CHECK-NEXT: ret void ; %tab = alloca [10 x i8], align 16 %t0 = bitcast [10 x i8]* %tab to i8* call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) store {}* %t1, {}** %p ret void } declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #2 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #0 declare {}* @llvm.invariant.start.p0i8(i64 immarg, i8* nocapture) #0 declare void @llvm.invariant.end.p0i8({}*, i64 immarg, i8* nocapture) #0 Loading
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +4 −17 Original line number Diff line number Diff line Loading @@ -2330,21 +2330,13 @@ static bool isAllocSiteRemovable(Instruction *AI, return false; LLVM_FALLTHROUGH; } case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::objectsize: Users.emplace_back(I); continue; case Intrinsic::invariant_start: // Only delete this if it has no uses or a single 'end' use. if (I->use_empty()) Users.emplace_back(I); else if (I->hasOneUse() && match(I->user_back(), m_Intrinsic<Intrinsic::invariant_end>())) Users.emplace_back(I); continue; } } Loading Loading @@ -2392,13 +2384,14 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { if (isAllocSiteRemovable(&MI, Users, &TLI)) { for (unsigned i = 0, e = Users.size(); i != e; ++i) { // Lowering all @llvm.objectsize calls first because they may // use a bitcast/GEP of the alloca we are removing. if (!Users[i]) continue; Instruction *I = cast<Instruction>(&*Users[i]); if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { // Lowering all @llvm.objectsize calls first because they may // use a bitcast/GEP of the alloca we are removing. if (II->getIntrinsicID() == Intrinsic::objectsize) { Value *Result = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/true); Loading @@ -2406,12 +2399,6 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { eraseInstFromFunction(*I); Users[i] = nullptr; // Skip examining in the next loop. } // Erase llvm.invariant.end because we expect that it uses an // llvm.invariant.start that we will remove below. if (II->getIntrinsicID() == Intrinsic::invariant_end) { eraseInstFromFunction(*I); Users[i] = nullptr; // Skip examining in the next loop. } } } for (unsigned i = 0, e = Users.size(); i != e; ++i) { Loading
llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll +0 −35 Original line number Diff line number Diff line Loading @@ -28,41 +28,6 @@ define i32 @foo() #0 { ret i32 %conv } ; This used to crash while erasing instructions: ; https://bugs.llvm.org/show_bug.cgi?id=43723 define void @PR43723() { ; CHECK-LABEL: @PR43723( ; CHECK-NEXT: ret void ; %tab = alloca [10 x i8], align 16 %t0 = bitcast [10 x i8]* %tab to i8* call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) ret void uselistorder i8* %t0, { 1, 0, 2 } } define void @unknown_use_of_invariant_start({}** %p) { ; CHECK-LABEL: @unknown_use_of_invariant_start( ; CHECK-NEXT: [[T1:%.*]] = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 undef) ; CHECK-NEXT: store {}* [[T1]], {}** [[P:%.*]], align 8 ; CHECK-NEXT: ret void ; %tab = alloca [10 x i8], align 16 %t0 = bitcast [10 x i8]* %tab to i8* call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) store {}* %t1, {}** %p ret void } declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #2 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #0 declare {}* @llvm.invariant.start.p0i8(i64 immarg, i8* nocapture) #0 declare void @llvm.invariant.end.p0i8({}*, i64 immarg, i8* nocapture) #0