1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +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:
Nikita Popov 2021-02-18 22:29:19 +01:00
parent c1001d823d
commit 93b123f786
10 changed files with 15 additions and 13 deletions

View File

@ -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(

View File

@ -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))

View File

@ -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(

View File

@ -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
}

View File

@ -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]

View File

@ -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

View File

@ -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 )

View File

@ -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 }

View File

@ -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

View File

@ -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
}