forked from OSchip/llvm-project
[SCCP] do not clean up dead blocks that have their address taken
[SCCP] do not clean up dead blocks that have their address taken Fixes a crash observed in IPSCCP. Because the SCCPSolver has already internalized BlockAddresses as Constants or ConstantExprs, we don't want to try to update their Values in the ValueLatticeElement. Instead, continue to propagate these BlockAddress Constants, continue converting BasicBlocks to unreachable, but don't delete the "dead" BasicBlocks which happen to have their address taken. Leave replacing the BlockAddresses to another pass. Fixes: https://github.com/llvm/llvm-project/issues/54238 Fixes: https://github.com/llvm/llvm-project/issues/54251 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D121744
This commit is contained in:
parent
34538dba9b
commit
e1bae23f6f
|
@ -530,7 +530,8 @@ bool llvm::runIPSCCP(
|
|||
MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
|
||||
|
||||
for (BasicBlock *DeadBB : BlocksToErase)
|
||||
DTU.deleteBB(DeadBB);
|
||||
if (!DeadBB->hasAddressTaken())
|
||||
DTU.deleteBB(DeadBB);
|
||||
|
||||
for (BasicBlock &BB : F) {
|
||||
for (Instruction &Inst : llvm::make_early_inc_range(BB)) {
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
; RUN: opt -S -passes=internalize,ipsccp %s | FileCheck %s
|
||||
; PR5569
|
||||
|
||||
; IPSCCP should prove that the blocks are dead and delete them, and
|
||||
; properly handle the dangling blockaddress constants.
|
||||
; If BasicBlocks are unreachable, IPSCCP should convert them to unreachable.
|
||||
; Unless they have their address taken, delete them. If they do have their
|
||||
; address taken, let other passes replace these "dead" blockaddresses with some
|
||||
; other Constant.
|
||||
|
||||
; CHECK: @bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)]
|
||||
|
||||
; CHECK: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
|
||||
|
||||
@code = global [5 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1], align 4 ; <[5 x i32]*> [#uses=0]
|
||||
@bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)] ; <[2 x i8*]*> [#uses=1]
|
||||
|
@ -25,6 +28,10 @@ define void @bar(i32* nocapture %pc) nounwind readonly {
|
|||
; CHECK-LABEL: @bar(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: lab0:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: end:
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
entry:
|
||||
br label %indirectgoto
|
||||
|
@ -53,3 +60,29 @@ define i32 @main() nounwind readnone {
|
|||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; https://github.com/llvm/llvm-project/issues/54238
|
||||
; https://github.com/llvm/llvm-project/issues/54251
|
||||
; https://github.com/llvm/llvm-project/issues/54328
|
||||
define i32 @test1() {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: redirected:
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
%1 = bitcast i8* blockaddress(@test1, %redirected) to i64*
|
||||
call void @set_return_addr(i64* %1)
|
||||
ret i32 0
|
||||
|
||||
redirected:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define internal void @set_return_addr(i64* %addr) {
|
||||
; CHECK-LABEL: @set_return_addr(
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
%addr.addr = alloca i64*, i32 0, align 8
|
||||
store i64* %addr, i64** %addr.addr, align 8
|
||||
ret void
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue