[llvm] e1bae23 - [SCCP] do not clean up dead blocks that have their address taken

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 18 11:02:26 PDT 2022


Author: Nick Desaulniers
Date: 2022-03-18T11:02:15-07:00
New Revision: e1bae23f6f2b35b9cfe249eab68209a00bacf8ee

URL: https://github.com/llvm/llvm-project/commit/e1bae23f6f2b35b9cfe249eab68209a00bacf8ee
DIFF: https://github.com/llvm/llvm-project/commit/e1bae23f6f2b35b9cfe249eab68209a00bacf8ee.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/SCCP.cpp
    llvm/test/Transforms/SCCP/dangling-block-address.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index abc563ab73314..d96a1a257d6a9 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -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)) {

diff  --git a/llvm/test/Transforms/SCCP/dangling-block-address.ll b/llvm/test/Transforms/SCCP/dangling-block-address.ll
index 5163c681b290f..e1e3b771cc37d 100644
--- a/llvm/test/Transforms/SCCP/dangling-block-address.ll
+++ b/llvm/test/Transforms/SCCP/dangling-block-address.ll
@@ -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
+}


        


More information about the llvm-commits mailing list