[ValueTracking] computeKnownBitsFromShiftOperator - merge zero/one callbacks to single KnownBits callback. NFCI.

Another cleanup for D90479 - handle the Known Ones/Zeros in a single callback, which will make it much easier to jump over to the KnownBits shift handling.
This commit is contained in:
Simon Pilgrim 2020-11-11 14:15:17 +00:00
parent 3109ce51d4
commit f6a326adef
1 changed files with 35 additions and 45 deletions

View File

@ -979,25 +979,22 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
/// Compute known bits from a shift operator, including those with a
/// non-constant shift amount. Known is the output of this function. Known2 is a
/// pre-allocated temporary with the same bit width as Known and on return
/// contains the known bit of the shift value source. KZF and KOF are
/// operator-specific functions that, given the known-zero or known-one bits
/// respectively, and a shift amount, compute the implied known-zero or
/// known-one bits of the shift operator's result respectively for that shift
/// amount. The results from calling KZF and KOF are conservatively combined for
/// all permitted shift amounts.
/// contains the known bit of the shift value source. KF is an
/// operator-specific function that, given the known-bits and a shift amount,
/// compute the implied known-bits of the shift operator's result respectively
/// for that shift amount. The results from calling KF are conservatively
/// combined for all permitted shift amounts.
static void computeKnownBitsFromShiftOperator(
const Operator *I, const APInt &DemandedElts, KnownBits &Known,
KnownBits &Known2, unsigned Depth, const Query &Q,
function_ref<APInt(const APInt &, unsigned)> KZF,
function_ref<APInt(const APInt &, unsigned)> KOF) {
function_ref<KnownBits(const KnownBits &, unsigned)> KF) {
unsigned BitWidth = Known.getBitWidth();
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Depth + 1, Q);
computeKnownBits(I->getOperand(1), DemandedElts, Known, Depth + 1, Q);
if (Known.isConstant()) {
unsigned ShiftAmt = Known.getConstant().getLimitedValue(BitWidth - 1);
Known.Zero = KZF(Known2.Zero, ShiftAmt);
Known.One = KOF(Known2.One, ShiftAmt);
Known = KF(Known2, ShiftAmt);
// If the known bits conflict, this must be an overflowing left shift, so
// the shift result is poison. We can return anything we want. Choose 0 for
@ -1061,8 +1058,7 @@ static void computeKnownBitsFromShiftOperator(
continue;
}
Known.Zero &= KZF(Known2.Zero, ShiftAmt);
Known.One &= KOF(Known2.One, ShiftAmt);
Known = KnownBits::commonBits(Known, KF(Known2, ShiftAmt));
}
// If the known bits conflict, the result is poison. Return a 0 and hope the
@ -1227,56 +1223,50 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Instruction::Shl: {
// (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
bool NSW = Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(I));
auto KZF = [NSW](const APInt &KnownZero, unsigned ShiftAmt) {
APInt KZResult = KnownZero << ShiftAmt;
KZResult.setLowBits(ShiftAmt); // Low bits known 0.
auto KF = [NSW](const KnownBits &KnownShiftVal, unsigned ShiftAmt) {
KnownBits Result;
Result.Zero = KnownShiftVal.Zero << ShiftAmt;
Result.One = KnownShiftVal.One << ShiftAmt;
// Low bits known zero.
Result.Zero.setLowBits(ShiftAmt);
// If this shift has "nsw" keyword, then the result is either a poison
// value or has the same sign bit as the first operand.
if (NSW && KnownZero.isSignBitSet())
KZResult.setSignBit();
return KZResult;
if (NSW) {
if (KnownShiftVal.Zero.isSignBitSet())
Result.Zero.setSignBit();
if (KnownShiftVal.One.isSignBitSet())
Result.One.setSignBit();
}
return Result;
};
auto KOF = [NSW](const APInt &KnownOne, unsigned ShiftAmt) {
APInt KOResult = KnownOne << ShiftAmt;
if (NSW && KnownOne.isSignBitSet())
KOResult.setSignBit();
return KOResult;
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
KZF, KOF);
KF);
break;
}
case Instruction::LShr: {
// (lshr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
auto KZF = [](const APInt &KnownZero, unsigned ShiftAmt) {
APInt KZResult = KnownZero.lshr(ShiftAmt);
auto KF = [](const KnownBits &KnownShiftVal, unsigned ShiftAmt) {
KnownBits Result;
Result.Zero = KnownShiftVal.Zero.lshr(ShiftAmt);
Result.One = KnownShiftVal.One.lshr(ShiftAmt);
// High bits known zero.
KZResult.setHighBits(ShiftAmt);
return KZResult;
Result.Zero.setHighBits(ShiftAmt);
return Result;
};
auto KOF = [](const APInt &KnownOne, unsigned ShiftAmt) {
return KnownOne.lshr(ShiftAmt);
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
KZF, KOF);
KF);
break;
}
case Instruction::AShr: {
// (ashr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
auto KZF = [](const APInt &KnownZero, unsigned ShiftAmt) {
return KnownZero.ashr(ShiftAmt);
auto KF = [](const KnownBits &KnownShiftVal, unsigned ShiftAmt) {
KnownBits Result;
Result.Zero = KnownShiftVal.Zero.ashr(ShiftAmt);
Result.One = KnownShiftVal.One.ashr(ShiftAmt);
return Result;
};
auto KOF = [](const APInt &KnownOne, unsigned ShiftAmt) {
return KnownOne.ashr(ShiftAmt);
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
KZF, KOF);
KF);
break;
}
case Instruction::Sub: {