mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
more cleanups, notably bitcast isn't used for "signed to unsigned type
conversions". :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125265 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b9b9044600
commit
44cc997d42
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user