[PATCH] D128224: [DSE] Don't remove nounwind invokes

Heejin Ahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 20 14:03:11 PDT 2022


aheejin created this revision.
aheejin added a reviewer: nikic.
Herald added subscribers: wingo, hiraditya.
Herald added a project: All.
aheejin requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128224

Files:
  llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
  llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll


Index: llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/DeadStoreElimination/nounwind-invoke.ll
@@ -0,0 +1,38 @@
+; RUN: opt -dse -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Make sure invokes are not removed as dead stores.
+; CHECK-LABEL: @test_nounwind_invoke
+define void @test_nounwind_invoke() personality ptr @__gxx_personality_v0 {
+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.p0' 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(ptr %tmp)
+          to label %bb1 unwind label %bb2
+; CHECK: bb:
+; CHECK-NEXT: alloca
+; CHECK-NEXT: invoke
+
+bb1:                                              ; preds = %bb
+  call void @llvm.lifetime.end.p0(i64 4, ptr %tmp)
+  ret void
+
+bb2:                                              ; preds = %bb
+  %tmp1 = landingpad { ptr, i32 }
+          cleanup
+  resume { ptr, i32 } %tmp1
+}
+
+; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0
+; Function Attrs: argmemonly nounwind willreturn
+declare void @foo(ptr) #1
+declare i32 @__gxx_personality_v0(...)
+
+attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn }
+attributes #1 = { argmemonly nounwind willreturn }
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1014,6 +1014,10 @@
       if (CB->isLifetimeStartOrEnd())
         return false;
 
+      // Invokes are terminators, so they cannot be removed
+      if (isa<InvokeInst>(CB))
+        return false;
+
       return CB->use_empty() && CB->willReturn() && CB->doesNotThrow();
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128224.438470.patch
Type: text/x-patch
Size: 2216 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220620/727a9703/attachment.bin>


More information about the llvm-commits mailing list