[PATCH] D92726: Teach isKnownNonEqual how to recurse through invertable multiplies

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 5 17:18:36 PST 2020


reames created this revision.
reames added reviewers: spatel, nikic, fhahn, craig.topper.
Herald added subscribers: dantrushin, bollu, hiraditya, mcrosier.
reames requested review of this revision.
Herald added a project: LLVM.

Build on the work started in 8f07629 <https://reviews.llvm.org/rG8f076291be41467560ebf73738561225d2b67206>, and add the multiply case.  In the process, more clearly describe the requirement for the operation we're looking through.

Reviewers, please confirm my reasoning is correct.  I always get confused by modulo arithmetic.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92726

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/test/Analysis/ValueTracking/known-non-equal.ll


Index: llvm/test/Analysis/ValueTracking/known-non-equal.ll
===================================================================
--- llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -130,4 +130,35 @@
   ret i1 %cmp
 }
 
+; %C is unknown and op could wrap mapping two values to the same
+; output value.
+define i1 @mul1(i8 %B, i8 %C) {
+; CHECK-LABEL: @mul1(
+; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
+; CHECK-NEXT:    [[A_OP:%.*]] = mul i8 [[C:%.*]], [[A]]
+; CHECK-NEXT:    [[B_OP:%.*]] = mul i8 [[C]], [[B]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP]], [[B_OP]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %A = add i8 %B, 1
+  %A.op = mul i8 %C, %A
+  %B.op = mul i8 %C, %B
+
+  %cmp = icmp eq i8 %A.op, %B.op
+  ret i1 %cmp
+}
+
+define i1 @mul2(i8 %B, i8 %C) {
+; CHECK-LABEL: @mul2(
+; CHECK-NEXT:    ret i1 false
+;
+  %A = add i8 %B, 1
+  %A.op = mul nuw i8 %C, %A
+  %B.op = mul nuw i8 %C, %B
+
+  %cmp = icmp eq i8 %A.op, %B.op
+  ret i1 %cmp
+}
+
+
 !0 = !{ i8 1, i8 5 }
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -2502,6 +2502,7 @@
   return isKnownNonZero(Op, Depth + 1, Q);
 }
 
+
 /// Return true if it is known that V1 != V2.
 static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
                             const Query &Q) {
@@ -2514,7 +2515,9 @@
   if (Depth >= MaxAnalysisRecursionDepth)
     return false;
 
-  // See if we can recurse through (exactly one of) our operands.
+  // See if we can recurse through (exactly one of) our operands.  This
+  // requires our operation be 1-to-1 and map every input value to exactly
+  // one output value.  Such an operation is invertable.
   auto *O1 = dyn_cast<Operator>(V1);
   auto *O2 = dyn_cast<Operator>(V2);
   if (O1 && O2 && O1->getOpcode() == O2->getOpcode()) {
@@ -2522,6 +2525,21 @@
     default: break;
     case Instruction::Add:
     case Instruction::Sub:
+      // Assume operand order has been canonicalized
+      if (O1->getOperand(0) == O2->getOperand(0))
+        return isKnownNonEqual(O1->getOperand(1), O2->getOperand(1),
+                               Depth + 1, Q);
+      if (O1->getOperand(1) == O2->getOperand(1))
+        return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
+                               Depth + 1, Q);
+      break;
+    case Instruction::Mul:
+      // invertable if A * B == (A * B) mod 2^N where A, and B are integers
+      // and N is the bitwdith.
+      if (!cast<BinaryOperator>(O1)->hasNoUnsignedWrap() ||
+          !cast<BinaryOperator>(O2)->hasNoUnsignedWrap())
+        break;
+
       // Assume operand order has been canonicalized
       if (O1->getOperand(0) == O2->getOperand(0))
         return isKnownNonEqual(O1->getOperand(1), O2->getOperand(1),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92726.309757.patch
Type: text/x-patch
Size: 2938 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201206/1614d716/attachment.bin>


More information about the llvm-commits mailing list