[PATCH] D92364: [MergeICmps] Disable if a GEP does not reference an Argument

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 30 22:11:20 PST 2020


MaskRay updated this revision to Diff 308541.
MaskRay added a comment.

Add log


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D92364

Files:
  llvm/lib/Transforms/Scalar/MergeICmps.cpp
  llvm/test/Transforms/MergeICmps/X86/gep-references-bb.ll


Index: llvm/test/Transforms/MergeICmps/X86/gep-references-bb.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/MergeICmps/X86/gep-references-bb.ll
@@ -0,0 +1,51 @@
+; RUN: opt < %s -S -mergeicmps -verify-dom-info | FileCheck %s
+target triple = "x86_64"
+
+%Triple = type { %Elem0, %Elem1, %Elem2 }
+%Elem0 = type { i32 }
+%Elem1 = type { i32 }
+%Elem2 = type { i32 }
+
+;; %gep does not reference an argument. Disable the optimization because
+;; otherwise the newly created gep may reference undef (after the basic block
+;; defining the pointer operand is deleted).
+;; TODO Optimize with a memcmp.
+; CHECK-LABEL: bb0:
+; CHECK:         load i32, i32* %l0_addr, align 4
+; CHECK:         load i32, i32* %r0_addr, align 4
+; CHECK-LABEL: bb1:
+; CHECK:         load i32, i32* %l1_addr, align 4
+; CHECK:         load i32, i32* %r1_addr, align 4
+; CHECK-LABEL: bb2:
+; CHECK:         load i32, i32* %l2_addr, align 4
+; CHECK:         load i32, i32* %r2_addr, align 4
+define i1 @bug(%Triple* nonnull dereferenceable(12) %lhs, %Triple* nonnull dereferenceable(12) %rhs) {
+bb0:
+  %gep = getelementptr %Triple, %Triple* %rhs, i64 0, i32 0
+  %l0_addr = getelementptr inbounds %Triple, %Triple* %lhs, i64 0, i32 0, i32 0
+  %l0 = load i32, i32* %l0_addr, align 4
+  %r0_addr = getelementptr inbounds %Triple, %Triple* %rhs, i64 0, i32 0, i32 0
+  %r0 = load i32, i32* %r0_addr, align 4
+  %cmp0 = icmp eq i32 %l0, %r0
+  br i1 %cmp0, label %bb1, label %final
+
+bb1:                                           ; preds = %bb0
+  %l1_addr = getelementptr inbounds %Triple, %Triple* %lhs, i64 0, i32 1, i32 0
+  %l1 = load i32, i32* %l1_addr, align 4
+  %r1_addr = getelementptr inbounds %Elem0, %Elem0* %gep, i64 1, i32 0
+  %r1 = load i32, i32* %r1_addr, align 4
+  %cmp1 = icmp eq i32 %l1, %r1
+  br i1 %cmp1, label %bb2, label %final
+
+bb2:                                           ; preds = %bb1
+  %l2_addr = getelementptr inbounds %Triple, %Triple* %lhs, i64 0, i32 2, i32 0
+  %l2 = load i32, i32* %l2_addr, align 4
+  %r2_addr = getelementptr inbounds %Elem0, %Elem0* %gep, i64 2, i32 0
+  %r2 = load i32, i32* %r2_addr, align 4
+  %cmp2 = icmp eq i32 %l2, %r2
+  br label %final
+
+final:                                            ; preds = %bb2, %bb1, %bb0
+  %ret = phi i1 [ false, %bb0 ], [ false, %bb1 ], [ %cmp2, %bb2 ]
+  ret i1 %ret
+}
Index: llvm/lib/Transforms/Scalar/MergeICmps.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/MergeICmps.cpp
+++ llvm/lib/Transforms/Scalar/MergeICmps.cpp
@@ -155,9 +155,13 @@
   }
   Value *const Addr = LoadI->getOperand(0);
   auto *const GEP = dyn_cast<GetElementPtrInst>(Addr);
-  if (!GEP)
+  if (!GEP) {
+    LLVM_DEBUG(dbgs() << "does not reference an argument\n");
     return {};
+  }
   LLVM_DEBUG(dbgs() << "GEP\n");
+  if (!isa<Argument>(GEP->getPointerOperand()))
+    return {};
   if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
     LLVM_DEBUG(dbgs() << "used outside of block\n");
     return {};


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92364.308541.patch
Type: text/x-patch
Size: 3087 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201201/e6542313/attachment.bin>


More information about the llvm-commits mailing list