[llvm] r302659 - [InstCombine] add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed May 10 06:56:52 PDT 2017


Author: spatel
Date: Wed May 10 08:56:52 2017
New Revision: 302659

URL: http://llvm.org/viewvc/llvm-project?rev=302659&view=rev
Log:
[InstCombine] add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1

This is another step towards favoring 'not' ops over random 'xor' in IR:
https://bugs.llvm.org/show_bug.cgi?id=32706

This transformation may have occurred in longer IR sequences using computeKnownBits,
but that could be much more expensive to calculate.

As the scalar result shows, we do not currently favor 'not' in all cases. The 'not'
created by the transform is transformed again (unnecessarily). Vectors don't have
this problem because vectors are (wrongly) excluded from several other combines.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/trunk/test/Transforms/InstCombine/add.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=302659&r1=302658&r2=302659&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Wed May 10 08:56:52 2017
@@ -1079,6 +1079,16 @@ static Instruction *foldAddWithConstant(
     return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty);
   }
 
+  // Shifts and add used to flip and mask off the low bit:
+  // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1
+  const APInt *C3;
+  if (*C == 1 && match(Op0, m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)),
+                                            m_APInt(C3)))) &&
+      C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
+    Value *NotX = Builder.CreateNot(X);
+    return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
+  }
+
   return nullptr;
 }
 

Modified: llvm/trunk/test/Transforms/InstCombine/add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add.ll?rev=302659&r1=302658&r2=302659&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/add.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/add.ll Wed May 10 08:56:52 2017
@@ -31,9 +31,8 @@ define <2 x i32> @select_0_or_1_from_boo
 
 define i32 @flip_and_mask(i32 %x) {
 ; CHECK-LABEL: @flip_and_mask(
-; CHECK-NEXT:    [[SHL:%.*]] = shl i32 %x, 31
-; CHECK-NEXT:    [[SHR:%.*]] = ashr exact i32 [[SHL]], 31
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[SHR]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %x, 1
+; CHECK-NEXT:    [[INC:%.*]] = xor i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i32 [[INC]]
 ;
   %shl = shl i32 %x, 31
@@ -44,9 +43,8 @@ define i32 @flip_and_mask(i32 %x) {
 
 define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
 ; CHECK-LABEL: @flip_and_mask_splat(
-; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i8> %x, <i8 7, i8 7>
-; CHECK-NEXT:    [[SHR:%.*]] = ashr exact <2 x i8> [[SHL]], <i8 7, i8 7>
-; CHECK-NEXT:    [[INC:%.*]] = add nsw <2 x i8> [[SHR]], <i8 1, i8 1>
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> %x, <i8 1, i8 1>
+; CHECK-NEXT:    [[INC:%.*]] = and <2 x i8> [[TMP1]], <i8 1, i8 1>
 ; CHECK-NEXT:    ret <2 x i8> [[INC]]
 ;
   %shl = shl <2 x i8> %x, <i8 7, i8 7>




More information about the llvm-commits mailing list