mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-16 11:24:39 +00:00
Implement InstCombine/add.ll:test(15|16)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8604 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -764,6 +764,43 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
return BinaryOperator::create(Instruction::And, Or, RHS);
|
return BinaryOperator::create(Instruction::And, Or, RHS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (Op0I->getOpcode() == Instruction::Add &&
|
||||||
|
Op0I->use_size() == 1) {
|
||||||
|
// Adding a one to a single bit bit-field should be turned into an XOR
|
||||||
|
// of the bit. First thing to check is to see if this AND is with a
|
||||||
|
// single bit constant.
|
||||||
|
unsigned long long AndRHS = cast<ConstantInt>(RHS)->getRawValue();
|
||||||
|
|
||||||
|
// Clear bits that are not part of the constant.
|
||||||
|
AndRHS &= (1ULL << RHS->getType()->getPrimitiveSize()*8)-1;
|
||||||
|
|
||||||
|
// If there is only one bit set...
|
||||||
|
if ((AndRHS & (AndRHS-1)) == 0) {
|
||||||
|
// Ok, at this point, we know that we are masking the result of the
|
||||||
|
// ADD down to exactly one bit. If the constant we are adding has
|
||||||
|
// no bits set below this bit, then we can eliminate the ADD.
|
||||||
|
unsigned long long AddRHS = cast<ConstantInt>(Op0CI)->getRawValue();
|
||||||
|
|
||||||
|
// Check to see if any bits below the one bit set in AndRHS are set.
|
||||||
|
if ((AddRHS & (AndRHS-1)) == 0) {
|
||||||
|
// If not, the only thing that can effect the output of the AND is
|
||||||
|
// the bit specified by AndRHS. If that bit is set, the effect of
|
||||||
|
// the XOR is to toggle the bit. If it is clear, then the ADD has
|
||||||
|
// no effect.
|
||||||
|
if ((AddRHS & AndRHS) == 0) { // Bit is not set, noop
|
||||||
|
I.setOperand(0, Op0I->getOperand(0));
|
||||||
|
return &I;
|
||||||
|
} else {
|
||||||
|
std::string Name = Op0I->getName(); Op0I->setName("");
|
||||||
|
// Pull the XOR out of the AND.
|
||||||
|
Instruction *NewAnd =
|
||||||
|
BinaryOperator::create(Instruction::And, Op0I->getOperand(0),
|
||||||
|
RHS, Name);
|
||||||
|
InsertNewInstBefore(NewAnd, I);
|
||||||
|
return BinaryOperator::create(Instruction::Xor, NewAnd, RHS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user