[llvm] 27e4afc - [DSE] Don't remove nounwind invokes

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 21 11:54:17 PDT 2022


Author: Heejin Ahn
Date: 2022-06-21T11:54:09-07:00
New Revision: 27e4afcea71818ef2ceb0be109321b9595a8fba2

URL: https://github.com/llvm/llvm-project/commit/27e4afcea71818ef2ceb0be109321b9595a8fba2
DIFF: https://github.com/llvm/llvm-project/commit/27e4afcea71818ef2ceb0be109321b9595a8fba2.diff

LOG: [DSE] Don't remove nounwind invokes

For non-mem-intrinsic and non-lifetime `CallBase`s, the current
`isRemovable` function only checks if the `CallBase` 1. has no uses 2.
will return 3. does not throw:
https://github.com/llvm/llvm-project/blob/80fb7823367c1d105fcbc8f21b69205a0d68c859/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp#L1017

But we should also exclude invokes even in case they don't throw,
because they are terminators and thus cannot be removed. While it
doesn't seem to make much sense for `invoke`s to have an `nounwind`
target, this kind of code can be generated and is also valid bitcode.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D128224

Added: 
    llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll

Modified: 
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index fbe11500cd287..df995f329a98a 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1014,7 +1014,8 @@ struct DSEState {
       if (CB->isLifetimeStartOrEnd())
         return false;
 
-      return CB->use_empty() && CB->willReturn() && CB->doesNotThrow();
+      return CB->use_empty() && CB->willReturn() && CB->doesNotThrow() &&
+             !CB->isTerminator();
     }
 
     return false;

diff  --git a/llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll b/llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll
new file mode 100644
index 0000000000000..710cef81bbefe
--- /dev/null
+++ b/llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --prefix-filecheck-ir-name abc
+; RUN: opt -dse -S < %s | FileCheck %s
+
+; Make sure invokes are not removed as dead stores.
+define void @test_nounwind_invoke() personality i8* bitcast (i32 (...)*  @__gxx_personality_v0 to i8*) {
+; CHECK-LABEL: @test_nounwind_invoke(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    invoke void @foo(i32* [[TMP]])
+; CHECK-NEXT:    to label [[BB1:%.*]] unwind label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i32(i64 4, i32* [[TMP]])
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    [[ABCTMP1:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT:    cleanup
+; CHECK-NEXT:    resume { i8*, i32 } [[ABCTMP1]]
+;
+bb:
+  %tmp = alloca i32, align 4
+  ; 'foo' is 'argmemonly', meaning it can only write to memory pointed by %tmp.
+  ; And this def is killed by 'call @llvm.lifetime.end.p0i32' in bb1 without
+  ; being used elsewhere, becoming a dead store. But we shouldn't remove this
+  ; because invokes are terminators and thus cannot be removed.
+  invoke void @foo(i32* %tmp)
+  to label %bb1 unwind label %bb2
+
+bb1:                                              ; preds = %bb
+  call void @llvm.lifetime.end.p0i32(i64 4, i32* %tmp)
+  ret void
+
+bb2:                                              ; preds = %bb
+  %tmp1 = landingpad { i8*, i32 }
+  cleanup
+  resume { i8*, i32 } %tmp1
+}
+
+; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
+declare void @llvm.lifetime.end.p0i32(i64 immarg, i32* nocapture) #0
+; Function Attrs: argmemonly nounwind willreturn
+declare void @foo(i32*) #1
+declare i32 @__gxx_personality_v0(...)
+
+attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn }
+attributes #1 = { argmemonly nounwind willreturn }


        


More information about the llvm-commits mailing list