[llvm] r295573 - [InstSimplify] add nsw/nuw (xor X, signbit), signbit --> X

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 18 13:59:10 PST 2017


Author: spatel
Date: Sat Feb 18 15:59:09 2017
New Revision: 295573

URL: http://llvm.org/viewvc/llvm-project?rev=295573&view=rev
Log:
[InstSimplify] add nsw/nuw (xor X, signbit), signbit --> X

The change to InstCombine in:
https://reviews.llvm.org/D29729
...exposes this missing fold in InstSimplify, so adding this
first to avoid a regression.


Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Transforms/InstCombine/add.ll
    llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=295573&r1=295572&r2=295573&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sat Feb 18 15:59:09 2017
@@ -557,9 +557,19 @@ static Value *SimplifyAddInst(Value *Op0
     return Y;
 
   // X + ~X -> -1   since   ~X = -X-1
+  Type *Ty = Op0->getType();
   if (match(Op0, m_Not(m_Specific(Op1))) ||
       match(Op1, m_Not(m_Specific(Op0))))
-    return Constant::getAllOnesValue(Op0->getType());
+    return Constant::getAllOnesValue(Ty);
+
+  // add nsw/nuw (xor Y, signbit), signbit --> Y
+  // The no-wrapping add guarantees that the top bit will be set by the add.
+  // Therefore, the xor must be clearing the already set sign bit of Y.
+  Constant *SignBit =
+      ConstantInt::get(Ty, APInt::getSignBit(Ty->getScalarSizeInBits()));
+  if ((isNSW || isNUW) && match(Op1, m_Specific(SignBit)) &&
+      match(Op0, m_Xor(m_Value(Y), m_Specific(SignBit))))
+    return Y;
 
   /// i1 add -> xor.
   if (MaxRecurse && Op0->getType()->isIntegerTy(1))

Modified: llvm/trunk/test/Transforms/InstCombine/add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add.ll?rev=295573&r1=295572&r2=295573&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/add.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/add.ll Sat Feb 18 15:59:09 2017
@@ -244,7 +244,9 @@ define i32 @test19(i1 %C) {
   ret i32 %V
 }
 
-; Add of sign bit -> xor of sign bit.
+; This is an InstSimplify fold, but test it here to make sure that
+; InstCombine does not prevent the fold.
+; With NSW, add of sign bit -> or of sign bit.
 
 define i32 @test20(i32 %x) {
 ; CHECK-LABEL: @test20(

Modified: llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll?rev=295573&r1=295572&r2=295573&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll Sat Feb 18 15:59:09 2017
@@ -5,9 +5,7 @@
 
 define <2 x i32> @add_nsw_signbit(<2 x i32> %x) {
 ; CHECK-LABEL: @add_nsw_signbit(
-; CHECK-NEXT:    [[Y:%.*]] = xor <2 x i32> %x, <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT:    [[Z:%.*]] = add nsw <2 x i32> [[Y]], <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT:    ret <2 x i32> [[Z]]
+; CHECK-NEXT:    ret <2 x i32> %x
 ;
   %y = xor <2 x i32> %x, <i32 -2147483648, i32 -2147483648>
   %z = add nsw <2 x i32> %y, <i32 -2147483648, i32 -2147483648>
@@ -18,9 +16,7 @@ define <2 x i32> @add_nsw_signbit(<2 x i
 
 define <2 x i5> @add_nuw_signbit(<2 x i5> %x) {
 ; CHECK-LABEL: @add_nuw_signbit(
-; CHECK-NEXT:    [[Y:%.*]] = xor <2 x i5> %x, <i5 -16, i5 -16>
-; CHECK-NEXT:    [[Z:%.*]] = add nuw <2 x i5> [[Y]], <i5 -16, i5 -16>
-; CHECK-NEXT:    ret <2 x i5> [[Z]]
+; CHECK-NEXT:    ret <2 x i5> %x
 ;
   %y = xor <2 x i5> %x, <i5 -16, i5 -16>
   %z = add nuw <2 x i5> %y, <i5 -16, i5 -16>




More information about the llvm-commits mailing list