[PATCH] D113897: [GVNSink] Make GVNSink resistant against self referencing instructions (PR36954)

Dawid Jurczak via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 17 03:54:45 PST 2021


yurai007 updated this revision to Diff 387894.
yurai007 edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113897/new/

https://reviews.llvm.org/D113897

Files:
  llvm/lib/Transforms/Scalar/GVNSink.cpp
  llvm/test/Transforms/GVNSink/sink-common-code.ll


Index: llvm/test/Transforms/GVNSink/sink-common-code.ll
===================================================================
--- llvm/test/Transforms/GVNSink/sink-common-code.ll
+++ llvm/test/Transforms/GVNSink/sink-common-code.ll
@@ -759,6 +759,43 @@
   ret i32 1
 }
 
+ at 0 = global i32 0, align 4
+ at 1 = global i8 0, align 2
+
+; CHECK-LABEL: test_pr36954
+; CHECK-NOT: xor
+; PR36954 reproducer containing self referencing instruction shouldn't crash GVNSink pass.
+define void @test_pr36954() {
+bb1:
+  %i1 = load i32, i32* @0, align 4
+  %i2 = trunc i32 %i1 to i8
+  br label %bb2
+
+bb2:
+  %i3 = phi i32 [ 0, %bb1 ], [ %i10, %bb5 ]
+  %i4 = icmp eq i32 %i3, 0
+  br i1 %i4, label %bb5, label %exit
+
+bb3:
+  br i1 %i4, label %bb5, label %bb4
+
+bb4:
+  %i5 = load i8, i8* @1, align 2
+  %i6 = sub i8 %i2, %i5
+  store i8 %i6, i8* @1, align 2
+  %i7 = zext i8 %i6 to i32
+  %i8 = xor i32 %i8, %i7
+  %i9 = icmp eq i32 %i8, 0
+  br i1 %i9, label %exit, label %bb3
+
+bb5:
+  %i10 = phi i32 [ %i3, %bb2 ], [ %i8, %bb3 ]
+  br label %bb2
+
+exit:
+  ret void
+}
+
 ; CHECK: !0 = !{!1, !1, i64 0}
 ; CHECK: !1 = !{!"float", !2}
 ; CHECK: !2 = !{!"an example type tree"}
Index: llvm/lib/Transforms/Scalar/GVNSink.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/GVNSink.cpp
+++ llvm/lib/Transforms/Scalar/GVNSink.cpp
@@ -349,6 +349,7 @@
   unsigned MemoryUseOrder = -1;
   bool Volatile = false;
   ArrayRef<int> ShuffleMask;
+  bool SelfReferenced = false;
 
 public:
   InstructionUseExpr(Instruction *I, ArrayRecycler<Value *> &R,
@@ -361,11 +362,17 @@
     if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I))
       ShuffleMask = SVI->getShuffleMask().copy(A);
 
-    for (auto &U : I->uses())
+    SelfReferenced = llvm::find_if(I->users(), [I](User *U) {
+                       return U == (User *)I;
+                     }) != I->users().end();
+    for (auto &U : I->uses()) {
       op_push_back(U.getUser());
+    }
     llvm::sort(op_begin(), op_end());
   }
 
+  bool isSelfReferenced() const { return SelfReferenced; }
+
   void setMemoryUseOrder(unsigned MUO) { MemoryUseOrder = MUO; }
   void setVolatile(bool V) { Volatile = V; }
 
@@ -494,6 +501,8 @@
       ValueNumbering[V] = nextValueNumber;
       return nextValueNumber++;
     }
+    if (exp->isSelfReferenced())
+      return ~0U;
 
     uint32_t e = ExpressionNumbering[exp];
     if (!e) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113897.387894.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211117/403c529f/attachment.bin>


More information about the llvm-commits mailing list