[PATCH] D119715: [InstCombine] Fold sub(0,and(lshr(X,C),1)) --> ashr(shl(X,(BW-1)-C),BW-1) (PR53610)

Simon Pilgrim via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 14 06:32:20 PST 2022


RKSimon created this revision.
RKSimon added reviewers: spatel, lebedev.ri, xbolva00.
Herald added a subscriber: hiraditya.
RKSimon requested review of this revision.
Herald added a project: LLVM.

As noted on PR53610, we can fold a 'bit splat' negation of a shifted bitmask pattern into a pair of shifts.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119715

Files:
  llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
  llvm/test/Transforms/InstCombine/negated-bitmask.ll


Index: llvm/test/Transforms/InstCombine/negated-bitmask.ll
===================================================================
--- llvm/test/Transforms/InstCombine/negated-bitmask.ll
+++ llvm/test/Transforms/InstCombine/negated-bitmask.ll
@@ -5,10 +5,9 @@
 
 define i8 @neg_mask1_lshr(i8 %a0) {
 ; CHECK-LABEL: @neg_mask1_lshr(
-; CHECK-NEXT:    [[SHIFT:%.*]] = lshr i8 [[A0:%.*]], 3
-; CHECK-NEXT:    [[MASK:%.*]] = and i8 [[SHIFT]], 1
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[MASK]]
-; CHECK-NEXT:    ret i8 [[NEG]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[A0:%.*]], 4
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr i8 [[TMP1]], 7
+; CHECK-NEXT:    ret i8 [[TMP2]]
 ;
   %shift = lshr i8 %a0, 3
   %mask = and i8 %shift, 1
@@ -18,10 +17,9 @@
 
 define <4 x i32> @neg_mask1_lshr_vector_uniform(<4 x i32> %a0) {
 ; CHECK-LABEL: @neg_mask1_lshr_vector_uniform(
-; CHECK-NEXT:    [[SHIFT:%.*]] = lshr <4 x i32> [[A0:%.*]], <i32 3, i32 3, i32 3, i32 3>
-; CHECK-NEXT:    [[MASK:%.*]] = and <4 x i32> [[SHIFT]], <i32 1, i32 1, i32 1, i32 1>
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw <4 x i32> zeroinitializer, [[MASK]]
-; CHECK-NEXT:    ret <4 x i32> [[NEG]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> [[A0:%.*]], <i32 28, i32 28, i32 28, i32 28>
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr <4 x i32> [[TMP1]], <i32 31, i32 31, i32 31, i32 31>
+; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
 ;
   %shift = lshr <4 x i32> %a0, <i32 3, i32 3, i32 3, i32 3>
   %mask = and <4 x i32> %shift, <i32 1, i32 1, i32 1, i32 1>
@@ -31,10 +29,9 @@
 
 define <4 x i32> @neg_mask1_lshr_vector_nonuniform(<4 x i32> %a0) {
 ; CHECK-LABEL: @neg_mask1_lshr_vector_nonuniform(
-; CHECK-NEXT:    [[SHIFT:%.*]] = lshr <4 x i32> [[A0:%.*]], <i32 3, i32 4, i32 5, i32 6>
-; CHECK-NEXT:    [[MASK:%.*]] = and <4 x i32> [[SHIFT]], <i32 1, i32 1, i32 1, i32 1>
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw <4 x i32> zeroinitializer, [[MASK]]
-; CHECK-NEXT:    ret <4 x i32> [[NEG]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> [[A0:%.*]], <i32 28, i32 27, i32 26, i32 25>
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr <4 x i32> [[TMP1]], <i32 31, i32 31, i32 31, i32 31>
+; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
 ;
   %shift = lshr <4 x i32> %a0, <i32 3, i32 4, i32 5, i32 6>
   %mask = and <4 x i32> %shift, <i32 1, i32 1, i32 1, i32 1>
Index: llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -185,6 +185,17 @@
       return Builder.CreateAdd(X, ConstantInt::get(X->getType(), 1),
                                I->getName() + ".neg");
     break;
+  case Instruction::And:
+    Constant *ShAmt;
+    std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
+    // sub(0,and(lshr(X,C),1)) --> ashr(shl(X,(BW-1)-C),BW-1)
+    if (match(Ops[1], m_One()) &&
+        match(Ops[0], m_LShr(m_Value(X), m_Constant(ShAmt)))) {
+      Constant *Ofs = ConstantInt::get(X->getType(), BitWidth - 1);
+      Value *NewShAmt = Builder.CreateSub(Ofs, ShAmt);
+      return Builder.CreateAShr(Builder.CreateShl(X, NewShAmt), Ofs);
+    }
+    break;
   case Instruction::AShr:
   case Instruction::LShr: {
     // Right-shift sign bit smear is negatible.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119715.408398.patch
Type: text/x-patch
Size: 3287 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220214/179dabf6/attachment.bin>


More information about the llvm-commits mailing list