From 2e9433d42da2a7bc756b7c1cb4a654dc906a7e7e Mon Sep 17 00:00:00 2001
From: Sanjay Patel <spatel@rotateright.com>
Date: Sat, 16 Jul 2016 18:29:26 +0000
Subject: [PATCH] [InstCombine] allow X + signbit --> X ^ signbit for vector
 splats

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275691 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Transforms/InstCombine/InstCombineAddSub.cpp | 13 ++++++++++---
 test/Transforms/InstCombine/apint-add.ll         |  2 +-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index f94a65a75f0..221a2200717 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1042,12 +1042,16 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   if (Value *V = SimplifyUsingDistributiveLaws(I))
     return replaceInstUsesWith(I, V);
 
-  if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
+  const APInt *Val;
+  if (match(RHS, m_APInt(Val))) {
     // X + (signbit) --> X ^ signbit
-    const APInt &Val = CI->getValue();
-    if (Val.isSignBit())
+    if (Val->isSignBit())
       return BinaryOperator::CreateXor(LHS, RHS);
+  }
 
+  // FIXME: Use the match above instead of dyn_cast to allow these transforms
+  // for splat vectors.
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
     // See if SimplifyDemandedBits can simplify this.  This handles stuff like
     // (X & 254)+1 -> (X&254)|1
     if (SimplifyDemandedInstructionBits(I))
@@ -1149,6 +1153,9 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
       return BinaryOperator::CreateSub(SubOne(CRHS), X);
   }
 
+  // FIXME: We already did a check for ConstantInt RHS above this.
+  // FIXME: Is this pattern covered by another fold? No regression tests fail on
+  // removal.
   if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
     // (X & FF00) + xx00  -> (X+xx00) & FF00
     Value *X;
diff --git a/test/Transforms/InstCombine/apint-add.ll b/test/Transforms/InstCombine/apint-add.ll
index f27af7b60cc..6740ae66aef 100644
--- a/test/Transforms/InstCombine/apint-add.ll
+++ b/test/Transforms/InstCombine/apint-add.ll
@@ -36,7 +36,7 @@ define i15 @test3(i15 %x) {
 ; X + signbit --> X ^ signbit
 define <2 x i5> @test3vec(<2 x i5> %x) {
 ; CHECK-LABEL: @test3vec(
-; CHECK-NEXT:    [[Y:%.*]] = add <2 x i5> %x, <i5 -16, i5 -16>
+; CHECK-NEXT:    [[Y:%.*]] = xor <2 x i5> %x, <i5 -16, i5 -16>
 ; CHECK-NEXT:    ret <2 x i5> [[Y]]
 ;
   %y = add <2 x i5> %x, <i5 16, i5 16>
-- 
2.40.0