[llvm] 3c5b1f2 - [SimplifyCFG] When eliminating `unreachable` landing pads, mark `call`s as `nounwind`

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 12 13:42:29 PST 2023


Author: Roman Lebedev
Date: 2023-01-13T00:41:58+03:00
New Revision: 3c5b1f2d94d021005ce3769a4402d4a4ae843989

URL: https://github.com/llvm/llvm-project/commit/3c5b1f2d94d021005ce3769a4402d4a4ae843989
DIFF: https://github.com/llvm/llvm-project/commit/3c5b1f2d94d021005ce3769a4402d4a4ae843989.diff

LOG: [SimplifyCFG] When eliminating `unreachable` landing pads, mark `call`s as `nounwind`

We really can't recover that knowledge, and `nounwind` knowledge,
(and not just a lack of the unwind edge, aka `call` instead of `invoke`),
is e.g. part of the reasoning in e.g. `mayHaveSideEffects()`.

Note that this is call-site-specific knowledge,
just because some callsite had an `unreachable`
unwind edge, does not mean that all will.

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/Utils/Local.h
    llvm/lib/Transforms/Utils/Local.cpp
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
    llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
    llvm/test/Transforms/SimplifyCFG/X86/2010-03-30-InvokeCrash.ll
    llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll
    llvm/test/Transforms/SimplifyCFG/X86/empty-cleanuppad.ll
    llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
    llvm/test/Transforms/SimplifyCFG/invoke_unwind.ll
    llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
    llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll
    llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 1ad1e7b948c16..d59c5e0033f5f 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -360,7 +360,12 @@ BasicBlock *changeToInvokeAndSplitBasicBlock(CallInst *CI,
 ///
 /// \param BB  Block whose terminator will be replaced.  Its terminator must
 ///            have an unwind successor.
-void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
+/// \param WouldUnwindBeUB  What is the behaviour should the call actually
+///                         unwind? For example, if the original landing pad
+///                         unconditionally ended with `unreachable`,
+///                         then the unwind would be UB.
+void removeUnwindEdge(BasicBlock *BB, bool WouldUnwindBeUB = false,
+                      DomTreeUpdater *DTU = nullptr);
 
 /// Remove all blocks that can not be reached from the function's entry.
 ///

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d5d0232d7c1e8..569eee3a39d6c 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2557,11 +2557,14 @@ static bool markAliveBlocks(Function &F,
   return Changed;
 }
 
-void llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) {
+void llvm::removeUnwindEdge(BasicBlock *BB, bool WouldUnwindBeUB,
+                            DomTreeUpdater *DTU) {
   Instruction *TI = BB->getTerminator();
 
   if (auto *II = dyn_cast<InvokeInst>(TI)) {
-    changeToCall(II, DTU);
+    CallInst *CI = changeToCall(II, DTU);
+    if (WouldUnwindBeUB && !CI->doesNotThrow())
+      CI->setDoesNotThrow();
     return;
   }
 

diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 870dc2b16a092..1ce412a4f5dca 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -5184,7 +5184,7 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
           DTU->applyUpdates(Updates);
           Updates.clear();
         }
-        removeUnwindEdge(TI->getParent(), DTU);
+        removeUnwindEdge(TI->getParent(), /*WouldUnwindBeUB=*/true, DTU);
         Changed = true;
       }
     } else if (auto *CSI = dyn_cast<CatchSwitchInst>(TI)) {

diff  --git a/llvm/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll b/llvm/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
index d7368efa1eae6..bc5118cb39e83 100644
--- a/llvm/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
@@ -7,7 +7,7 @@ declare void @bar()
 define i32 @foo() personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    call void @bar() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    ret i32 0
 ;
 entry:
@@ -24,3 +24,6 @@ lpad:
 }
 
 declare i32 @__gxx_personality_v0(i32, i64, ptr, ptr)
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index 94d1fa54159d7..7fe32dfc244d7 100644
--- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -20,7 +20,7 @@ F:
 define void @test2() personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @test2()
