diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index bb4220d6164..1171149180b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/ValueTracking.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -1004,9 +1005,18 @@ static void computeKnownBitsFromShiftOperator(Operator *I, // calculation. Reusing the APInts here to prevent unnecessary allocations. KnownZero.clearAllBits(), KnownOne.clearAllBits(); + // If we know the shifter operand is nonzero, we can sometimes infer more + // known bits. However this is expensive to compute, so be lazy about it and + // only compute it when absolutely necessary. + Optional<bool> ShifterOperandIsNonZero; + // Early exit if we can't constrain any well-defined shift amount. - if (!(ShiftAmtKZ & (BitWidth-1)) && !(ShiftAmtKO & (BitWidth-1))) - return; + if (!(ShiftAmtKZ & (BitWidth - 1)) && !(ShiftAmtKO & (BitWidth - 1))) { + ShifterOperandIsNonZero = + isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q); + if (!*ShifterOperandIsNonZero) + return; + } computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, DL, Depth + 1, Q); @@ -1018,6 +1028,16 @@ static void computeKnownBitsFromShiftOperator(Operator *I, continue; if ((ShiftAmt | ShiftAmtKO) != ShiftAmt) continue; + // If we know the shifter is nonzero, we may be able to infer more known + // bits. This check is sunk down as far as possible to avoid the expensive + // call to isKnownNonZero if the cheaper checks above fail. + if (ShiftAmt == 0) { + if (!ShifterOperandIsNonZero.hasValue()) + ShifterOperandIsNonZero = + isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q); + if (*ShifterOperandIsNonZero) + continue; + } KnownZero &= KZF(KnownZero2, ShiftAmt); KnownOne &= KOF(KnownOne2, ShiftAmt); |