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 } +@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 } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits