Minor cleanup, plus implement InstCombine/xor.ll:test17
authorChris Lattner <sabre@nondot.org>
Tue, 4 Nov 2003 23:50:51 +0000 (23:50 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 4 Nov 2003 23:50:51 +0000 (23:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9711 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 88026c30d5506e5c42ba5df50a816d069bd53886..dafd7568f8aa3cad92f671771c005f2e093ce60a 100644 (file)
@@ -1000,23 +1000,37 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
         if (RHS == ConstantBool::True && SCI->hasOneUse())
           return new SetCondInst(SCI->getInverseCondition(),
                                  SCI->getOperand(0), SCI->getOperand(1));
+
+      // ~(c-X) == X-(c-1) == X+(-c+1)
+      if (Op0I->getOpcode() == Instruction::Sub && RHS->isAllOnesValue() &&
+          isa<Constant>(Op0I->getOperand(0))) {
+        Constant *ConstantRHS = *-*cast<Constant>(Op0I->getOperand(0)) +
+                                *ConstantInt::get(I.getType(), 1);
+        return BinaryOperator::create(Instruction::Add, Op0I->getOperand(1),
+                                      ConstantRHS);
+      }
           
       if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
-        if (Op0I->getOpcode() == Instruction::Add) {
+        switch (Op0I->getOpcode()) {
+        case Instruction::Add:
           // ~(X-c) --> (-c-1)-X
           if (RHS->isAllOnesValue()) 
             return BinaryOperator::create(Instruction::Sub,
                                           *-*Op0CI -
                                               *ConstantInt::get(I.getType(), 1),
                                           Op0I->getOperand(0));
-        } else if (Op0I->getOpcode() == Instruction::And) {
+          break;
+        case Instruction::And:
           // (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
           if ((*RHS & *Op0CI)->isNullValue())
             return BinaryOperator::create(Instruction::Or, Op0, RHS);
-        } else if (Op0I->getOpcode() == Instruction::Or) {
+          break;
+        case Instruction::Or:
           // (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
           if ((*RHS & *Op0CI) == RHS)
             return BinaryOperator::create(Instruction::And, Op0, ~*RHS);
+          break;
+        default: break;
         }
     }
   }