[SimplifyCFG] Don't split musttail call from ret
Summary: When inserting an `unreachable` after a noreturn call, we must ensure that it's not a musttail call to avoid breaking the IR invariants for musttail calls. Reviewers: fedor.sergeev, majnemer Reviewed By: majnemer Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60080 llvm-svn: 357485
This commit is contained in:
parent
6a27c48be2
commit
fb4d9f7287
@ -2054,7 +2054,7 @@ static bool markAliveBlocks(Function &F,
|
||||
Changed = true;
|
||||
break;
|
||||
}
|
||||
if (CI->doesNotReturn()) {
|
||||
if (CI->doesNotReturn() && !CI->isMustTailCall()) {
|
||||
// If we found a call to a no-return function, insert an unreachable
|
||||
// instruction after it. Make sure there isn't *already* one there
|
||||
// though.
|
||||
|
||||
@ -1,11 +1,29 @@
|
||||
; RUN: opt < %s -simplifycfg -S | grep unreachable
|
||||
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
||||
; PR1796
|
||||
|
||||
declare void @Finisher(i32) noreturn
|
||||
|
||||
define void @YYY(i32) {
|
||||
; Make sure we optimize a sequence of two calls (second unreachable);
|
||||
define void @double_call(i32) {
|
||||
; CHECK-LABEL: @double_call(
|
||||
; CHECK-NEXT: tail call void @Finisher(i32 %0) #0
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
tail call void @Finisher(i32 %0) noreturn
|
||||
tail call void @Finisher(i32 %0) noreturn
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we DON'T try to optimize a musttail call (the IR invariant
|
||||
; is that it must be followed by [optional bitcast then] ret).
|
||||
define void @must_tail(i32) {
|
||||
; CHECK-LABEL: @must_tail(
|
||||
; CHECK-NEXT: musttail call void @Finisher(i32 %0) #0
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
musttail call void @Finisher(i32 %0) #0
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: attributes #0 = { noreturn }
|
||||
attributes #0 = { noreturn }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user