Files
clang-p2996/llvm/test/Transforms/SCCP/dangling-block-address.ll
Nick Desaulniers e1bae23f6f [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
2022-03-18 11:02:15 -07:00

89 lines
2.8 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=internalize,ipsccp %s | FileCheck %s
; PR5569
; 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)]
@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]
define void @foo(i32 %x) nounwind readnone {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: unreachable
;
entry:
%b = alloca i32, align 4 ; <i32*> [#uses=1]
store volatile i32 -1, i32* %b
ret void
}
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
lab0: ; preds = %indirectgoto
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
br label %indirectgoto
end: ; preds = %indirectgoto
ret void
indirectgoto: ; preds = %lab0, %entry
%indvar = phi i32 [ %indvar.next, %lab0 ], [ 0, %entry ] ; <i32> [#uses=2]
%pc.addr.0 = getelementptr i32, i32* %pc, i32 %indvar ; <i32*> [#uses=1]
%tmp1.pn = load i32, i32* %pc.addr.0 ; <i32> [#uses=1]
%indirect.goto.dest.in = getelementptr inbounds [2 x i8*], [2 x i8*]* @bar.l, i32 0, i32 %tmp1.pn ; <i8**> [#uses=1]
%indirect.goto.dest = load i8*, i8** %indirect.goto.dest.in ; <i8*> [#uses=1]
indirectbr i8* %indirect.goto.dest, [label %lab0, label %end]
}
define i32 @main() nounwind readnone {
; CHECK-LABEL: @main(
; CHECK-NEXT: entry:
; CHECK-NEXT: unreachable
;
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
}