Implement InstCombine/add.ll:test20
authorChris Lattner <sabre@nondot.org>
Sat, 10 Apr 2004 22:01:55 +0000 (22:01 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 10 Apr 2004 22:01:55 +0000 (22:01 +0000)
Canonicalize add of sign bit constant into a xor

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12819 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 944b83c520a1122c008e6aa928feaf6819038051..23d0f5ffcc78f78f4f9b6431cbadd085fc2a9dd1 100644 (file)
@@ -540,10 +540,20 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   bool Changed = SimplifyCommutative(I);
   Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
 
-  // X + 0 --> X
-  if (!I.getType()->isFloatingPoint() &&    // -0 + +0 = +0, so it's not a noop
-      RHS == Constant::getNullValue(I.getType()))
-    return ReplaceInstUsesWith(I, LHS);
+  if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
+    // X + 0 --> X
+    if (!I.getType()->isFloatingPoint() && // -0 + +0 = +0, so it's not a noop
+        RHSC->isNullValue())
+      return ReplaceInstUsesWith(I, LHS);
+    
+    // X + (signbit) --> X ^ signbit
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
+      unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+      uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1;
+      if (Val == (1ULL << NumBits-1))
+        return BinaryOperator::create(Instruction::Xor, LHS, RHS);
+    }
+  }
 
   // X + X --> X << 1
   if (I.getType()->isInteger())