diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2018-12-02 14:14:11 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2018-12-02 14:14:11 +0000 |
commit | 687b92cd9cf58e3405b906c7accd13bbdb813793 (patch) | |
tree | 4a0b4b5cc4bb3d9bcd47c005bd2e0ce3873bfbd7 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | b205606d3e52324827d94025df5a8427b3163f0a (diff) | |
download | llvm-687b92cd9cf58e3405b906c7accd13bbdb813793.zip llvm-687b92cd9cf58e3405b906c7accd13bbdb813793.tar.gz llvm-687b92cd9cf58e3405b906c7accd13bbdb813793.tar.bz2 |
[ValueTracking] Support funnel shifts in computeKnownBits()
If the shift amount is known, we can determine the known bits of the
output based on the known bits of two inputs.
This is essentially the same functionality as implemented in D54869,
but for ValueTracking rather than InstCombine SimplifyDemandedBits.
Differential Revision: https://reviews.llvm.org/D55140
llvm-svn: 348091
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index a6ad6bf..6f01960 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1506,6 +1506,27 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known, // of bits which might be set provided by popcnt KnownOne2. break; } + case Intrinsic::fshr: + case Intrinsic::fshl: { + const APInt *SA; + if (!match(I->getOperand(2), m_APInt(SA))) + break; + + // Normalize to funnel shift left. + uint64_t ShiftAmt = SA->urem(BitWidth); + if (II->getIntrinsicID() == Intrinsic::fshr) + ShiftAmt = BitWidth - ShiftAmt; + + KnownBits Known3(Known); + computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q); + computeKnownBits(I->getOperand(1), Known3, Depth + 1, Q); + + Known.Zero = + Known2.Zero.shl(ShiftAmt) | Known3.Zero.lshr(BitWidth - ShiftAmt); + Known.One = + Known2.One.shl(ShiftAmt) | Known3.One.lshr(BitWidth - ShiftAmt); + break; + } case Intrinsic::x86_sse42_crc32_64_64: Known.Zero.setBitsFrom(32); break; |