[llvm] f5cf7f5 - [DSE] Do not consider 'noop' intrinsics as read-clobbers.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 18 07:51:17 PDT 2020


Author: Florian Hahn
Date: 2020-10-18T15:51:05+01:00
New Revision: f5cf7f544b7abe8488f76945537044f700b5548a

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

LOG: [DSE] Do not consider 'noop' intrinsics as read-clobbers.

isNoopIntrinsic returns true for some intrinsics that are modeled in
MemorySSA but do not actually read or write any memory and do not block
DSE. Such intrinsics should not be considered as read-clobbers.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
    llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 946730e24758..f0eb520f9332 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1519,9 +1519,9 @@ namespace {
 //   3. StartDef completely overwrites CurrentDef.
 // 4. Erase CurrentDef from the function and MemorySSA.
 
-// Returns true if \p M is an intrisnic that does not read or write memory.
-bool isNoopIntrinsic(MemoryUseOrDef *M) {
-  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(M->getMemoryInst())) {
+// Returns true if \p I is an intrisnic that does not read or write memory.
+bool isNoopIntrinsic(Instruction *I) {
+  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
     switch (II->getIntrinsicID()) {
     case Intrinsic::lifetime_start:
     case Intrinsic::lifetime_end:
@@ -1564,7 +1564,7 @@ bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) {
     return true;
 
   // Skip intrinsics that do not really read or modify memory.
-  if (isNoopIntrinsic(D))
+  if (isNoopIntrinsic(D->getMemoryInst()))
     return true;
 
   return false;
@@ -1849,6 +1849,9 @@ struct DSEState {
 
   // Returns true if \p Use may read from \p DefLoc.
   bool isReadClobber(MemoryLocation DefLoc, Instruction *UseInst) {
+    if (isNoopIntrinsic(UseInst))
+      return false;
+
     // Monotonic or weaker atomic stores can be re-ordered and do not need to be
     // treated as read clobber.
     if (auto SI = dyn_cast<StoreInst>(UseInst))
@@ -2132,7 +2135,7 @@ struct DSEState {
         continue;
       }
 
-      if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess))) {
+      if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
         LLVM_DEBUG(dbgs() << "    ... adding uses of intrinsic\n");
         PushMemUses(UseAccess);
         continue;

diff  --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll b/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll
index 5fe212fb3033..37f8e460db35 100644
--- a/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll
@@ -42,8 +42,6 @@ define void @test_strcat_with_lifetime(i8* %src) {
 ; CHECK-NEXT:    [[B:%.*]] = alloca [16 x i8], align 1
 ; CHECK-NEXT:    [[B_CAST:%.*]] = bitcast [16 x i8]* [[B]] to i8*
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull [[B_CAST]])
-; CHECK-NEXT:    [[DEST:%.*]] = getelementptr inbounds [16 x i8], [16 x i8]* [[B]], i64 0, i64 0
-; CHECK-NEXT:    [[CALL:%.*]] = call i8* @strcat(i8* [[DEST]], i8* [[SRC:%.*]])
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull [[B_CAST]])
 ; CHECK-NEXT:    ret void
 ;
@@ -341,7 +339,6 @@ define void @dse_strcpy(i8* nocapture readonly %src) {
 ; CHECK-NEXT:    [[A:%.*]] = alloca [256 x i8], align 16
 ; CHECK-NEXT:    [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @strcpy(i8* nonnull [[BUF]], i8* nonnull dereferenceable(1) [[SRC:%.*]])
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
 ; CHECK-NEXT:    ret void
 ;
@@ -358,7 +355,6 @@ define void @dse_strncpy(i8* nocapture readonly %src) {
 ; CHECK-NEXT:    [[A:%.*]] = alloca [256 x i8], align 16
 ; CHECK-NEXT:    [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull [[BUF]], i8* nonnull dereferenceable(1) [[SRC:%.*]], i64 6)
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
 ; CHECK-NEXT:    ret void
 ;
@@ -375,7 +371,6 @@ define void @dse_strcat(i8* nocapture readonly %src) {
 ; CHECK-NEXT:    [[A:%.*]] = alloca [256 x i8], align 16
 ; CHECK-NEXT:    [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @strcat(i8* nonnull [[BUF]], i8* nonnull dereferenceable(1) [[SRC:%.*]])
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
 ; CHECK-NEXT:    ret void
 ;
@@ -392,7 +387,6 @@ define void @dse_strncat(i8* nocapture readonly %src) {
 ; CHECK-NEXT:    [[A:%.*]] = alloca [256 x i8], align 16
 ; CHECK-NEXT:    [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @strncat(i8* nonnull [[BUF]], i8* nonnull dereferenceable(1) [[SRC:%.*]], i64 6)
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
 ; CHECK-NEXT:    ret void
 ;


        


More information about the llvm-commits mailing list