[InstCombine] X - 0 is equal to X, not undef
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 21 May 2015 23:04:21 +0000 (23:04 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 21 May 2015 23:04:21 +0000 (23:04 +0000)
A refactoring made @llvm.ssub.with.overflow.i32(i32 %X, i32 0) transform
into undef instead of %X.

This fixes PR23624.

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

lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/intrinsics.ll

index e979d76c1d0ed235a6d3d4a27382e15063f11d5f..09ab16511e7034bbb0bece36fa9c135501116731 100644 (file)
@@ -2141,13 +2141,11 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS,
   case OCF_SIGNED_ADD: {
     // X + undef -> undef
     if (isa<UndefValue>(RHS))
-      return SetResult(UndefValue::get(RHS->getType()),
-                       UndefValue::get(Builder->getInt1Ty()), false);
+      return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false);
 
-    if (ConstantInt *ConstRHS = dyn_cast<ConstantInt>(RHS))
-      // X + 0 -> {X, false}
-      if (ConstRHS->isZero())
-        return SetResult(LHS, Builder->getFalse(), false);
+    // X + 0 -> {X, false}
+    if (match(RHS, m_Zero()))
+      return SetResult(LHS, Builder->getFalse(), false);
 
     // We can strength reduce this signed add into a regular add if we can prove
     // that it will never overflow.
@@ -2160,16 +2158,16 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS,
   case OCF_UNSIGNED_SUB:
   case OCF_SIGNED_SUB: {
     // undef - X -> undef
+    if (isa<UndefValue>(LHS))
+      return SetResult(LHS, UndefValue::get(Builder->getInt1Ty()), false);
+
     // X - undef -> undef
-    if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS))
-      return SetResult(UndefValue::get(LHS->getType()),
-                       UndefValue::get(Builder->getInt1Ty()), false);
+    if (isa<UndefValue>(RHS))
+      return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false);
 
-    if (ConstantInt *ConstRHS = dyn_cast<ConstantInt>(RHS))
-      // X - 0 -> {X, false}
-      if (ConstRHS->isZero())
-        return SetResult(UndefValue::get(LHS->getType()), Builder->getFalse(),
-                         false);
+    // X - 0 -> {X, false}
+    if (match(RHS, m_Zero()))
+      return SetResult(LHS, Builder->getFalse(), false);
 
     if (OCF == OCF_SIGNED_SUB) {
       if (WillNotOverflowSignedSub(LHS, RHS, OrigI))
@@ -2194,19 +2192,15 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS,
   case OCF_SIGNED_MUL:
     // X * undef -> undef
     if (isa<UndefValue>(RHS))
-      return SetResult(UndefValue::get(LHS->getType()),
-                       UndefValue::get(Builder->getInt1Ty()), false);
-
-    if (ConstantInt *RHSI = dyn_cast<ConstantInt>(RHS)) {
-      // X * 0 -> {0, false}
-      if (RHSI->isZero())
-        return SetResult(Constant::getNullValue(RHS->getType()),
-                         Builder->getFalse(), false);
-
-      // X * 1 -> {X, false}
-      if (RHSI->equalsInt(1))
-        return SetResult(LHS, Builder->getFalse(), false);
-    }
+      return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false);
+
+    // X * 0 -> {0, false}
+    if (match(RHS, m_Zero()))
+      return SetResult(RHS, Builder->getFalse(), false);
+
+    // X * 1 -> {X, false}
+    if (match(RHS, m_One()))
+      return SetResult(LHS, Builder->getFalse(), false);
 
     if (OCF == OCF_SIGNED_MUL)
       if (WillNotOverflowSignedMul(LHS, RHS, OrigI))
index f9ccf51a621f9f3d759c31cc10d76c05cf24569b..974ee4395b897ca6394e539a80c634c97daf113c 100644 (file)
@@ -417,3 +417,11 @@ define %ov.result.32 @ssubtest_reorder(i8 %a) {
 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
 ; CHECK-NEXT:  ret %ov.result.32 %1
 }
+
+define %ov.result.32 @never_overflows_ssub(i32 %a) {
+  %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %a, i32 0)
+  ret %ov.result.32 %x
+; CHECK-LABEL: @never_overflows_ssub
+; CHECK-NEXT: %[[x:.*]] = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %a, 0
+; CHECK-NEXT:  ret %ov.result.32 %[[x]]
+}