mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
Implement InstCombine/cast.ll:test31. This speeds up 462.libquantum by 26%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30456 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e04deb9914
commit
e695a3bd32
@ -3871,12 +3871,46 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
|||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
|
if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
|
||||||
LHSI->getOperand(0)->hasOneUse()) {
|
LHSI->getOperand(0)->hasOneUse()) {
|
||||||
|
ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
|
||||||
|
|
||||||
|
// If an operand is an AND of a truncating cast, we can widen the
|
||||||
|
// and/compare to be the input width without changing the value
|
||||||
|
// produced, eliminating a cast.
|
||||||
|
if (CastInst *Cast = dyn_cast<CastInst>(LHSI->getOperand(0))) {
|
||||||
|
// We can do this transformation if either the AND constant does not
|
||||||
|
// have its sign bit set or if it is an equality comparison.
|
||||||
|
// Extending a relational comparison when we're checking the sign
|
||||||
|
// bit would not work.
|
||||||
|
if (Cast->hasOneUse() && Cast->isTruncIntCast() &&
|
||||||
|
(I.isEquality() ||
|
||||||
|
(AndCST->getZExtValue() == (uint64_t)AndCST->getSExtValue()) &&
|
||||||
|
(CI->getZExtValue() == (uint64_t)CI->getSExtValue()))) {
|
||||||
|
ConstantInt *NewCST;
|
||||||
|
ConstantInt *NewCI;
|
||||||
|
if (Cast->getOperand(0)->getType()->isSigned()) {
|
||||||
|
NewCST = ConstantSInt::get(Cast->getOperand(0)->getType(),
|
||||||
|
AndCST->getZExtValue());
|
||||||
|
NewCI = ConstantSInt::get(Cast->getOperand(0)->getType(),
|
||||||
|
CI->getZExtValue());
|
||||||
|
} else {
|
||||||
|
NewCST = ConstantUInt::get(Cast->getOperand(0)->getType(),
|
||||||
|
AndCST->getZExtValue());
|
||||||
|
NewCI = ConstantUInt::get(Cast->getOperand(0)->getType(),
|
||||||
|
CI->getZExtValue());
|
||||||
|
}
|
||||||
|
Instruction *NewAnd =
|
||||||
|
BinaryOperator::createAnd(Cast->getOperand(0), NewCST,
|
||||||
|
LHSI->getName());
|
||||||
|
InsertNewInstBefore(NewAnd, I);
|
||||||
|
return new SetCondInst(I.getOpcode(), NewAnd, NewCI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If this is: (X >> C1) & C2 != C3 (where any shift and any compare
|
// If this is: (X >> C1) & C2 != C3 (where any shift and any compare
|
||||||
// could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This
|
// could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This
|
||||||
// happens a LOT in code produced by the C front-end, for bitfield
|
// happens a LOT in code produced by the C front-end, for bitfield
|
||||||
// access.
|
// access.
|
||||||
ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
|
ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
|
||||||
Constant *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
|
|
||||||
|
|
||||||
// Check to see if there is a noop-cast between the shift and the and.
|
// Check to see if there is a noop-cast between the shift and the and.
|
||||||
if (!Shift) {
|
if (!Shift) {
|
||||||
@ -3962,11 +3996,12 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
|||||||
"tmp");
|
"tmp");
|
||||||
} else {
|
} else {
|
||||||
// Make sure we insert a logical shift.
|
// Make sure we insert a logical shift.
|
||||||
|
Constant *NewAndCST = AndCST;
|
||||||
if (AndCST->getType()->isSigned())
|
if (AndCST->getType()->isSigned())
|
||||||
AndCST = ConstantExpr::getCast(AndCST,
|
NewAndCST = ConstantExpr::getCast(AndCST,
|
||||||
AndCST->getType()->getUnsignedVersion());
|
AndCST->getType()->getUnsignedVersion());
|
||||||
NS = new ShiftInst(Instruction::Shr, AndCST, Shift->getOperand(1),
|
NS = new ShiftInst(Instruction::Shr, NewAndCST,
|
||||||
"tmp");
|
Shift->getOperand(1), "tmp");
|
||||||
}
|
}
|
||||||
InsertNewInstBefore(cast<Instruction>(NS), I);
|
InsertNewInstBefore(cast<Instruction>(NS), I);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user