mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-09 21:50:50 +00:00
[InstCombine] Move portion of SimplifyDemandedUseBits that deals with instructions with multiple uses out to a separate method. NFCI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300082 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
73ba5e9415
commit
c7bad98e0e
@ -542,6 +542,13 @@ private:
|
|||||||
bool SimplifyDemandedBits(Instruction *I, unsigned Op,
|
bool SimplifyDemandedBits(Instruction *I, unsigned Op,
|
||||||
const APInt &DemandedMask, APInt &KnownZero,
|
const APInt &DemandedMask, APInt &KnownZero,
|
||||||
APInt &KnownOne, unsigned Depth = 0);
|
APInt &KnownOne, unsigned Depth = 0);
|
||||||
|
/// Helper routine of SimplifyDemandedUseBits. It computes KnownZero/KnownOne
|
||||||
|
/// bits. It also tries to handle simplifications that can be done based on
|
||||||
|
/// DemandedMask, but without modifying the Instruction.
|
||||||
|
Value *SimplifyMultipleUseDemandedBits(Instruction *I,
|
||||||
|
const APInt &DemandedMask,
|
||||||
|
APInt &KnownZero, APInt &KnownOne,
|
||||||
|
unsigned Depth, Instruction *CxtI);
|
||||||
/// Helper routine of SimplifyDemandedUseBits. It tries to simplify demanded
|
/// Helper routine of SimplifyDemandedUseBits. It tries to simplify demanded
|
||||||
/// bit for "r1 = shr x, c1; r2 = shl r1, c2" instruction sequence.
|
/// bit for "r1 = shr x, c1; r2 = shl r1, c2" instruction sequence.
|
||||||
Value *SimplifyShrShlDemandedBits(Instruction *Lsr, Instruction *Sftl,
|
Value *SimplifyShrShlDemandedBits(Instruction *Lsr, Instruction *Sftl,
|
||||||
|
@ -142,9 +142,6 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
|||||||
if (Depth == 6) // Limit search depth.
|
if (Depth == 6) // Limit search depth.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
|
|
||||||
APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
|
|
||||||
|
|
||||||
Instruction *I = dyn_cast<Instruction>(V);
|
Instruction *I = dyn_cast<Instruction>(V);
|
||||||
if (!I) {
|
if (!I) {
|
||||||
computeKnownBits(V, KnownZero, KnownOne, Depth, CxtI);
|
computeKnownBits(V, KnownZero, KnownOne, Depth, CxtI);
|
||||||
@ -155,81 +152,13 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
|||||||
// we can't do any simplifications of the operands, because DemandedMask
|
// we can't do any simplifications of the operands, because DemandedMask
|
||||||
// only reflects the bits demanded by *one* of the users.
|
// only reflects the bits demanded by *one* of the users.
|
||||||
if (Depth != 0 && !I->hasOneUse()) {
|
if (Depth != 0 && !I->hasOneUse()) {
|
||||||
// Despite the fact that we can't simplify this instruction in all User's
|
return SimplifyMultipleUseDemandedBits(I, DemandedMask, KnownZero, KnownOne,
|
||||||
// context, we can at least compute the knownzero/knownone bits, and we can
|
Depth, CxtI);
|
||||||
// do simplifications that apply to *just* the one user if we know that
|
|
||||||
// this instruction has a simpler value in that context.
|
|
||||||
if (I->getOpcode() == Instruction::And) {
|
|
||||||
// If either the LHS or the RHS are Zero, the result is zero.
|
|
||||||
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
|
|
||||||
// If all of the demanded bits are known 1 on one side, return the other.
|
|
||||||
// These bits cannot contribute to the result of the 'and' in this
|
|
||||||
// context.
|
|
||||||
if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) ==
|
|
||||||
(DemandedMask & ~LHSKnownZero))
|
|
||||||
return I->getOperand(0);
|
|
||||||
if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) ==
|
|
||||||
(DemandedMask & ~RHSKnownZero))
|
|
||||||
return I->getOperand(1);
|
|
||||||
|
|
||||||
// If all of the demanded bits in the inputs are known zeros, return zero.
|
|
||||||
if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
|
|
||||||
return Constant::getNullValue(VTy);
|
|
||||||
|
|
||||||
} else if (I->getOpcode() == Instruction::Or) {
|
|
||||||
// We can simplify (X|Y) -> X or Y in the user's context if we know that
|
|
||||||
// only bits from X or Y are demanded.
|
|
||||||
|
|
||||||
// If either the LHS or the RHS are One, the result is One.
|
|
||||||
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
|
|
||||||
// If all of the demanded bits are known zero on one side, return the
|
|
||||||
// other. These bits cannot contribute to the result of the 'or' in this
|
|
||||||
// context.
|
|
||||||
if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) ==
|
|
||||||
(DemandedMask & ~LHSKnownOne))
|
|
||||||
return I->getOperand(0);
|
|
||||||
if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) ==
|
|
||||||
(DemandedMask & ~RHSKnownOne))
|
|
||||||
return I->getOperand(1);
|
|
||||||
|
|
||||||
// If all of the potentially set bits on one side are known to be set on
|
|
||||||
// the other side, just use the 'other' side.
|
|
||||||
if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) ==
|
|
||||||
(DemandedMask & (~RHSKnownZero)))
|
|
||||||
return I->getOperand(0);
|
|
||||||
if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) ==
|
|
||||||
(DemandedMask & (~LHSKnownZero)))
|
|
||||||
return I->getOperand(1);
|
|
||||||
} else if (I->getOpcode() == Instruction::Xor) {
|
|
||||||
// We can simplify (X^Y) -> X or Y in the user's context if we know that
|
|
||||||
// only bits from X or Y are demanded.
|
|
||||||
|
|
||||||
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
|
||||||
CxtI);
|
|
||||||
|
|
||||||
// If all of the demanded bits are known zero on one side, return the
|
|
||||||
// other.
|
|
||||||
if ((DemandedMask & RHSKnownZero) == DemandedMask)
|
|
||||||
return I->getOperand(0);
|
|
||||||
if ((DemandedMask & LHSKnownZero) == DemandedMask)
|
|
||||||
return I->getOperand(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the KnownZero/KnownOne bits to simplify things downstream.
|
|
||||||
computeKnownBits(I, KnownZero, KnownOne, Depth, CxtI);
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
|
||||||
|
APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
|
||||||
|
|
||||||
// If this is the root being simplified, allow it to have multiple uses,
|
// If this is the root being simplified, allow it to have multiple uses,
|
||||||
// just set the DemandedMask to all bits so that we can try to simplify the
|
// just set the DemandedMask to all bits so that we can try to simplify the
|
||||||
// operands. This allows visitTruncInst (for example) to simplify the
|
// operands. This allows visitTruncInst (for example) to simplify the
|
||||||
@ -818,6 +747,97 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper routine of SimplifyDemandedUseBits. It computes KnownZero/KnownOne
|
||||||
|
/// bits. It also tries to handle simplifications that can be done based on
|
||||||
|
/// DemandedMask, but without modifying the Instruction.
|
||||||
|
Value *InstCombiner::SimplifyMultipleUseDemandedBits(Instruction *I,
|
||||||
|
const APInt &DemandedMask,
|
||||||
|
APInt &KnownZero,
|
||||||
|
APInt &KnownOne,
|
||||||
|
unsigned Depth,
|
||||||
|
Instruction *CxtI) {
|
||||||
|
unsigned BitWidth = DemandedMask.getBitWidth();
|
||||||
|
Type *ITy = I->getType();
|
||||||
|
|
||||||
|
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
|
||||||
|
APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
|
||||||
|
|
||||||
|
// Despite the fact that we can't simplify this instruction in all User's
|
||||||
|
// context, we can at least compute the knownzero/knownone bits, and we can
|
||||||
|
// do simplifications that apply to *just* the one user if we know that
|
||||||
|
// this instruction has a simpler value in that context.
|
||||||
|
if (I->getOpcode() == Instruction::And) {
|
||||||
|
// If either the LHS or the RHS are Zero, the result is zero.
|
||||||
|
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
|
||||||
|
// If all of the demanded bits are known 1 on one side, return the other.
|
||||||
|
// These bits cannot contribute to the result of the 'and' in this
|
||||||
|
// context.
|
||||||
|
if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) ==
|
||||||
|
(DemandedMask & ~LHSKnownZero))
|
||||||
|
return I->getOperand(0);
|
||||||
|
if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) ==
|
||||||
|
(DemandedMask & ~RHSKnownZero))
|
||||||
|
return I->getOperand(1);
|
||||||
|
|
||||||
|
// If all of the demanded bits in the inputs are known zeros, return zero.
|
||||||
|
if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
|
||||||
|
return Constant::getNullValue(ITy);
|
||||||
|
|
||||||
|
} else if (I->getOpcode() == Instruction::Or) {
|
||||||
|
// We can simplify (X|Y) -> X or Y in the user's context if we know that
|
||||||
|
// only bits from X or Y are demanded.
|
||||||
|
|
||||||
|
// If either the LHS or the RHS are One, the result is One.
|
||||||
|
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
|
||||||
|
// If all of the demanded bits are known zero on one side, return the
|
||||||
|
// other. These bits cannot contribute to the result of the 'or' in this
|
||||||
|
// context.
|
||||||
|
if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) ==
|
||||||
|
(DemandedMask & ~LHSKnownOne))
|
||||||
|
return I->getOperand(0);
|
||||||
|
if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) ==
|
||||||
|
(DemandedMask & ~RHSKnownOne))
|
||||||
|
return I->getOperand(1);
|
||||||
|
|
||||||
|
// If all of the potentially set bits on one side are known to be set on
|
||||||
|
// the other side, just use the 'other' side.
|
||||||
|
if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) ==
|
||||||
|
(DemandedMask & (~RHSKnownZero)))
|
||||||
|
return I->getOperand(0);
|
||||||
|
if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) ==
|
||||||
|
(DemandedMask & (~LHSKnownZero)))
|
||||||
|
return I->getOperand(1);
|
||||||
|
} else if (I->getOpcode() == Instruction::Xor) {
|
||||||
|
// We can simplify (X^Y) -> X or Y in the user's context if we know that
|
||||||
|
// only bits from X or Y are demanded.
|
||||||
|
|
||||||
|
computeKnownBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
|
||||||
|
CxtI);
|
||||||
|
|
||||||
|
// If all of the demanded bits are known zero on one side, return the
|
||||||
|
// other.
|
||||||
|
if ((DemandedMask & RHSKnownZero) == DemandedMask)
|
||||||
|
return I->getOperand(0);
|
||||||
|
if ((DemandedMask & LHSKnownZero) == DemandedMask)
|
||||||
|
return I->getOperand(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the KnownZero/KnownOne bits to simplify things downstream.
|
||||||
|
computeKnownBits(I, KnownZero, KnownOne, Depth, CxtI);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Helper routine of SimplifyDemandedUseBits. It tries to simplify
|
/// Helper routine of SimplifyDemandedUseBits. It tries to simplify
|
||||||
/// "E1 = (X lsr C1) << C2", where the C1 and C2 are constant, into
|
/// "E1 = (X lsr C1) << C2", where the C1 and C2 are constant, into
|
||||||
/// "E2 = X << (C2 - C1)" or "E2 = X >> (C1 - C2)", depending on the sign
|
/// "E2 = X << (C2 - C1)" or "E2 = X >> (C1 - C2)", depending on the sign
|
||||||
|
Loading…
Reference in New Issue
Block a user