[PATCH] D159402: [ValueTracking] Consider assumptions in isKnownNonEqual

Marc Auberer via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 2 05:14:44 PDT 2023


marcauberer created this revision.
marcauberer added reviewers: foad, goldstein.w.n, jmolloy, jdoerfert, spatel, reames.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
marcauberer requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Consider icmp ne and icmp eq assumption intrinsic calls when checking
for known non-equality.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159402

Files:
  llvm/include/llvm/Analysis/ValueTracking.h
  llvm/lib/Analysis/ValueTracking.cpp


Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -3117,6 +3117,50 @@
   return true;
 }
 
+bool llvm::getKnownNonEqualFromAssume(const Value *V1, const Value *V2,
+                                      const SimplifyQuery &Q) {
+  // Use of assumptions is context-sensitive. If we don't have a context, we
+  // cannot use them!
+  if (!Q.AC || !Q.CxtI)
+    return false;
+
+  // Note that the patterns below need to be kept in sync with the code
+  // in AssumptionCache::updateAffectedValues.
+
+  for (auto &AssumeVH : Q.AC->assumptionsFor(V1)) {
+    if (!AssumeVH)
+      continue;
+
+    CallInst *I = cast<CallInst>(AssumeVH);
+    assert(I->getParent()->getParent() == Q.CxtI->getParent()->getParent() &&
+           "Got assumption for the wrong function!");
+
+    // Warning: This loop can end up being somewhat performance sensitive.
+    // We're running this loop for once for each value queried resulting in a
+    // runtime of ~O(#assumes * #values).
+
+    assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
+           "must be an assume intrinsic");
+
+    Value *Arg = I->getArgOperand(0);
+    ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
+    if (!Cmp || !isValidAssumeForContext(I, Q.CxtI, Q.DT))
+      continue;
+    if (!Cmp->isEquality())
+      continue;
+
+    // If we have a matching assumption:
+    // - EQ: return false
+    // - NE: return true
+    Value *Op0 = Cmp->getOperand(0);
+    Value *Op1 = Cmp->getOperand(1);
+    if ((Op0 == V1 && Op1 == V2) || (Op0 == V2 && Op1 == V1))
+      return Cmp->getPredicate() == CmpInst::ICMP_NE;
+  }
+
+  return false;
+}
+
 /// Return true if it is known that V1 != V2.
 static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
                             const SimplifyQuery &Q) {
@@ -3166,7 +3210,9 @@
         Known2.Zero.intersects(Known1.One))
       return true;
   }
-  return false;
+
+  // Check whether a nearby assume intrinsic can determine non-equality.
+  return getKnownNonEqualFromAssume(V1, V2, Q);
 }
 
 /// Return true if 'V & Mask' is known to be zero.  We use this predicate to
Index: llvm/include/llvm/Analysis/ValueTracking.h
===================================================================
--- llvm/include/llvm/Analysis/ValueTracking.h
+++ llvm/include/llvm/Analysis/ValueTracking.h
@@ -168,6 +168,10 @@
                      const DominatorTree *DT = nullptr,
                      bool UseInstrInfo = true);
 
+/// Check if an assume intrinsic covers the non-equality information
+bool getKnownNonEqualFromAssume(const Value *V1, const Value *V2,
+                                const SimplifyQuery &Q);
+
 /// Return true if the given values are known to be non-equal when defined.
 /// Supports scalar integer types only.
 bool isKnownNonEqual(const Value *V1, const Value *V2, const DataLayout &DL,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159402.555586.patch
Type: text/x-patch
Size: 2999 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230902/1e290313/attachment.bin>


More information about the llvm-commits mailing list