mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[DCE] Don't remove non-willreturn calls
In both ADCE and BDCE (via DemandedBits) we should not remove instructions that are not guaranteed to return. This issue was pointed out by fhahn in the recent llvm-dev thread. Differential Revision: https://reviews.llvm.org/D96993
This commit is contained in:
parent
c1001d823d
commit
93b123f786
@ -80,7 +80,7 @@ void DemandedBitsWrapperPass::print(raw_ostream &OS, const Module *M) const {
|
||||
|
||||
static bool isAlwaysLive(Instruction *I) {
|
||||
return I->isTerminator() || isa<DbgInfoIntrinsic>(I) || I->isEHPad() ||
|
||||
I->mayHaveSideEffects();
|
||||
I->mayHaveSideEffects() || !I->willReturn();
|
||||
}
|
||||
|
||||
void DemandedBits::determineLiveOperandBits(
|
||||
|
@ -325,7 +325,7 @@ void AggressiveDeadCodeElimination::initialize() {
|
||||
|
||||
bool AggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) {
|
||||
// TODO -- use llvm::isInstructionTriviallyDead
|
||||
if (I.isEHPad() || I.mayHaveSideEffects()) {
|
||||
if (I.isEHPad() || I.mayHaveSideEffects() || !I.willReturn()) {
|
||||
// Skip any value profile instrumentation calls if they are
|
||||
// instrumenting constants.
|
||||
if (isInstrumentsConstant(I))
|
||||
|
@ -5,8 +5,8 @@
|
||||
; bundles since the presence of unknown operand bundles implies
|
||||
; arbitrary memory effects.
|
||||
|
||||
declare void @readonly_function() readonly nounwind
|
||||
declare void @readnone_function() readnone nounwind
|
||||
declare void @readonly_function() readonly nounwind willreturn
|
||||
declare void @readnone_function() readnone nounwind willreturn
|
||||
|
||||
define void @test0() {
|
||||
; CHECK-LABEL: @test0(
|
||||
|
@ -11,7 +11,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
; CHECK0-NOT: bar
|
||||
; CHECK0: T foo
|
||||
; CHECK0-NOT: bar
|
||||
define void @foo() {
|
||||
define void @foo() mustprogress {
|
||||
call void @bar()
|
||||
ret void
|
||||
}
|
||||
@ -19,7 +19,7 @@ define void @foo() {
|
||||
; CHECK1-NOT: foo
|
||||
; CHECK1: T bar
|
||||
; CHECK1-NOT: foo
|
||||
define void @bar() {
|
||||
define void @bar() mustprogress {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt -adce -S < %s | not grep call
|
||||
|
||||
declare i32 @strlen(i8*) readonly nounwind
|
||||
declare i32 @strlen(i8*) readonly nounwind willreturn
|
||||
|
||||
define void @test() {
|
||||
call i32 @strlen( i8* null ) ; <i32>:1 [#uses=0]
|
||||
|
@ -4,9 +4,10 @@
|
||||
declare void @may_not_return(i32) nounwind readnone
|
||||
declare void @will_return(i32) nounwind readnone willreturn
|
||||
|
||||
; FIXME: This is a miscompile.
|
||||
define void @test(i32 %a) {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: [[B:%.*]] = add i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: call void @may_not_return(i32 [[B]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%b = add i32 %a, 1
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: opt -bdce -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=bdce -S < %s | FileCheck %s
|
||||
|
||||
declare i32 @strlen(i8*) readonly nounwind
|
||||
declare i32 @strlen(i8*) readonly nounwind willreturn
|
||||
|
||||
define void @test1() {
|
||||
call i32 @strlen( i8* null )
|
||||
|
@ -14,5 +14,5 @@ define void @PR34211(i16* %p) {
|
||||
|
||||
declare void @no_side_effects_so_dead(i16) #0
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #0 = { nounwind readnone willreturn }
|
||||
|
||||
|
@ -4,9 +4,10 @@
|
||||
declare void @may_not_return(i32) nounwind readnone
|
||||
declare void @will_return(i32) nounwind readnone willreturn
|
||||
|
||||
; FIXME: This is a miscompile.
|
||||
define void @test(i32 %a) {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: [[B:%.*]] = add i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: call void @may_not_return(i32 [[B]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%b = add i32 %a, 1
|
||||
|
@ -14,7 +14,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
; CHECK0-NOT: bar
|
||||
; CHECK0: T foo
|
||||
; CHECK0-NOT: bar
|
||||
define void @foo() {
|
||||
define void @foo() mustprogress {
|
||||
call void @bar()
|
||||
ret void
|
||||
}
|
||||
@ -24,7 +24,7 @@ define void @foo() {
|
||||
; CHECK1-NOT: foo
|
||||
; CHECK1: T bar
|
||||
; CHECK1-NOT: foo
|
||||
define void @bar() {
|
||||
define void @bar() mustprogress {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user