diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-03-26 20:16:57 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-03-26 20:21:05 +0100 |
commit | fd7df0cf3873a0c9eef6cce4dab05551ff6e0e8d (patch) | |
tree | b5e1353b5841b48a1f06eccccb53f47073259b27 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 9666e89d577887cf574507207484a066588fc9ca (diff) | |
download | llvm-fd7df0cf3873a0c9eef6cce4dab05551ff6e0e8d.zip llvm-fd7df0cf3873a0c9eef6cce4dab05551ff6e0e8d.tar.gz llvm-fd7df0cf3873a0c9eef6cce4dab05551ff6e0e8d.tar.bz2 |
[ValueTracking] Handle shl pair in isKnownNonEqual()
Handle (x << s) != (y << s) where x != y and the shifts are
non-wrapping. Once again, this establishes parity with the
corresponing mul fold that already exists. The shift case is
more powerful because we don't need to guard against multiplies
by zero.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 6f89ba9..39d8f9b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2655,6 +2655,20 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth, Depth + 1, Q); break; } + case Instruction::Shl: { + // Same as multiplies, with the difference that we don't need to check + // for a non-zero multiply. Shifts always multiply by non-zero. + auto *OBO1 = cast<OverflowingBinaryOperator>(O1); + auto *OBO2 = cast<OverflowingBinaryOperator>(O2); + if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) && + (!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap())) + break; + + if (O1->getOperand(1) == O2->getOperand(1)) + 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()) |