diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp --- a/llvm/lib/Analysis/DemandedBits.cpp +++ b/llvm/lib/Analysis/DemandedBits.cpp @@ -80,7 +80,7 @@ static bool isAlwaysLive(Instruction *I) { return I->isTerminator() || isa(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 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -325,7 +325,7 @@ 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 --- 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 --- a/llvm/test/LTO/X86/parallel.ll +++ b/llvm/test/LTO/X86/parallel.ll @@ -11,7 +11,7 @@ ; 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 @@ ; 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 --- 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 ) ; :1 [#uses=0] diff --git a/llvm/test/Transforms/ADCE/willreturn.ll b/llvm/test/Transforms/ADCE/willreturn.ll --- 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 --- 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 --- a/llvm/test/Transforms/BDCE/dead-void-ro.ll +++ b/llvm/test/Transforms/BDCE/dead-void-ro.ll @@ -14,5 +14,5 @@ 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 --- 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 --- a/llvm/test/tools/gold/X86/parallel.ll +++ b/llvm/test/tools/gold/X86/parallel.ll @@ -14,7 +14,7 @@ ; 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 @@ ; CHECK1-NOT: foo ; CHECK1: T bar ; CHECK1-NOT: foo -define void @bar() { +define void @bar() mustprogress { call void @foo() ret void }