mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-03 10:19:25 +00:00
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:
parent
55ec9f281c
commit
8a6f3c5646
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user