mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Make MaskedValueIsZero take a uint64_t instead of a ConstantIntegral as a
mask. This allows the code to be simpler and more efficient. Also, generalize some of the cases in MVIZ a bit, making it slightly more aggressive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26035 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -406,20 +406,19 @@ static ConstantInt *SubOne(ConstantInt *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
|
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
|
||||||
/// this predicate to simplify operations downstream. V and Mask are known to
|
/// this predicate to simplify operations downstream. Mask is known to be zero
|
||||||
/// be the same type.
|
/// for bits that V cannot have.
|
||||||
static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask,
|
static bool MaskedValueIsZero(Value *V, uint64_t Mask, unsigned Depth = 0) {
|
||||||
unsigned Depth = 0) {
|
|
||||||
// Note, we cannot consider 'undef' to be "IsZero" here. The problem is that
|
// Note, we cannot consider 'undef' to be "IsZero" here. The problem is that
|
||||||
// we cannot optimize based on the assumption that it is zero without changing
|
// we cannot optimize based on the assumption that it is zero without changing
|
||||||
// to to an explicit zero. If we don't change it to zero, other code could
|
// it to be an explicit zero. If we don't change it to zero, other code could
|
||||||
// optimized based on the contradictory assumption that it is non-zero.
|
// optimized based on the contradictory assumption that it is non-zero.
|
||||||
// Because instcombine aggressively folds operations with undef args anyway,
|
// Because instcombine aggressively folds operations with undef args anyway,
|
||||||
// this won't lose us code quality.
|
// this won't lose us code quality.
|
||||||
if (Mask->isNullValue())
|
if (Mask == 0)
|
||||||
return true;
|
return true;
|
||||||
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
|
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
|
||||||
return ConstantExpr::getAnd(CI, Mask)->isNullValue();
|
return (CI->getRawValue() & Mask) == 0;
|
||||||
|
|
||||||
if (Depth == 6) return false; // Limit search depth.
|
if (Depth == 6) return false; // Limit search depth.
|
||||||
|
|
||||||
@@ -427,12 +426,9 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask,
|
|||||||
switch (I->getOpcode()) {
|
switch (I->getOpcode()) {
|
||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
// (X & C1) & C2 == 0 iff C1 & C2 == 0.
|
// (X & C1) & C2 == 0 iff C1 & C2 == 0.
|
||||||
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1))) {
|
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1)))
|
||||||
ConstantIntegral *C1C2 =
|
return MaskedValueIsZero(I->getOperand(0), CI->getRawValue() & Mask,
|
||||||
cast<ConstantIntegral>(ConstantExpr::getAnd(CI, Mask));
|
Depth+1);
|
||||||
if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// If either the LHS or the RHS are MaskedValueIsZero, the result is zero.
|
// If either the LHS or the RHS are MaskedValueIsZero, the result is zero.
|
||||||
return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) ||
|
return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) ||
|
||||||
MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
|
MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
|
||||||
@@ -448,41 +444,34 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask,
|
|||||||
case Instruction::Cast: {
|
case Instruction::Cast: {
|
||||||
const Type *SrcTy = I->getOperand(0)->getType();
|
const Type *SrcTy = I->getOperand(0)->getType();
|
||||||
if (SrcTy == Type::BoolTy)
|
if (SrcTy == Type::BoolTy)
|
||||||
return (Mask->getRawValue() & 1) == 0;
|
return (Mask & 1) == 0;
|
||||||
|
if (!SrcTy->isInteger()) return false;
|
||||||
|
|
||||||
if (SrcTy->isInteger()) {
|
// (cast <ty> X to int) & C2 == 0 iff <ty> could not have contained C2.
|
||||||
// (cast <ty> X to int) & C2 == 0 iff <ty> could not have contained C2.
|
if (SrcTy->isUnsigned()) // Only handle zero ext.
|
||||||
if (SrcTy->isUnsigned() && // Only handle zero ext.
|
return MaskedValueIsZero(I->getOperand(0),
|
||||||
ConstantExpr::getCast(Mask, SrcTy)->isNullValue())
|
Mask & SrcTy->getIntegralTypeMask(), Depth+1);
|
||||||
return true;
|
|
||||||
|
// If this is a noop or trunc cast, recurse.
|
||||||
// If this is a noop cast, recurse.
|
if (SrcTy->getPrimitiveSizeInBits() >=
|
||||||
if ((SrcTy->isSigned() && SrcTy->getUnsignedVersion() == I->getType())||
|
I->getType()->getPrimitiveSizeInBits())
|
||||||
SrcTy->getSignedVersion() == I->getType()) {
|
return MaskedValueIsZero(I->getOperand(0),
|
||||||
Constant *NewMask =
|
Mask & SrcTy->getIntegralTypeMask(), Depth+1);
|
||||||
ConstantExpr::getCast(Mask, I->getOperand(0)->getType());
|
|
||||||
return MaskedValueIsZero(I->getOperand(0),
|
|
||||||
cast<ConstantIntegral>(NewMask), Depth+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::Shl:
|
case Instruction::Shl:
|
||||||
// (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
|
// (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
|
||||||
if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
|
if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
|
||||||
return MaskedValueIsZero(I->getOperand(0),
|
return MaskedValueIsZero(I->getOperand(0), Mask >> SA->getValue(),
|
||||||
cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA)),
|
|
||||||
Depth+1);
|
Depth+1);
|
||||||
break;
|
break;
|
||||||
case Instruction::Shr:
|
case Instruction::Shr:
|
||||||
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
|
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
|
||||||
if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
|
if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
|
||||||
if (I->getType()->isUnsigned()) {
|
if (I->getType()->isUnsigned()) {
|
||||||
Constant *C1 = ConstantIntegral::getAllOnesValue(I->getType());
|
Mask <<= SA->getValue();
|
||||||
C1 = ConstantExpr::getShr(C1, SA);
|
Mask &= I->getType()->getIntegralTypeMask();
|
||||||
C1 = ConstantExpr::getAnd(C1, Mask);
|
return MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
|
||||||
if (C1->isNullValue())
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -877,10 +866,9 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
if (Found) {
|
if (Found) {
|
||||||
// This is a sign extend if the top bits are known zero.
|
// This is a sign extend if the top bits are known zero.
|
||||||
Constant *Mask = ConstantInt::getAllOnesValue(XorLHS->getType());
|
uint64_t Mask = XorLHS->getType()->getIntegralTypeMask();
|
||||||
Mask = ConstantExpr::getShl(Mask,
|
Mask <<= 64-(TySizeBits-Size);
|
||||||
ConstantInt::get(Type::UByteTy, 64-(TySizeBits-Size)));
|
if (!MaskedValueIsZero(XorLHS, Mask))
|
||||||
if (!MaskedValueIsZero(XorLHS, cast<ConstantInt>(Mask)))
|
|
||||||
Size = 0; // Not a sign ext, but can't be any others either.
|
Size = 0; // Not a sign ext, but can't be any others either.
|
||||||
goto FoundSExt;
|
goto FoundSExt;
|
||||||
}
|
}
|
||||||
@@ -1375,10 +1363,10 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
|
|||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
|
|
||||||
if (I.getType()->isSigned()) {
|
if (I.getType()->isSigned()) {
|
||||||
// If the top bits of both operands are zero (i.e. we can prove they are
|
// If the sign bits of both operands are zero (i.e. we can prove they are
|
||||||
// unsigned inputs), turn this into a udiv.
|
// unsigned inputs), turn this into a udiv.
|
||||||
ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
|
uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
|
||||||
if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
|
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
||||||
const Type *NTy = Op0->getType()->getUnsignedVersion();
|
const Type *NTy = Op0->getType()->getUnsignedVersion();
|
||||||
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
|
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
|
||||||
InsertNewInstBefore(LHS, I);
|
InsertNewInstBefore(LHS, I);
|
||||||
@@ -1430,8 +1418,8 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
|||||||
|
|
||||||
// If the top bits of both operands are zero (i.e. we can prove they are
|
// If the top bits of both operands are zero (i.e. we can prove they are
|
||||||
// unsigned inputs), turn this into a urem.
|
// unsigned inputs), turn this into a urem.
|
||||||
ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
|
uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
|
||||||
if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
|
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
||||||
const Type *NTy = Op0->getType()->getUnsignedVersion();
|
const Type *NTy = Op0->getType()->getUnsignedVersion();
|
||||||
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
|
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
|
||||||
InsertNewInstBefore(LHS, I);
|
InsertNewInstBefore(LHS, I);
|
||||||
@@ -1888,11 +1876,9 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS,
|
|||||||
// is all N is, ignore it.
|
// is all N is, ignore it.
|
||||||
unsigned MB, ME;
|
unsigned MB, ME;
|
||||||
if (isRunOfOnes(Mask, MB, ME)) { // begin/end bit of run, inclusive
|
if (isRunOfOnes(Mask, MB, ME)) { // begin/end bit of run, inclusive
|
||||||
Constant *Mask = ConstantInt::getAllOnesValue(RHS->getType());
|
uint64_t Mask = RHS->getType()->getIntegralTypeMask();
|
||||||
Mask = ConstantExpr::getUShr(Mask,
|
Mask >>= 64-MB+1;
|
||||||
ConstantInt::get(Type::UByteTy,
|
if (MaskedValueIsZero(RHS, Mask))
|
||||||
(64-MB+1)));
|
|
||||||
if (MaskedValueIsZero(RHS, cast<ConstantIntegral>(Mask)))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1939,13 +1925,13 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS));
|
return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MaskedValueIsZero(Op0, AndRHS)) // LHS & RHS == 0
|
if (MaskedValueIsZero(Op0, AndRHS->getZExtValue())) // LHS & RHS == 0
|
||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
|
|
||||||
// If the mask is not masking out any bits, there is no reason to do the
|
// If the mask is not masking out any bits, there is no reason to do the
|
||||||
// and in the first place.
|
// and in the first place.
|
||||||
ConstantIntegral *NotAndRHS =
|
uint64_t NotAndRHS = // ~ANDRHS
|
||||||
cast<ConstantIntegral>(ConstantExpr::getNot(AndRHS));
|
AndRHS->getZExtValue()^Op0->getType()->getIntegralTypeMask();
|
||||||
if (MaskedValueIsZero(Op0, NotAndRHS))
|
if (MaskedValueIsZero(Op0, NotAndRHS))
|
||||||
return ReplaceInstUsesWith(I, Op0);
|
return ReplaceInstUsesWith(I, Op0);
|
||||||
|
|
||||||
@@ -1964,9 +1950,9 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
// (X ^ V) & C2 --> (X & C2) iff (V & C2) == 0
|
// (X ^ V) & C2 --> (X & C2) iff (V & C2) == 0
|
||||||
// (X | V) & C2 --> (X & C2) iff (V & C2) == 0
|
// (X | V) & C2 --> (X & C2) iff (V & C2) == 0
|
||||||
if (MaskedValueIsZero(Op0LHS, AndRHS))
|
if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()))
|
||||||
return BinaryOperator::createAnd(Op0RHS, AndRHS);
|
return BinaryOperator::createAnd(Op0RHS, AndRHS);
|
||||||
if (MaskedValueIsZero(Op0RHS, AndRHS))
|
if (MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
|
||||||
return BinaryOperator::createAnd(Op0LHS, AndRHS);
|
return BinaryOperator::createAnd(Op0LHS, AndRHS);
|
||||||
|
|
||||||
// If the mask is only needed on one incoming arm, push it up.
|
// If the mask is only needed on one incoming arm, push it up.
|
||||||
@@ -1979,7 +1965,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
return BinaryOperator::create(
|
return BinaryOperator::create(
|
||||||
cast<BinaryOperator>(Op0I)->getOpcode(), Op0LHS, NewRHS);
|
cast<BinaryOperator>(Op0I)->getOpcode(), Op0LHS, NewRHS);
|
||||||
}
|
}
|
||||||
if (!isa<Constant>(NotAndRHS) &&
|
if (!isa<Constant>(Op0RHS) &&
|
||||||
MaskedValueIsZero(Op0RHS, NotAndRHS)) {
|
MaskedValueIsZero(Op0RHS, NotAndRHS)) {
|
||||||
// Not masking anything out for the RHS, move to LHS.
|
// Not masking anything out for the RHS, move to LHS.
|
||||||
Instruction *NewLHS = BinaryOperator::createAnd(Op0LHS, AndRHS,
|
Instruction *NewLHS = BinaryOperator::createAnd(Op0LHS, AndRHS,
|
||||||
@@ -1993,8 +1979,8 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
break;
|
break;
|
||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
// (X & V) & C2 --> 0 iff (V & C2) == 0
|
// (X & V) & C2 --> 0 iff (V & C2) == 0
|
||||||
if (MaskedValueIsZero(Op0LHS, AndRHS) ||
|
if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()) ||
|
||||||
MaskedValueIsZero(Op0RHS, AndRHS))
|
MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
|
||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
break;
|
break;
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
@@ -2239,8 +2225,8 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
|
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
|
||||||
// If X is known to only contain bits that already exist in RHS, just
|
// If X is known to only contain bits that already exist in RHS, just
|
||||||
// replace this instruction with RHS directly.
|
// replace this instruction with RHS directly.
|
||||||
if (MaskedValueIsZero(Op0,
|
if (MaskedValueIsZero(Op0,
|
||||||
cast<ConstantIntegral>(ConstantExpr::getNot(RHS))))
|
RHS->getZExtValue()^RHS->getType()->getIntegralTypeMask()))
|
||||||
return ReplaceInstUsesWith(I, RHS);
|
return ReplaceInstUsesWith(I, RHS);
|
||||||
|
|
||||||
ConstantInt *C1 = 0; Value *X = 0;
|
ConstantInt *C1 = 0; Value *X = 0;
|
||||||
@@ -2282,7 +2268,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
|
|
||||||
// (X^C)|Y -> (X|Y)^C iff Y&C == 0
|
// (X^C)|Y -> (X|Y)^C iff Y&C == 0
|
||||||
if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
|
if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
|
||||||
MaskedValueIsZero(Op1, C1)) {
|
MaskedValueIsZero(Op1, C1->getZExtValue())) {
|
||||||
Instruction *NOr = BinaryOperator::createOr(A, Op1, Op0->getName());
|
Instruction *NOr = BinaryOperator::createOr(A, Op1, Op0->getName());
|
||||||
Op0->setName("");
|
Op0->setName("");
|
||||||
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
|
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
|
||||||
@@ -2290,7 +2276,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
|
|
||||||
// Y|(X^C) -> (X|Y)^C iff Y&C == 0
|
// Y|(X^C) -> (X|Y)^C iff Y&C == 0
|
||||||
if (Op1->hasOneUse() && match(Op1, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
|
if (Op1->hasOneUse() && match(Op1, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
|
||||||
MaskedValueIsZero(Op0, C1)) {
|
MaskedValueIsZero(Op0, C1->getZExtValue())) {
|
||||||
Instruction *NOr = BinaryOperator::createOr(A, Op0, Op1->getName());
|
Instruction *NOr = BinaryOperator::createOr(A, Op0, Op1->getName());
|
||||||
Op0->setName("");
|
Op0->setName("");
|
||||||
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
|
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
|
||||||
@@ -2312,18 +2298,18 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
if ((C2->getRawValue() & (C2->getRawValue()+1)) == 0 && // C2 == 0+1+
|
if ((C2->getRawValue() & (C2->getRawValue()+1)) == 0 && // C2 == 0+1+
|
||||||
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
|
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
|
||||||
// Add commutes, try both ways.
|
// Add commutes, try both ways.
|
||||||
if (V1 == B && MaskedValueIsZero(V2, C2))
|
if (V1 == B && MaskedValueIsZero(V2, C2->getZExtValue()))
|
||||||
return ReplaceInstUsesWith(I, A);
|
return ReplaceInstUsesWith(I, A);
|
||||||
if (V2 == B && MaskedValueIsZero(V1, C2))
|
if (V2 == B && MaskedValueIsZero(V1, C2->getZExtValue()))
|
||||||
return ReplaceInstUsesWith(I, A);
|
return ReplaceInstUsesWith(I, A);
|
||||||
}
|
}
|
||||||
// Or commutes, try both ways.
|
// Or commutes, try both ways.
|
||||||
if ((C1->getRawValue() & (C1->getRawValue()+1)) == 0 &&
|
if ((C1->getRawValue() & (C1->getRawValue()+1)) == 0 &&
|
||||||
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
|
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
|
||||||
// Add commutes, try both ways.
|
// Add commutes, try both ways.
|
||||||
if (V1 == A && MaskedValueIsZero(V2, C1))
|
if (V1 == A && MaskedValueIsZero(V2, C1->getZExtValue()))
|
||||||
return ReplaceInstUsesWith(I, B);
|
return ReplaceInstUsesWith(I, B);
|
||||||
if (V2 == A && MaskedValueIsZero(V1, C1))
|
if (V2 == A && MaskedValueIsZero(V1, C1->getZExtValue()))
|
||||||
return ReplaceInstUsesWith(I, B);
|
return ReplaceInstUsesWith(I, B);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3599,7 +3585,8 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
|
|||||||
|
|
||||||
// See if we can turn a signed shr into an unsigned shr.
|
// See if we can turn a signed shr into an unsigned shr.
|
||||||
if (!isLeftShift && I.getType()->isSigned()) {
|
if (!isLeftShift && I.getType()->isSigned()) {
|
||||||
if (MaskedValueIsZero(Op0, ConstantInt::getMinValue(I.getType()))) {
|
if (MaskedValueIsZero(Op0,
|
||||||
|
1ULL << (I.getType()->getPrimitiveSizeInBits()-1))) {
|
||||||
Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
|
Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
|
||||||
V = InsertNewInstBefore(new ShiftInst(Instruction::Shr, V, Op1,
|
V = InsertNewInstBefore(new ShiftInst(Instruction::Shr, V, Op1,
|
||||||
I.getName()), I);
|
I.getName()), I);
|
||||||
@@ -4373,7 +4360,8 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
|||||||
Constant *Not1 =
|
Constant *Not1 =
|
||||||
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
|
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
|
||||||
// cast (X != 0) to int --> X if X&~1 == 0
|
// cast (X != 0) to int --> X if X&~1 == 0
|
||||||
if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
|
if (MaskedValueIsZero(Op0,
|
||||||
|
cast<ConstantIntegral>(Not1)->getZExtValue())) {
|
||||||
if (CI.getType() == Op0->getType())
|
if (CI.getType() == Op0->getType())
|
||||||
return ReplaceInstUsesWith(CI, Op0);
|
return ReplaceInstUsesWith(CI, Op0);
|
||||||
else
|
else
|
||||||
@@ -4415,7 +4403,8 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
|||||||
if (Op1C->getRawValue() == 1) {
|
if (Op1C->getRawValue() == 1) {
|
||||||
Constant *Not1 =
|
Constant *Not1 =
|
||||||
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
|
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
|
||||||
if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
|
if (MaskedValueIsZero(Op0,
|
||||||
|
cast<ConstantIntegral>(Not1)->getZExtValue())) {
|
||||||
if (CI.getType() == Op0->getType())
|
if (CI.getType() == Op0->getType())
|
||||||
return ReplaceInstUsesWith(CI, Op0);
|
return ReplaceInstUsesWith(CI, Op0);
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user