Skip to content

Commit e1bae23

Browse files
[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: llvm/llvm-project#54238 Fixes: llvm/llvm-project#54251 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D121744
1 parent 34538db commit e1bae23

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

llvm/lib/Transforms/Scalar/SCCP.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ bool llvm::runIPSCCP(
530530
MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
531531

532532
for (BasicBlock *DeadBB : BlocksToErase)
533-
DTU.deleteBB(DeadBB);
533+
if (!DeadBB->hasAddressTaken())
534+
DTU.deleteBB(DeadBB);
534535

535536
for (BasicBlock &BB : F) {
536537
for (Instruction &Inst : llvm::make_early_inc_range(BB)) {

llvm/test/Transforms/SCCP/dangling-block-address.ll

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
; RUN: opt -S -passes=internalize,ipsccp %s | FileCheck %s
33
; PR5569
44

5-
; IPSCCP should prove that the blocks are dead and delete them, and
6-
; properly handle the dangling blockaddress constants.
5+
; If BasicBlocks are unreachable, IPSCCP should convert them to unreachable.
6+
; Unless they have their address taken, delete them. If they do have their
7+
; address taken, let other passes replace these "dead" blockaddresses with some
8+
; other Constant.
9+
10+
; CHECK: @bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)]
711

8-
; CHECK: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
912

1013
@code = global [5 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1], align 4 ; <[5 x i32]*> [#uses=0]
1114
@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 {
2528
; CHECK-LABEL: @bar(
2629
; CHECK-NEXT: entry:
2730
; CHECK-NEXT: unreachable
31+
; CHECK: lab0:
32+
; CHECK-NEXT: unreachable
33+
; CHECK: end:
34+
; CHECK-NEXT: unreachable
2835
;
2936
entry:
3037
br label %indirectgoto
@@ -53,3 +60,29 @@ define i32 @main() nounwind readnone {
5360
entry:
5461
ret i32 0
5562
}
63+
64+
; https://github.com/llvm/llvm-project/issues/54238
65+
; https://github.com/llvm/llvm-project/issues/54251
66+
; https://github.com/llvm/llvm-project/issues/54328
67+
define i32 @test1() {
68+
; CHECK-LABEL: @test1(
69+
; CHECK-NEXT: unreachable
70+
; CHECK: redirected:
71+
; CHECK-NEXT: unreachable
72+
;
73+
%1 = bitcast i8* blockaddress(@test1, %redirected) to i64*
74+
call void @set_return_addr(i64* %1)
75+
ret i32 0
76+
77+
redirected:
78+
ret i32 0
79+
}
80+
81+
define internal void @set_return_addr(i64* %addr) {
82+
; CHECK-LABEL: @set_return_addr(
83+
; CHECK-NEXT: unreachable
84+
;
85+
%addr.addr = alloca i64*, i32 0, align 8
86+
store i64* %addr, i64** %addr.addr, align 8
87+
ret void
88+
}

0 commit comments

Comments
 (0)