refactor matches for De Morgan's Laws; NFCI

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247061 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel 2015-09-08 20:14:13 +00:00
parent 55ec9f281c
commit 8a6f3c5646

View File

@ -1200,6 +1200,34 @@ Value *InstCombiner::FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS) {
return nullptr; return nullptr;
} }
/// Match De Morgan's Laws:
/// (~A & ~B) == (~(A | B))
/// (~A | ~B) == (~(A & B))
static Instruction *matchDeMorgansLaws(BinaryOperator &I,
InstCombiner::BuilderTy *Builder) {
auto Opcode = I.getOpcode();
assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
"Trying to match De Morgan's Laws with something other than and/or");
Value *Op0 = I.getOperand(0);
Value *Op1 = I.getOperand(1);
// TODO: Use pattern matchers instead of dyn_cast.
if (Value *Op0NotVal = dyn_castNotVal(Op0))
if (Value *Op1NotVal = dyn_castNotVal(Op1))
if (Op0->hasOneUse() && Op1->hasOneUse()) {
// Flip the logic operation.
if (Opcode == Instruction::And)
Opcode = Instruction::Or;
else
Opcode = Instruction::And;
Value *LogicOp = Builder->CreateBinOp(Opcode, Op0NotVal, Op1NotVal,
I.getName() + ".demorgan");
return BinaryOperator::CreateNot(LogicOp);
}
return nullptr;
}
Instruction *InstCombiner::visitAnd(BinaryOperator &I) { Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
bool Changed = SimplifyAssociativeOrCommutative(I); bool Changed = SimplifyAssociativeOrCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@ -1330,15 +1358,8 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
return NV; return NV;
} }
if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))
// (~A & ~B) == (~(A | B)) - De Morgan's Law return DeMorgan;
if (Value *Op0NotVal = dyn_castNotVal(Op0))
if (Value *Op1NotVal = dyn_castNotVal(Op1))
if (Op0->hasOneUse() && Op1->hasOneUse()) {
Value *Or = Builder->CreateOr(Op0NotVal, Op1NotVal,
I.getName()+".demorgan");
return BinaryOperator::CreateNot(Or);
}
{ {
Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr; Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;
@ -2360,14 +2381,8 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (match(Op0, m_And(m_Or(m_Specific(Op1), m_Value(C)), m_Value(A)))) if (match(Op0, m_And(m_Or(m_Specific(Op1), m_Value(C)), m_Value(A))))
return BinaryOperator::CreateOr(Op1, Builder->CreateAnd(A, C)); return BinaryOperator::CreateOr(Op1, Builder->CreateAnd(A, C));
// (~A | ~B) == (~(A & B)) - De Morgan's Law if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))
if (Value *Op0NotVal = dyn_castNotVal(Op0)) return DeMorgan;
if (Value *Op1NotVal = dyn_castNotVal(Op1))
if (Op0->hasOneUse() && Op1->hasOneUse()) {
Value *And = Builder->CreateAnd(Op0NotVal, Op1NotVal,
I.getName()+".demorgan");
return BinaryOperator::CreateNot(And);
}
// Canonicalize xor to the RHS. // Canonicalize xor to the RHS.
bool SwappedForXor = false; bool SwappedForXor = false;