[llvm] dcd2157 - [ValueTracking] Fix isKnownNonEqual() with constexpr mul

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 28 09:39:28 PST 2020


Author: Nikita Popov
Date: 2020-12-28T18:32:57+01:00
New Revision: dcd21572f971ae5b5f1bf1f1abefafa0085404e1

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

LOG: [ValueTracking] Fix isKnownNonEqual() with constexpr mul

Confusingly, BinaryOperator is not an Operator,
OverflowingBinaryOperator is... We were implicitly assuming that
the multiply is an Instruction here.

This fixes the assertion failure reported in
https://reviews.llvm.org/D92726#2472827.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 25f6be2b10dd..0e32e7f4b102 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2529,14 +2529,14 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
         return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
                                Depth + 1, Q);
       break;
-    case Instruction::Mul:
+    case Instruction::Mul: {
       // invertible if A * B == (A * B) mod 2^N where A, and B are integers
       // and N is the bitwdith.  The nsw case is non-obvious, but proven by
       // alive2: https://alive2.llvm.org/ce/z/Z6D5qK
-      if ((!cast<BinaryOperator>(O1)->hasNoUnsignedWrap() ||
-           !cast<BinaryOperator>(O2)->hasNoUnsignedWrap()) &&
-          (!cast<BinaryOperator>(O1)->hasNoSignedWrap() ||
-           !cast<BinaryOperator>(O2)->hasNoSignedWrap()))
+      auto *OBO1 = cast<OverflowingBinaryOperator>(O1);
+      auto *OBO2 = cast<OverflowingBinaryOperator>(O2);
+      if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) &&
+          (!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap()))
         break;
 
       // Assume operand order has been canonicalized
@@ -2546,6 +2546,7 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
         return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
                                Depth + 1, Q);
       break;
+    }
     case Instruction::SExt:
     case Instruction::ZExt:
       if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())

diff  --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
index 8bc9a86c9a93..197088a85e81 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -201,5 +201,17 @@ define i1 @mul5(i8 %B, i8 %C) {
   ret i1 %cmp
 }
 
+ at g = external global i16, align 1
+
+define i1 @mul_constantexpr(i16 %a) {
+; CHECK-LABEL: @mul_constantexpr(
+; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i16 [[A:%.*]], 3
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 mul nsw (i16 ptrtoint (i16* @g to i16), i16 -1), [[MUL]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = mul nsw i16 %a, 3
+  %cmp = icmp eq i16 mul nsw (i16 ptrtoint (i16* @g to i16), i16 -1), %mul
+  ret i1 %cmp
+}
 
 !0 = !{ i8 1, i8 5 }


        


More information about the llvm-commits mailing list