From 7cbe2ebb212c5cacbe4771c75f0515c389a905e5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 15 Jun 2007 06:23:19 +0000 Subject: [PATCH] Generalize many transforms to work on ~ of vectors in addition to ~ of integer ops. This implements Transforms/InstCombine/and-or-not.ll test3/test4, and finishes off PR1510 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37589 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 546f0f2709d..70bd8a80818 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2050,9 +2050,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { return BinaryOperator::createMul(LHS, AddOne(C2)); // X + ~X --> -1 since ~X = -X-1 - if (dyn_castNotVal(LHS) == RHS || - dyn_castNotVal(RHS) == LHS) - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + if (dyn_castNotVal(LHS) == RHS || dyn_castNotVal(RHS) == LHS) + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // (A & C1)+(B & C2) --> (A & C1)|(B & C2) iff C1&C2 == 0 @@ -3717,7 +3716,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (isa(Op1)) // X | undef -> -1 - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // or X, X = X if (Op0 == Op1) @@ -3912,16 +3911,14 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1 if (A == Op1) // ~A | A == -1 - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); } else { A = 0; } // Note, A is still live here! if (match(Op1, m_Not(m_Value(B)))) { // Op0 | ~B if (Op0 == B) - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // (~A | ~B) == (~(A & B)) - De Morgan's Law if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) { @@ -4135,6 +4132,29 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X } + // Is this a ~ operation? + if (Value *NotOp = dyn_castNotVal(&I)) { + // ~(~X & Y) --> (X | ~Y) - De Morgan's Law + // ~(~X | Y) === (X & ~Y) - De Morgan's Law + if (BinaryOperator *Op0I = dyn_cast(NotOp)) { + if (Op0I->getOpcode() == Instruction::And || + Op0I->getOpcode() == Instruction::Or) { + if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); + if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { + Instruction *NotY = + BinaryOperator::createNot(Op0I->getOperand(1), + Op0I->getOperand(1)->getName()+".not"); + InsertNewInstBefore(NotY, I); + if (Op0I->getOpcode() == Instruction::And) + return BinaryOperator::createOr(Op0NotVal, NotY); + else + return BinaryOperator::createAnd(Op0NotVal, NotY); + } + } + } + } + + if (ConstantInt *RHS = dyn_cast(Op1)) { // xor (icmp A, B), true = not (icmp A, B) = !icmp A, B if (ICmpInst *ICI = dyn_cast(Op0)) @@ -4151,23 +4171,6 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { ConstantInt::get(I.getType(), 1)); return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS); } - - // ~(~X & Y) --> (X | ~Y) - De Morgan's Law - // ~(~X | Y) === (X & ~Y) - De Morgan's Law - if ((Op0I->getOpcode() == Instruction::And || - Op0I->getOpcode() == Instruction::Or) && RHS->isAllOnesValue()) { - if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); - if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { - Instruction *NotY = - BinaryOperator::createNot(Op0I->getOperand(1), - Op0I->getOperand(1)->getName()+".not"); - InsertNewInstBefore(NotY, I); - if (Op0I->getOpcode() == Instruction::And) - return BinaryOperator::createOr(Op0NotVal, NotY); - else - return BinaryOperator::createAnd(Op0NotVal, NotY); - } - } if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) if (Op0I->getOpcode() == Instruction::Add) { @@ -4212,12 +4215,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1 if (X == Op1) - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1 if (X == Op0) - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); BinaryOperator *Op1I = dyn_cast(Op1); @@ -7092,7 +7094,7 @@ static Constant *GetSelectFoldableConstant(Instruction *I) { case Instruction::AShr: return Constant::getNullValue(I->getType()); case Instruction::And: - return ConstantInt::getAllOnesValue(I->getType()); + return Constant::getAllOnesValue(I->getType()); case Instruction::Mul: return ConstantInt::get(I->getType(), 1); }