[PATCH] D123118: [InstCombine] SimplifyDemandedUseBits - remove lshr node if we only demand known sign bit

Simon Pilgrim via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 04:54:02 PDT 2022


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

This is a lshr equivalent to D122340 <https://reviews.llvm.org/D122340> - if we don't demand any of the additional sign bits introduced by the ashr, the lshr can be treated as an ashr and we can remove the shift entirely if we only demand an already known sign bit.

If people prefer, I can simplify the code further, but I figured it made sense to try to keep it similar to the ashr fold for comparison.

Another step towards PR21929

https://alive2.llvm.org/ce/z/4EwrW5


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123118

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/Transforms/InstCombine/modulo.ll


Index: llvm/test/Transforms/InstCombine/modulo.ll
===================================================================
--- llvm/test/Transforms/InstCombine/modulo.ll
+++ llvm/test/Transforms/InstCombine/modulo.ll
@@ -4,9 +4,8 @@
 define i32 @PR21929(i32 %x) {
 ; CHECK-LABEL: @PR21929(
 ; CHECK-NEXT:    [[REM_I:%.*]] = srem i32 [[X:%.*]], 2
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[REM_I]], 30
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2
-; CHECK-NEXT:    [[RET_I:%.*]] = add nsw i32 [[TMP2]], [[REM_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[REM_I]], 2
+; CHECK-NEXT:    [[RET_I:%.*]] = add nsw i32 [[TMP1]], [[REM_I]]
 ; CHECK-NEXT:    ret i32 [[RET_I]]
 ;
   %rem.i = srem i32 %x, 2
@@ -19,9 +18,8 @@
 define <2 x i32> @PR21929_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @PR21929_vec(
 ; CHECK-NEXT:    [[REM_I:%.*]] = srem <2 x i32> [[X:%.*]], <i32 2, i32 2>
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[REM_I]], <i32 30, i32 30>
-; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 2, i32 2>
-; CHECK-NEXT:    [[RET_I:%.*]] = add nsw <2 x i32> [[TMP2]], [[REM_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[REM_I]], <i32 2, i32 2>
+; CHECK-NEXT:    [[RET_I:%.*]] = add nsw <2 x i32> [[TMP1]], [[REM_I]]
 ; CHECK-NEXT:    ret <2 x i32> [[RET_I]]
 ;
   %rem.i = srem <2 x i32> %x, <i32 2, i32 2>
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -616,6 +616,19 @@
     if (match(I->getOperand(1), m_APInt(SA))) {
       uint64_t ShiftAmt = SA->getLimitedValue(BitWidth-1);
 
+      // If we are just demanding the shifted sign bit and below, then this can
+      // be treated as an ASHR in disguise.
+      if (ShiftAmt == DemandedMask.countLeadingZeros()) {
+        // If we only want bits that already match the signbit then we don't
+        // need to shift.
+        unsigned NumHiDemandedBits =
+            BitWidth - DemandedMask.countTrailingZeros();
+        unsigned SignBits =
+            ComputeNumSignBits(I->getOperand(0), Depth + 1, CxtI);
+        if (SignBits >= NumHiDemandedBits)
+          return I->getOperand(0);
+      }
+
       // Unsigned shift right.
       APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D123118.420453.patch
Type: text/x-patch
Size: 2401 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220405/bf1c457b/attachment.bin>


More information about the llvm-commits mailing list