mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-14 17:34:41 +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
|
// whole construct
|
||||||
if (!MCst->isZero())
|
if (!MCst->isZero())
|
||||||
return 0;
|
return 0;
|
||||||
Value* newOr1 = Builder->CreateOr(B, D);
|
Value *newOr1 = Builder->CreateOr(B, D);
|
||||||
Value* newOr2 = ConstantExpr::getOr(CCst, ECst);
|
Value *newOr2 = ConstantExpr::getOr(CCst, ECst);
|
||||||
Value* newAnd = Builder->CreateAnd(A, newOr1);
|
Value *newAnd = Builder->CreateAnd(A, newOr1);
|
||||||
return Builder->CreateICmp(NEWCC, newAnd, newOr2);
|
return Builder->CreateICmp(NEWCC, newAnd, newOr2);
|
||||||
}
|
}
|
||||||
return 0;
|
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)
|
||||||
// handle (roughly):
|
if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_EQ, Builder))
|
||||||
// (icmp eq (A & B), C) & (icmp eq (A & D), E)
|
return V;
|
||||||
Value* fold = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_EQ, Builder);
|
|
||||||
if (fold) return fold;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
|
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
|
||||||
Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0);
|
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)) {
|
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
|
||||||
const APInt &AndRHSMask = AndRHS->getValue();
|
const APInt &AndRHSMask = AndRHS->getValue();
|
||||||
APInt NotAndRHS(~AndRHSMask);
|
|
||||||
|
|
||||||
// Optimize a variety of ((val OP C1) & C2) combinations...
|
// Optimize a variety of ((val OP C1) & C2) combinations...
|
||||||
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
|
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
|
||||||
@ -1006,10 +1002,11 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
switch (Op0I->getOpcode()) {
|
switch (Op0I->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case Instruction::Xor:
|
case Instruction::Xor:
|
||||||
case Instruction::Or:
|
case Instruction::Or: {
|
||||||
// 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.
|
||||||
if (!Op0I->hasOneUse()) break;
|
if (!Op0I->hasOneUse()) break;
|
||||||
|
|
||||||
|
APInt NotAndRHS(~AndRHSMask);
|
||||||
if (MaskedValueIsZero(Op0LHS, NotAndRHS)) {
|
if (MaskedValueIsZero(Op0LHS, NotAndRHS)) {
|
||||||
// Not masking anything out for the LHS, move to RHS.
|
// Not masking anything out for the LHS, move to RHS.
|
||||||
Value *NewRHS = Builder->CreateAnd(Op0RHS, AndRHS,
|
Value *NewRHS = Builder->CreateAnd(Op0RHS, AndRHS,
|
||||||
@ -1025,6 +1022,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
// ((A & N) + B) & AndRHS -> (A + B) & AndRHS iff N&AndRHS == AndRHS.
|
// ((A & N) + B) & AndRHS -> (A + B) & AndRHS iff N&AndRHS == AndRHS.
|
||||||
// ((A | N) + B) & AndRHS -> (A + B) & AndRHS iff N&AndRHS == 0
|
// ((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
|
// (A - N) & AndRHS -> -N & AndRHS iff A&AndRHS==0 and AndRHS
|
||||||
// has 1's for all bits that the subtraction with A might affect.
|
// 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 BitWidth = AndRHSMask.getBitWidth();
|
||||||
uint32_t Zeros = AndRHSMask.countLeadingZeros();
|
uint32_t Zeros = AndRHSMask.countLeadingZeros();
|
||||||
APInt Mask = APInt::getLowBitsSet(BitWidth, BitWidth - Zeros);
|
APInt Mask = APInt::getLowBitsSet(BitWidth, BitWidth - Zeros);
|
||||||
|
|
||||||
ConstantInt *A = dyn_cast<ConstantInt>(Op0LHS);
|
if (MaskedValueIsZero(Op0LHS, Mask)) {
|
||||||
if (!(A && A->isZero()) && // avoid infinite recursion.
|
|
||||||
MaskedValueIsZero(Op0LHS, Mask)) {
|
|
||||||
Value *NewNeg = Builder->CreateNeg(Op0RHS);
|
Value *NewNeg = Builder->CreateNeg(Op0RHS);
|
||||||
return BinaryOperator::CreateAnd(NewNeg, AndRHS);
|
return BinaryOperator::CreateAnd(NewNeg, AndRHS);
|
||||||
}
|
}
|
||||||
@ -1073,35 +1069,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
|
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
|
||||||
if (Instruction *Res = OptAndOp(Op0I, Op0CI, AndRHS, I))
|
if (Instruction *Res = OptAndOp(Op0I, Op0CI, AndRHS, I))
|
||||||
return Res;
|
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
|
// If this is an integer truncation, and if the source is an 'and' with
|
||||||
// frequently occurs for bitfield accesses.
|
// 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)) &&
|
Value *X = 0; ConstantInt *YC = 0;
|
||||||
CastOp->getNumOperands() == 2)
|
if (match(Op0, m_Trunc(m_And(m_Value(X), m_ConstantInt(YC))))) {
|
||||||
if (ConstantInt *AndCI =dyn_cast<ConstantInt>(CastOp->getOperand(1))){
|
// Change: and (trunc (and X, YC) to T), C2
|
||||||
if (CastOp->getOpcode() == Instruction::And) {
|
// into : and (trunc X to T), trunc(YC) & C2
|
||||||
// Change: and (cast (and X, C1) to T), C2
|
// This will fold the two constants together, which may allow
|
||||||
// into : and (cast X to T), trunc_or_bitcast(C1)&C2
|
// other simplifications.
|
||||||
// This will fold the two constants together, which may allow
|
Value *NewCast = Builder->CreateTrunc(X, I.getType(), "and.shrunk");
|
||||||
// other simplifications.
|
Constant *C3 = ConstantExpr::getTrunc(YC, I.getType());
|
||||||
Value *NewCast = Builder->CreateTruncOrBitCast(
|
C3 = ConstantExpr::getAnd(C3, AndRHS);
|
||||||
CastOp->getOperand(0), I.getType(),
|
return BinaryOperator::CreateAnd(NewCast, C3);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,7 +1105,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
I.getName()+".demorgan");
|
I.getName()+".demorgan");
|
||||||
return BinaryOperator::CreateNot(Or);
|
return BinaryOperator::CreateNot(Or);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Value *A = 0, *B = 0, *C = 0, *D = 0;
|
Value *A = 0, *B = 0, *C = 0, *D = 0;
|
||||||
// (A|B) & ~(A&B) -> A^B
|
// (A|B) & ~(A&B) -> A^B
|
||||||
|
@ -40,7 +40,7 @@ define i32 @test5(i32 %A, i32 %B, i32 %C) {
|
|||||||
%E = sub i32 %A, %D
|
%E = sub i32 %A, %D
|
||||||
ret i32 %E
|
ret i32 %E
|
||||||
; CHECK: @test5
|
; CHECK: @test5
|
||||||
; CHECK: %D = sub i32 %C, %B
|
; CHECK: %D1 = sub i32 %C, %B
|
||||||
; CHECK: %E = add
|
; CHECK: %E = add
|
||||||
; CHECK: ret i32 %E
|
; CHECK: ret i32 %E
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user