From 8d96964e29e737b597e31af04db14570b87c6346 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 10 Mar 2003 23:06:50 +0000 Subject: [PATCH] Generalize not and neg comparison testers to allow constant to be considered not'able and neg'able. This allows optimization of this: int %test4(int %A, int %B) { %a = xor int %A, -1 %c = and int %a, 5 ; 5 = ~c2 %d = xor int %c, -1 ret int %d } into this: int %test4(int %A, int %B) { ; No predecessors! %c.demorgan = or int %A, -6 ; [#uses=1] ret int %c.demorgan } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5736 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 68 +++++++++++-------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index f66448257b3..b020a85dcc7 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -154,17 +154,37 @@ static bool SimplifyCommutative(BinaryOperator &I) { return Changed; } -// dyn_castNegInst - Given a 'sub' instruction, return the RHS of the -// instruction if the LHS is a constant zero (which is the 'negate' form). +// dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction +// if the LHS is a constant zero (which is the 'negate' form). // -static inline Value *dyn_castNegInst(Value *V) { - return BinaryOperator::isNeg(V) ? - BinaryOperator::getNegArgument(cast(V)) : 0; +static inline Value *dyn_castNegVal(Value *V) { + if (BinaryOperator::isNeg(V)) + return BinaryOperator::getNegArgument(cast(V)); + + // Constants can be considered to be negated values... + if (Constant *C = dyn_cast(V)) { + Constant *NC = *Constant::getNullValue(V->getType()) - *C; + assert(NC && "Couldn't constant fold a subtract!"); + return NC; + } + return 0; } -static inline Value *dyn_castNotInst(Value *V) { - return BinaryOperator::isNot(V) ? - BinaryOperator::getNotArgument(cast(V)) : 0; +static inline Value *dyn_castNotVal(Value *V) { + if (BinaryOperator::isNot(V)) + return BinaryOperator::getNotArgument(cast(V)); + + // Constants can be considered to be not'ed values... + if (ConstantIntegral *C = dyn_cast(V)) { + Constant *NC = *ConstantIntegral::getAllOnesValue(C->getType()) ^ *C; + assert(NC && "Couldn't constant fold an exclusive or!"); + return NC; + } + return 0; +} + +static bool isOnlyUse(Value *V) { + return V->use_size() == 1 || isa(V); } @@ -200,12 +220,13 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { return ReplaceInstUsesWith(I, LHS); // -A + B --> B - A - if (Value *V = dyn_castNegInst(LHS)) + if (Value *V = dyn_castNegVal(LHS)) return BinaryOperator::create(Instruction::Sub, RHS, V); // A + -B --> A - B - if (Value *V = dyn_castNegInst(RHS)) - return BinaryOperator::create(Instruction::Sub, LHS, V); + if (!isa(RHS)) + if (Value *V = dyn_castNegVal(RHS)) + return BinaryOperator::create(Instruction::Sub, LHS, V); // X*C + X --> X * (C+1) if (dyn_castFoldableMul(LHS) == RHS) { @@ -232,15 +253,8 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { if (Op0 == Op1) // sub X, X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // If this is a subtract instruction with a constant RHS, convert it to an add - // instruction of a negative constant - // - if (Constant *Op2 = dyn_cast(Op1)) - if (Constant *RHS = *Constant::getNullValue(I.getType()) - *Op2) // 0 - RHS - return BinaryOperator::create(Instruction::Add, Op0, RHS, I.getName()); - // If this is a 'B = x-(-A)', change to B = x+A... - if (Value *V = dyn_castNegInst(Op1)) + if (Value *V = dyn_castNegVal(Op1)) return BinaryOperator::create(Instruction::Add, Op0, V); // Replace (-1 - A) with (~A)... @@ -424,11 +438,11 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - Value *Op0NotVal = dyn_castNotInst(Op0); - Value *Op1NotVal = dyn_castNotInst(Op1); + Value *Op0NotVal = dyn_castNotVal(Op0); + Value *Op1NotVal = dyn_castNotVal(Op1); // (~A & ~B) == (~(A | B)) - Demorgan's Law - if (Op0->use_size() == 1 && Op1->use_size() == 1 && Op0NotVal && Op1NotVal) { + if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) { Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal, Op1NotVal,I.getName()+".demorgan", &I); @@ -456,12 +470,12 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op1); - if (Value *X = dyn_castNotInst(Op0)) // ~A | A == -1 + if (Value *X = dyn_castNotVal(Op0)) // ~A | A == -1 if (X == Op1) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); - if (Value *X = dyn_castNotInst(Op1)) // A | ~A == -1 + if (Value *X = dyn_castNotVal(Op1)) // A | ~A == -1 if (X == Op0) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); @@ -487,7 +501,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { // Is this a "NOT" instruction? if (Op1C->isAllOnesValue()) { // xor (xor X, -1), -1 = not (not X) = X - if (Value *X = dyn_castNotInst(Op0)) + if (Value *X = dyn_castNotVal(Op0)) return ReplaceInstUsesWith(I, X); // xor (setcc A, B), true = not (setcc A, B) = setncc A, B @@ -498,12 +512,12 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { } } - if (Value *X = dyn_castNotInst(Op0)) // ~A ^ A == -1 + if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1 if (X == Op1) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); - if (Value *X = dyn_castNotInst(Op1)) // A ^ ~A == -1 + if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1 if (X == Op0) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType()));