+; CHECK-NEXT:    call void @test2() #[[ATTR3:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -570,4 +570,5 @@ attributes #0 = { null_pointer_is_valid }
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid }
+; CHECK: attributes #[[ATTR3]] = { nounwind }
 ;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/2010-03-30-InvokeCrash.ll b/llvm/test/Transforms/SimplifyCFG/X86/2010-03-30-InvokeCrash.ll
index dacd2ddc506a9..321df6211f71e 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/2010-03-30-InvokeCrash.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/2010-03-30-InvokeCrash.ll
@@ -9,7 +9,7 @@ declare void @bar(i32)
 define void @foo() personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @bar(i32 undef)
+; CHECK-NEXT:    call void @bar(i32 undef) #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -26,3 +26,6 @@ u:                                                ; preds = %entry
 }
 
 declare i32 @__gxx_personality_v0(...)
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll b/llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll
index da5c976873d72..6cbc1cbf7465c 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll
@@ -9,10 +9,10 @@ target triple = "x86_64-unknown-linux-gnu"
 define void @f(i1 %B) personality i1 undef {
 ; CHECK-LABEL: @f(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    call void @g() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    br label [[CONTINUE:%.*]]
 ; CHECK:       continue:
-; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    call void @g() #[[ATTR0]]
 ; CHECK-NEXT:    br label [[CONTINUE]]
 ;
 entry:
@@ -42,3 +42,6 @@ cleanup2:                                         ; preds = %continue
 }
 
 declare void @g()
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/empty-cleanuppad.ll b/llvm/test/Transforms/SimplifyCFG/X86/empty-cleanuppad.ll
index 7e86b342ede22..e6fdcba655b21 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/empty-cleanuppad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/empty-cleanuppad.ll
@@ -20,7 +20,7 @@ target triple = "x86_64-pc-windows-msvc18.0.0"
 define void @f1() personality ptr @__CxxFrameHandler3 {
 ; CHECK-LABEL: @f1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    call void @g() #[[ATTR1:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -189,7 +189,7 @@ ehcleanup.1:
 define void @f4() personality ptr @__CxxFrameHandler3 {
 ; CHECK-LABEL: @f4(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    call void @g() #[[ATTR1]]
 ; CHECK-NEXT:    invoke void @g()
 ; CHECK-NEXT:    to label [[TRY_CONT:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
 ; CHECK:       catch.dispatch:
@@ -473,7 +473,7 @@ try.cont:
 define void @f10(i32 %V) personality ptr @__CxxFrameHandler3 {
 ; CHECK-LABEL: @f10(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    call void @g() #[[ATTR1]]
 ; CHECK-NEXT:    unreachable
 ;
 entry:
@@ -559,4 +559,5 @@ declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
 ;.
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; CHECK: attributes #[[ATTR1]] = { nounwind }
 ;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
index 767817bf1c5d7..e86425b9f25b0 100644
--- a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
@@ -40,7 +40,7 @@ exit:
 define void @test2() personality ptr @ProcessCLRException {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @f()
+; CHECK-NEXT:    call void @f() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    invoke void @f()
 ; CHECK-NEXT:    to label [[VIA_CATCHSWITCH:%.*]] unwind label [[CLEANUP_INNER:%.*]]
 ; CHECK:       cleanup.inner:
@@ -155,5 +155,5 @@ exit:
   ret void
 }
 ;.
-; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
+; CHECK: attributes #[[ATTR0]] = { nounwind }
 ;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/invoke_unwind.ll b/llvm/test/Transforms/SimplifyCFG/invoke_unwind.ll
index 32ec9b23ad2fe..7f47132f12d5f 100644
--- a/llvm/test/Transforms/SimplifyCFG/invoke_unwind.ll
+++ b/llvm/test/Transforms/SimplifyCFG/invoke_unwind.ll
@@ -7,7 +7,7 @@ declare void @bar()
 ; instructions to call instructions if the handler just rethrows the exception.
 define i32 @test1() personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    call void @bar(), !prof [[PROF0:![0-9]+]]
+; CHECK-NEXT:    call void @bar() #[[ATTR0:[0-9]+]], !prof [[PROF0:![0-9]+]]
 ; CHECK-NEXT:    ret i32 0
 ;
   invoke void @bar( )
@@ -23,7 +23,7 @@ Rethrow:
 
 define i32 @test2() personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    call void @bar() [ "foo"(i32 100) ]
+; CHECK-NEXT:    call void @bar() #[[ATTR0]] [ "foo"(i32 100) ]
 ; CHECK-NEXT:    ret i32 0
 ;
   invoke void @bar( ) [ "foo"(i32 100) ]
@@ -46,10 +46,10 @@ define i64 @test3(i1 %cond) personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BR1:%.*]], label [[BR2:%.*]]
 ; CHECK:       br1:
-; CHECK-NEXT:    [[CALL1:%.*]] = call i64 @dummy1()
+; CHECK-NEXT:    [[CALL1:%.*]] = call i64 @dummy1() #[[ATTR0]]
 ; CHECK-NEXT:    br label [[INVOKE_CONT:%.*]]
 ; CHECK:       br2:
-; CHECK-NEXT:    [[CALL2:%.*]] = call i64 @dummy2()
+; CHECK-NEXT:    [[CALL2:%.*]] = call i64 @dummy2() #[[ATTR0]]
 ; CHECK-NEXT:    br label [[INVOKE_CONT]]
 ; CHECK:       invoke.cont:
 ; CHECK-NEXT:    [[C:%.*]] = phi i64 [ [[CALL1]], [[BR1]] ], [ [[CALL2]], [[BR2]] ]
@@ -88,5 +88,7 @@ lpad2:
 
 declare i32 @__gxx_personality_v0(...)
 ;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.
 ; CHECK: [[PROF0]] = !{!"branch_weights", i32 371}
 ;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
index ff031e95bc042..d9d845a66d7a6 100644
--- a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
+++ b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
@@ -28,10 +28,10 @@ define void @caller(i1 %c) personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:    call void @escape(ptr [[I6]])
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[V0:%.*]], label [[V1:%.*]]
 ; CHECK:       v0:
-; CHECK-NEXT:    call void @throwing_callee_foo()
+; CHECK-NEXT:    call void @throwing_callee_foo() #[[ATTR1:[0-9]+]]
 ; CHECK-NEXT:    unreachable
 ; CHECK:       v1:
-; CHECK-NEXT:    call void @throwing_callee_bar()
+; CHECK-NEXT:    call void @throwing_callee_bar() #[[ATTR1]]
 ; CHECK-NEXT:    unreachable
 ;
 entry:
@@ -82,4 +82,5 @@ end:
 }
 ;.
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; CHECK: attributes #[[ATTR1]] = { nounwind }
 ;.

diff  --git a/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll b/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll
index 0174eb149581c..1bb405b9af020 100644
--- a/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll
@@ -6,7 +6,7 @@ define void @foo() personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 1, ptr nonnull [[A]]) #[[ATTR1:[0-9]+]]
-; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    call void @bar() #[[ATTR1]]
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 1, ptr nonnull [[A]]) #[[ATTR1]]
 ; CHECK-NEXT:    ret void
 ;

diff  --git a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
index 9828db2a69853..0d495f95afe6e 100644
--- a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
+++ b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
@@ -7,7 +7,7 @@ declare void @f()
 define void @test1() personality ptr @Personality {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @f()
+; CHECK-NEXT:    call void @f() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -61,7 +61,7 @@ define void @test3() personality ptr @Personality {
 ; CHECK-NEXT:    to label [[EXIT:%.*]] unwind label [[CLEANUP_PAD:%.*]]
 ; CHECK:       cleanup.pad:
 ; CHECK-NEXT:    [[CLEANUP:%.*]] = cleanuppad within none []
-; CHECK-NEXT:    call void @f()
+; CHECK-NEXT:    call void @f() #[[ATTR0]]
 ; CHECK-NEXT:    unreachable
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
@@ -238,3 +238,6 @@ catch.body2:
 exit:
   ret void
 }
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.


        


More information about the llvm-commits mailing list