[llvm-branch-commits] [llvm] 8e9c2ad - [DCE] Don't remove non-willreturn calls

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Feb 19 16:32:37 PST 2021


Author: Nikita Popov
Date: 2021-02-19T16:32:07-08:00
New Revision: 8e9c2ad95eb5ab439b933d8c793957bc4d82e456

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

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

(cherry picked from commit 2f17ed294fcd8cde505b93c9c5bbab06ba59051c)

Added: 
    

Modified: 
    llvm/lib/Analysis/DemandedBits.cpp
    llvm/lib/Transforms/Scalar/ADCE.cpp
    llvm/test/Feature/OperandBundles/adce.ll
    llvm/test/LTO/X86/parallel.ll
    llvm/test/Transforms/ADCE/dce_pure_call.ll
    llvm/test/Transforms/ADCE/willreturn.ll
    llvm/test/Transforms/BDCE/dce-pure.ll
    llvm/test/Transforms/BDCE/dead-void-ro.ll
    llvm/test/Transforms/BDCE/willreturn.ll
    llvm/test/tools/gold/X86/parallel.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp
index 461fd7239905..dd11b0b02bf8 100644
--- a/llvm/lib/Analysis/DemandedBits.cpp
+++ b/llvm/lib/Analysis/DemandedBits.cpp
@@ -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(

diff  --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp
index 2b649732a799..ce4e5e575fbf 100644
--- a/llvm/lib/Transforms/Scalar/ADCE.cpp
+++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
@@ -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))

diff  --git a/llvm/test/Feature/OperandBundles/adce.ll b/llvm/test/Feature/OperandBundles/adce.ll
index a729ba710689..fa4e045fdd1e 100644
--- a/llvm/test/Feature/OperandBundles/adce.ll
+++ b/llvm/test/Feature/OperandBundles/adce.ll
@@ -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(

diff  --git a/llvm/test/LTO/X86/parallel.ll b/llvm/test/LTO/X86/parallel.ll
index b3c128193821..34235ec0202b 100644
--- a/llvm/test/LTO/X86/parallel.ll
+++ b/llvm/test/LTO/X86/parallel.ll
@@ -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
 }

diff  --git a/llvm/test/Transforms/ADCE/dce_pure_call.ll b/llvm/test/Transforms/ADCE/dce_pure_call.ll
index 66483abbc919..88e92bf13f49 100644
--- a/llvm/test/Transforms/ADCE/dce_pure_call.ll
+++ b/llvm/test/Transforms/ADCE/dce_pure_call.ll
@@ -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]

diff  --git a/llvm/test/Transforms/ADCE/willreturn.ll b/llvm/test/Transforms/ADCE/willreturn.ll
index c3482a417cb0..61bbbe0ae5fa 100644
--- a/llvm/test/Transforms/ADCE/willreturn.ll
+++ b/llvm/test/Transforms/ADCE/willreturn.ll
@@ -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

diff  --git a/llvm/test/Transforms/BDCE/dce-pure.ll b/llvm/test/Transforms/BDCE/dce-pure.ll
index a487a04db611..e00121d0c9e9 100644
--- a/llvm/test/Transforms/BDCE/dce-pure.ll
+++ b/llvm/test/Transforms/BDCE/dce-pure.ll
@@ -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 )

diff  --git a/llvm/test/Transforms/BDCE/dead-void-ro.ll b/llvm/test/Transforms/BDCE/dead-void-ro.ll
index 36f09511503b..77f4e097f4bb 100644
--- a/llvm/test/Transforms/BDCE/dead-void-ro.ll
+++ b/llvm/test/Transforms/BDCE/dead-void-ro.ll
@@ -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 }
 

diff  --git a/llvm/test/Transforms/BDCE/willreturn.ll b/llvm/test/Transforms/BDCE/willreturn.ll
index b87ab0050e7a..5efd6ad6e0cf 100644
--- a/llvm/test/Transforms/BDCE/willreturn.ll
+++ b/llvm/test/Transforms/BDCE/willreturn.ll
@@ -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

diff  --git a/llvm/test/tools/gold/X86/parallel.ll b/llvm/test/tools/gold/X86/parallel.ll
index 6972efc652a3..b8072f01e5a2 100644
--- a/llvm/test/tools/gold/X86/parallel.ll
+++ b/llvm/test/tools/gold/X86/parallel.ll
@@ -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
 }


        


More information about the llvm-branch-commits mailing list