mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-25 21:18:19 +00:00
Re-apply r113679, which was reverted in r113720, which added a paid of new instcombine transforms
to expose greater opportunities for store narrowing in codegen. This patch fixes a potential infinite loop in instcombine caused by one of the introduced transforms being overly aggressive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113763 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -207,12 +207,26 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
|
||||
}
|
||||
break;
|
||||
case Instruction::Or:
|
||||
if (Op->hasOneUse() && Together != OpRHS) {
|
||||
// (X | C1) & C2 --> (X | (C1&C2)) & C2
|
||||
Value *Or = Builder->CreateOr(X, Together);
|
||||
Or->takeName(Op);
|
||||
return BinaryOperator::CreateAnd(Or, AndRHS);
|
||||
if (Op->hasOneUse()){
|
||||
if (Together != OpRHS) {
|
||||
// (X | C1) & C2 --> (X | (C1&C2)) & C2
|
||||
Value *Or = Builder->CreateOr(X, Together);
|
||||
Or->takeName(Op);
|
||||
return BinaryOperator::CreateAnd(Or, AndRHS);
|
||||
}
|
||||
|
||||
ConstantInt *TogetherCI = dyn_cast<ConstantInt>(Together);
|
||||
if (TogetherCI && !TogetherCI->isZero()){
|
||||
// (X | C1) & C2 --> (X & (C2^(C1&C2))) | C1
|
||||
// NOTE: This reduces the number of bits set in the & mask, which
|
||||
// can expose opportunities for store narrowing.
|
||||
Together = ConstantExpr::getXor(AndRHS, Together);
|
||||
Value *And = Builder->CreateAnd(X, Together);
|
||||
And->takeName(Op);
|
||||
return BinaryOperator::CreateOr(And, OpRHS);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Instruction::Add:
|
||||
if (Op->hasOneUse()) {
|
||||
@@ -1943,6 +1957,18 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
}
|
||||
}
|
||||
|
||||
// Note: If we've gotten to the point of visiting the outer OR, then the
|
||||
// inner one couldn't be simplified. If it was a constant, then it won't
|
||||
// be simplified by a later pass either, so we try swapping the inner/outer
|
||||
// ORs in the hopes that we'll be able to simplify it this way.
|
||||
// (X|C) | V --> (X|V) | C
|
||||
if (Op0->hasOneUse() && !isa<ConstantInt>(Op1) &&
|
||||
match(Op0, m_Or(m_Value(A), m_ConstantInt(C1)))) {
|
||||
Value *Inner = Builder->CreateOr(A, Op1);
|
||||
Inner->takeName(Op0);
|
||||
return BinaryOperator::CreateOr(Inner, C1);
|
||||
}
|
||||
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user