Move some those Xor simplifications which don't require creating new

instructions out of InstCombine and into InstructionSimplify.  While
there, introduce an m_AllOnes pattern to simplify matching with integers
and vectors with all bits equal to one.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119536 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2010-11-17 18:52:15 +00:00
parent 89e14c7579
commit 2b749870d0
4 changed files with 100 additions and 62 deletions

View File

@ -37,6 +37,11 @@ namespace llvm {
Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,

View File

@ -96,9 +96,23 @@ struct one_ty {
}
};
/// m_One() - Match a an integer 1.
/// m_One() - Match an integer 1.
inline one_ty m_One() { return one_ty(); }
struct all_ones_ty {
template<typename ITy>
bool match(ITy *V) {
if (const ConstantInt *C = dyn_cast<ConstantInt>(V))
return C->isAllOnesValue();
if (const ConstantVector *C = dyn_cast<ConstantVector>(V))
return C->isAllOnesValue();
return false;
}
};
/// m_AllOnes() - Match an integer or vector with all bits set to true.
inline all_ones_ty m_AllOnes() { return all_ones_ty(); }
template<typename Class>
struct bind_ty {

View File

@ -276,23 +276,13 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD,
if (Op0 == Op1)
return Op0;
// X & <0,0> = <0,0>
if (isa<ConstantAggregateZero>(Op1))
// X & 0 = 0
if (match(Op1, m_Zero()))
return Op1;
// X & <-1,-1> = X
if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1))
if (CP->isAllOnesValue())
return Op0;
if (ConstantInt *Op1CI = dyn_cast<ConstantInt>(Op1)) {
// X & 0 = 0
if (Op1CI->isZero())
return Op1CI;
// X & -1 = X
if (Op1CI->isAllOnesValue())
return Op0;
}
// X & -1 = X
if (match(Op1, m_AllOnes()))
return Op0;
// A & ~A = ~A & A = 0
Value *A, *B;
@ -365,23 +355,13 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD,
if (Op0 == Op1)
return Op0;
// X | <0,0> = X
if (isa<ConstantAggregateZero>(Op1))
// X | 0 = X
if (match(Op1, m_Zero()))
return Op0;
// X | <-1,-1> = <-1,-1>
if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1))
if (CP->isAllOnesValue())
return Op1;
if (ConstantInt *Op1CI = dyn_cast<ConstantInt>(Op1)) {
// X | 0 = X
if (Op1CI->isZero())
return Op0;
// X | -1 = -1
if (Op1CI->isAllOnesValue())
return Op1CI;
}
// X | -1 = -1
if (match(Op1, m_AllOnes()))
return Op1;
// A | ~A = ~A | A = -1
Value *A, *B;
@ -431,6 +411,71 @@ Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD,
return ::SimplifyOrInst(Op0, Op1, TD, DT, RecursionLimit);
}
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD,
const DominatorTree *DT, unsigned MaxRecurse) {
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
Constant *Ops[] = { CLHS, CRHS };
return ConstantFoldInstOperands(Instruction::Xor, CLHS->getType(),
Ops, 2, TD);
}
// Canonicalize the constant to the RHS.
std::swap(Op0, Op1);
}
// A ^ undef -> undef
if (isa<UndefValue>(Op1))
return UndefValue::get(Op0->getType());
// A ^ 0 = A
if (match(Op1, m_Zero()))
return Op0;
// A ^ A = 0
if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
// A ^ ~A = ~A ^ A = -1
Value *A, *B;
if ((match(Op0, m_Not(m_Value(A))) && A == Op1) ||
(match(Op1, m_Not(m_Value(A))) && A == Op0))
return Constant::getAllOnesValue(Op0->getType());
// (A ^ B) ^ A = B
if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
(A == Op1 || B == Op1))
return A == Op1 ? B : A;
// A ^ (A ^ B) = B
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
(A == Op0 || B == Op0))
return A == Op0 ? B : A;
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (MaxRecurse && (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)))
if (Value *V = ThreadBinOpOverSelect(Instruction::Xor, Op0, Op1, TD, DT,
MaxRecurse-1))
return V;
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (MaxRecurse && (isa<PHINode>(Op0) || isa<PHINode>(Op1)))
if (Value *V = ThreadBinOpOverPHI(Instruction::Xor, Op0, Op1, TD, DT,
MaxRecurse-1))
return V;
return 0;
}
Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD,
const DominatorTree *DT) {
return ::SimplifyXorInst(Op0, Op1, TD, DT, RecursionLimit);
}
static const Type *GetCompareTy(Value *Op) {
return CmpInst::makeCmpResultType(Op->getType());
}
@ -774,6 +819,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
case Instruction::Or:
Result = SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD, DT);
break;
case Instruction::Xor:
Result = SimplifyXorInst(I->getOperand(0), I->getOperand(1), TD, DT);
break;
case Instruction::ICmp:
Result = SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(),
I->getOperand(0), I->getOperand(1), TD, DT);

View File

@ -1976,25 +1976,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
bool Changed = SimplifyAssociativeOrCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
if (isa<UndefValue>(Op1)) {
if (isa<UndefValue>(Op0))
// Handle undef ^ undef -> 0 special case. This is a common
// idiom (misuse).
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
return ReplaceInstUsesWith(I, Op1); // X ^ undef -> undef
}
if (Value *V = SimplifyXorInst(Op0, Op1, TD))
return ReplaceInstUsesWith(I, V);
// xor X, X = 0
if (Op0 == Op1)
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (SimplifyDemandedInstructionBits(I))
return &I;
if (I.getType()->isVectorTy())
if (isa<ConstantAggregateZero>(Op1))
return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X
// Is this a ~ operation?
if (Value *NotOp = dyn_castNotVal(&I)) {
@ -2113,15 +2101,6 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
return NV;
}
if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1
if (X == Op1)
return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));
if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1
if (X == Op0)
return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));
BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1);
if (Op1I) {
Value *A, *B;
@ -2134,10 +2113,6 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
I.swapOperands(); // Simplified below.
std::swap(Op0, Op1);
}
} else if (match(Op1I, m_Xor(m_Specific(Op0), m_Value(B)))) {
return ReplaceInstUsesWith(I, B); // A^(A^B) == B
} else if (match(Op1I, m_Xor(m_Value(A), m_Specific(Op0)))) {
return ReplaceInstUsesWith(I, A); // A^(B^A) == B
} else if (match(Op1I, m_And(m_Value(A), m_Value(B))) &&
Op1I->hasOneUse()){
if (A == Op0) { // A^(A&B) -> A^(B&A)
@ -2160,10 +2135,6 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
std::swap(A, B);
if (B == Op1) // (A|B)^B == A & ~B
return BinaryOperator::CreateAnd(A, Builder->CreateNot(Op1, "tmp"));
} else if (match(Op0I, m_Xor(m_Specific(Op1), m_Value(B)))) {
return ReplaceInstUsesWith(I, B); // (A^B)^A == B
} else if (match(Op0I, m_Xor(m_Value(A), m_Specific(Op1)))) {
return ReplaceInstUsesWith(I, A); // (B^A)^A == B
} else if (match(Op0I, m_And(m_Value(A), m_Value(B))) &&
Op0I->hasOneUse()){
if (A == Op1) // (A&B)^A -> (B&A)^A