InstCombine: (X ^ signbit) + C -> X + (signbit ^ C)
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 6 May 2013 21:21:31 +0000 (21:21 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 6 May 2013 21:21:31 +0000 (21:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181249 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/sub-xor.ll

index 1aa51d06cb09547e9f28f4ea4a8c7e7dfb8481d2..166f8dfdb4a1830b5559ba5c8a4982955eec3f82 100644 (file)
@@ -974,6 +974,11 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
           return BinaryOperator::CreateSub(ConstantExpr::getAdd(XorRHS, CI),
                                            XorLHS);
       }
+      // (X + signbit) + C could have gotten canonicalized to (X ^ signbit) + C,
+      // transform them into (X + (signbit ^ C))
+      if (XorRHS->getValue().isSignBit())
+          return BinaryOperator::CreateAdd(XorLHS,
+                                           ConstantExpr::getXor(XorRHS, CI));
     }
   }
 
index 279e4aca9de4f02fa0b2a754c01bb50322b69f2b..1d14852bc803983c4e92fcdebed173c6c5134f0e 100644 (file)
@@ -35,3 +35,13 @@ define i32 @test3(i32 %x) nounwind {
 ; CHECK-NEXT: sub i32 73, %and
 ; CHECK-NEXT: ret
 }
+
+define i32 @test4(i32 %x) nounwind {
+  %sub = xor i32 %x, 2147483648
+  %add = add i32 %sub, 42
+  ret i32 %add
+
+; CHECK: @test4
+; CHECK-NEXT: add i32 %x, -2147483606
+; CHECK-NEXT: ret
+}