more cleanups, notably bitcast isn't used for "signed to unsigned type

conversions". :)

llvm-svn: 125265
This commit is contained in:
Chris Lattner 2011-02-10 05:17:27 +00:00
parent 7d0e43ff8b
commit dcef03fba2
2 changed files with 28 additions and 46 deletions

View File

@ -703,9 +703,9 @@ static Value* foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS,
// whole construct
if (!MCst->isZero())
return 0;
Value* newOr1 = Builder->CreateOr(B, D);
Value* newOr2 = ConstantExpr::getOr(CCst, ECst);
Value* newAnd = Builder->CreateAnd(A, newOr1);
Value *newOr1 = Builder->CreateOr(B, D);
Value *newOr2 = ConstantExpr::getOr(CCst, ECst);
Value *newAnd = Builder->CreateAnd(A, newOr1);
return Builder->CreateICmp(NEWCC, newAnd, newOr2);
}
return 0;
@ -729,12 +729,9 @@ Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
}
}
{
// handle (roughly):
// (icmp eq (A & B), C) & (icmp eq (A & D), E)
Value* fold = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_EQ, Builder);
if (fold) return fold;
}
// handle (roughly): (icmp eq (A & B), C) & (icmp eq (A & D), E)
if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_EQ, Builder))
return V;
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0);
@ -997,7 +994,6 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
const APInt &AndRHSMask = AndRHS->getValue();
APInt NotAndRHS(~AndRHSMask);
// Optimize a variety of ((val OP C1) & C2) combinations...
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
@ -1006,10 +1002,11 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
switch (Op0I->getOpcode()) {
default: break;
case Instruction::Xor:
case Instruction::Or:
case Instruction::Or: {
// If the mask is only needed on one incoming arm, push it up.
if (!Op0I->hasOneUse()) break;
APInt NotAndRHS(~AndRHSMask);
if (MaskedValueIsZero(Op0LHS, NotAndRHS)) {
// Not masking anything out for the LHS, move to RHS.
Value *NewRHS = Builder->CreateAnd(Op0RHS, AndRHS,
@ -1025,6 +1022,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
break;
}
case Instruction::Add:
// ((A & N) + B) & AndRHS -> (A + B) & AndRHS iff N&AndRHS == AndRHS.
// ((A | N) + B) & AndRHS -> (A + B) & AndRHS iff N&AndRHS == 0
@ -1044,14 +1042,12 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
// (A - N) & AndRHS -> -N & AndRHS iff A&AndRHS==0 and AndRHS
// has 1's for all bits that the subtraction with A might affect.
if (Op0I->hasOneUse()) {
if (Op0I->hasOneUse() && !match(Op0LHS, m_Zero())) {
uint32_t BitWidth = AndRHSMask.getBitWidth();
uint32_t Zeros = AndRHSMask.countLeadingZeros();
APInt Mask = APInt::getLowBitsSet(BitWidth, BitWidth - Zeros);
ConstantInt *A = dyn_cast<ConstantInt>(Op0LHS);
if (!(A && A->isZero()) && // avoid infinite recursion.
MaskedValueIsZero(Op0LHS, Mask)) {
if (MaskedValueIsZero(Op0LHS, Mask)) {
Value *NewNeg = Builder->CreateNeg(Op0RHS);
return BinaryOperator::CreateAnd(NewNeg, AndRHS);
}
@ -1073,35 +1069,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
if (Instruction *Res = OptAndOp(Op0I, Op0CI, AndRHS, I))
return Res;
} else if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
// If this is an integer truncation or change from signed-to-unsigned, and
// if the source is an and/or with immediate, transform it. This
// frequently occurs for bitfield accesses.
if (Instruction *CastOp = dyn_cast<Instruction>(CI->getOperand(0))) {
if ((isa<TruncInst>(CI) || isa<BitCastInst>(CI)) &&
CastOp->getNumOperands() == 2)
if (ConstantInt *AndCI =dyn_cast<ConstantInt>(CastOp->getOperand(1))){
if (CastOp->getOpcode() == Instruction::And) {
// Change: and (cast (and X, C1) to T), C2
// into : and (cast X to T), trunc_or_bitcast(C1)&C2
// This will fold the two constants together, which may allow
// other simplifications.
Value *NewCast = Builder->CreateTruncOrBitCast(
CastOp->getOperand(0), I.getType(),
CastOp->getName()+".shrunk");
// trunc_or_bitcast(C1)&C2
Constant *C3 = ConstantExpr::getTruncOrBitCast(AndCI,I.getType());
C3 = ConstantExpr::getAnd(C3, AndRHS);
return BinaryOperator::CreateAnd(NewCast, C3);
} else if (CastOp->getOpcode() == Instruction::Or) {
// Change: and (cast (or X, C1) to T), C2
// into : trunc(C1)&C2 iff trunc(C1)&C2 == C2
Constant *C3 = ConstantExpr::getTruncOrBitCast(AndCI,I.getType());
if (ConstantExpr::getAnd(C3, AndRHS) == AndRHS)
// trunc(C1)&C2
return ReplaceInstUsesWith(I, AndRHS);
}
}
}
// If this is an integer truncation, and if the source is an 'and' with
// immediate, transform it. This frequently occurs for bitfield accesses.
{
Value *X = 0; ConstantInt *YC = 0;
if (match(Op0, m_Trunc(m_And(m_Value(X), m_ConstantInt(YC))))) {
// Change: and (trunc (and X, YC) to T), C2
// into : and (trunc X to T), trunc(YC) & C2
// This will fold the two constants together, which may allow
// other simplifications.
Value *NewCast = Builder->CreateTrunc(X, I.getType(), "and.shrunk");
Constant *C3 = ConstantExpr::getTrunc(YC, I.getType());
C3 = ConstantExpr::getAnd(C3, AndRHS);
return BinaryOperator::CreateAnd(NewCast, C3);
}
}
@ -1123,7 +1105,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
I.getName()+".demorgan");
return BinaryOperator::CreateNot(Or);
}
{
Value *A = 0, *B = 0, *C = 0, *D = 0;
// (A|B) & ~(A&B) -> A^B

View File

@ -40,7 +40,7 @@ define i32 @test5(i32 %A, i32 %B, i32 %C) {
%E = sub i32 %A, %D
ret i32 %E
; CHECK: @test5
; CHECK: %D = sub i32 %C, %B
; CHECK: %D1 = sub i32 %C, %B
; CHECK: %E = add
; CHECK: ret i32 %E
}