[PATCH] D25785: [InstSimplify] folds for negation of sign-bit

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 19 14:33:07 PDT 2016


This revision was automatically updated to reflect the committed changes.
Closed by commit rL284649: [InstSimplify] fold negation of sign-bit (authored by spatel).

Changed prior to commit:
  https://reviews.llvm.org/D25785?vs=75187&id=75230#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25785

Files:
  llvm/trunk/lib/Analysis/InstructionSimplify.cpp
  llvm/trunk/test/Transforms/InstSimplify/negate.ll


Index: llvm/trunk/test/Transforms/InstSimplify/negate.ll
===================================================================
--- llvm/trunk/test/Transforms/InstSimplify/negate.ll
+++ llvm/trunk/test/Transforms/InstSimplify/negate.ll
@@ -19,20 +19,16 @@
 
 define i8 @negate_zero_or_minsigned_nsw(i8 %x) {
 ; CHECK-LABEL: @negate_zero_or_minsigned_nsw(
-; CHECK-NEXT:    [[SIGNBIT:%.*]] = and i8 %x, -128
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[SIGNBIT]]
-; CHECK-NEXT:    ret i8 [[NEG]]
+; CHECK-NEXT:    ret i8 0
 ;
   %signbit = and i8 %x, 128
   %neg = sub nsw i8 0, %signbit
   ret i8 %neg
 }
 
 define <2 x i8> @negate_zero_or_minsigned_nsw_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @negate_zero_or_minsigned_nsw_vec(
-; CHECK-NEXT:    [[SIGNBIT:%.*]] = shl <2 x i8> %x, <i8 7, i8 7>
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw <2 x i8> zeroinitializer, [[SIGNBIT]]
-; CHECK-NEXT:    ret <2 x i8> [[NEG]]
+; CHECK-NEXT:    ret <2 x i8> zeroinitializer
 ;
   %signbit = shl <2 x i8> %x, <i8 7, i8 7>
   %neg = sub nsw <2 x i8> zeroinitializer, %signbit
@@ -42,8 +38,7 @@
 define i8 @negate_zero_or_minsigned(i8 %x) {
 ; CHECK-LABEL: @negate_zero_or_minsigned(
 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = shl i8 %x, 7
-; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[SIGNBIT]]
-; CHECK-NEXT:    ret i8 [[NEG]]
+; CHECK-NEXT:    ret i8 [[SIGNBIT]]
 ;
   %signbit = shl i8 %x, 7
   %neg = sub i8 0, %signbit
@@ -53,8 +48,7 @@
 define <2 x i8> @negate_zero_or_minsigned_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @negate_zero_or_minsigned_vec(
 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = and <2 x i8> %x, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[SIGNBIT]]
-; CHECK-NEXT:    ret <2 x i8> [[NEG]]
+; CHECK-NEXT:    ret <2 x i8> [[SIGNBIT]]
 ;
   %signbit = and <2 x i8> %x, <i8 128, i8 128>
   %neg = sub <2 x i8> zeroinitializer, %signbit
Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp
@@ -680,9 +680,26 @@
   if (Op0 == Op1)
     return Constant::getNullValue(Op0->getType());
 
-  // 0 - X -> 0 if the sub is NUW.
-  if (isNUW && match(Op0, m_Zero()))
-    return Op0;
+  // Is this a negation?
+  if (match(Op0, m_Zero())) {
+    // 0 - X -> 0 if the sub is NUW.
+    if (isNUW)
+      return Op0;
+
+    unsigned BitWidth = Op1->getType()->getScalarSizeInBits();
+    APInt KnownZero(BitWidth, 0);
+    APInt KnownOne(BitWidth, 0);
+    computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+    if (KnownZero == ~APInt::getSignBit(BitWidth)) {
+      // Op1 is either 0 or the minimum signed value. If the sub is NSW, then
+      // Op1 must be 0 because negating the minimum signed value is undefined.
+      if (isNSW)
+        return Op0;
+
+      // 0 - X -> X if X is 0 or the minimum signed value.
+      return Op1;
+    }
+  }
 
   // (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
   // For example, (X + Y) - Y -> X; (Y + X) - Y -> X


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25785.75230.patch
Type: text/x-patch
Size: 3078 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161019/e589ae54/attachment.bin>


More information about the llvm-commits mailing list