summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-06-15 06:23:19 +0000
committerChris Lattner <sabre@nondot.org>2007-06-15 06:23:19 +0000
commit373389260fd6032ba1200e1883577bad4d159827 (patch)
tree6038b150b262c3347f8bcd56b89bf00055d889d8 /llvm/lib/Transforms
parent9923af42cfc25ec8231541977aff279778b5774c (diff)
downloadbcm5719-llvm-373389260fd6032ba1200e1883577bad4d159827.tar.gz
bcm5719-llvm-373389260fd6032ba1200e1883577bad4d159827.zip
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 llvm-svn: 37589
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp60
1 files changed, 31 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 546f0f2709d..70bd8a80818 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/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<UndefValue>(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<BinaryOperator>(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<ConstantInt>(Op1)) {
// xor (icmp A, B), true = not (icmp A, B) = !icmp A, B
if (ICmpInst *ICI = dyn_cast<ICmpInst>(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<ConstantInt>(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<BinaryOperator>(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);
}
OpenPOWER on IntegriCloud