[InstCombine] Canonicalize ssub.sat to sadd.sat

Canonicalize ssub.sat(X, C) to ssub.sat(X, -C) if C is constant and
not signed minimum. This will help further optimizations to apply.

This change is part of https://reviews.llvm.org/D54534.

llvm-svn: 347772
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2dc80b2..a6921d7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2102,6 +2102,17 @@
         return BinaryOperator::CreateNSWSub(Arg0, Arg1);
       break;
     }
+
+    // ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN
+    // TODO: Support non-splat C.
+    const APInt *C;
+    if (IID == Intrinsic::ssub_sat && match(Arg1, m_APInt(C)) &&
+        !C->isMinSignedValue()) {
+      Value *NegVal = ConstantInt::get(II->getType(), -*C);
+      return replaceInstUsesWith(
+          *II, Builder.CreateBinaryIntrinsic(
+              Intrinsic::sadd_sat, Arg0, NegVal));
+    }
     break;
   }