mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
implement InstCombine/shift-simplify.ll by transforming:
(X >> Z) op (Y >> Z) -> (X op Y) >> Z for all shifts and all ops={and/or/xor}. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9961cf1fed
commit
e511b74f4a
@ -3310,9 +3310,9 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
}
|
||||
|
||||
// fold (and (cast A), (cast B)) -> (cast (and A, B))
|
||||
if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) {
|
||||
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
|
||||
const Type *SrcTy = Op0C->getOperand(0)->getType();
|
||||
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
|
||||
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
|
||||
// Only do this if the casts both really cause code to be generated.
|
||||
ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
|
||||
@ -3324,6 +3324,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
return new CastInst(NewOp, I.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (X >> Z) & (Y >> Z) -> (X&Y) >> Z for all shifts.
|
||||
if (ShiftInst *SI1 = dyn_cast<ShiftInst>(Op1)) {
|
||||
if (ShiftInst *SI0 = dyn_cast<ShiftInst>(Op0))
|
||||
if (SI0->getOpcode() == SI1->getOpcode() &&
|
||||
SI0->getOperand(1) == SI1->getOperand(1) &&
|
||||
(SI0->hasOneUse() || SI1->hasOneUse())) {
|
||||
Instruction *NewOp =
|
||||
InsertNewInstBefore(BinaryOperator::createAnd(SI0->getOperand(0),
|
||||
SI1->getOperand(0),
|
||||
SI0->getName()), I);
|
||||
return new ShiftInst(SI1->getOpcode(), NewOp, SI1->getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
@ -3568,6 +3583,20 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
}
|
||||
}
|
||||
|
||||
// (X >> Z) | (Y >> Z) -> (X|Y) >> Z for all shifts.
|
||||
if (ShiftInst *SI1 = dyn_cast<ShiftInst>(Op1)) {
|
||||
if (ShiftInst *SI0 = dyn_cast<ShiftInst>(Op0))
|
||||
if (SI0->getOpcode() == SI1->getOpcode() &&
|
||||
SI0->getOperand(1) == SI1->getOperand(1) &&
|
||||
(SI0->hasOneUse() || SI1->hasOneUse())) {
|
||||
Instruction *NewOp =
|
||||
InsertNewInstBefore(BinaryOperator::createOr(SI0->getOperand(0),
|
||||
SI1->getOperand(0),
|
||||
SI0->getName()), I);
|
||||
return new ShiftInst(SI1->getOpcode(), NewOp, SI1->getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1
|
||||
if (A == Op1) // ~A | A == -1
|
||||
return ReplaceInstUsesWith(I,
|
||||
@ -3880,6 +3909,20 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
}
|
||||
}
|
||||
|
||||
// (X >> Z) ^ (Y >> Z) -> (X^Y) >> Z for all shifts.
|
||||
if (ShiftInst *SI1 = dyn_cast<ShiftInst>(Op1)) {
|
||||
if (ShiftInst *SI0 = dyn_cast<ShiftInst>(Op0))
|
||||
if (SI0->getOpcode() == SI1->getOpcode() &&
|
||||
SI0->getOperand(1) == SI1->getOperand(1) &&
|
||||
(SI0->hasOneUse() || SI1->hasOneUse())) {
|
||||
Instruction *NewOp =
|
||||
InsertNewInstBefore(BinaryOperator::createXor(SI0->getOperand(0),
|
||||
SI1->getOperand(0),
|
||||
SI0->getName()), I);
|
||||
return new ShiftInst(SI1->getOpcode(), NewOp, SI1->getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user