[PATCH] D91364: [InstCombine] fold low-bit mask of sext-in-reg

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 12 09:35:28 PST 2020


spatel created this revision.
spatel added reviewers: lebedev.ri, craig.topper, Bhramar.vatsa.
Herald added subscribers: hiraditya, mcrosier.
Herald added a project: LLVM.
spatel requested review of this revision.

This is an alternative to D91343 <https://reviews.llvm.org/D91343>. I do not have stats for how often the shl+ashr pattern (sext-in-reg) occurs, but we have an SDAG node for that operation, so it seems common enough to warrant a dedicated fold for this pattern:
https://rise4fun.com/Alive/vI9


https://reviews.llvm.org/D91364

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/and.ll


Index: llvm/test/Transforms/InstCombine/and.ll
===================================================================
--- llvm/test/Transforms/InstCombine/and.ll
+++ llvm/test/Transforms/InstCombine/and.ll
@@ -979,7 +979,7 @@
 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
 ; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 20
 ; CHECK-NEXT:    call void @use32(i32 [[R]])
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], 4095
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %l = shl i32 %x, 20
@@ -989,6 +989,8 @@
   ret i32 %and
 }
 
+; Negative test - mismatched shift amounts
+
 define i32 @lowmask_not_sext_in_reg(i32 %x) {
 ; CHECK-LABEL: @lowmask_not_sext_in_reg(
 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 19
@@ -1004,6 +1006,8 @@
   ret i32 %and
 }
 
+; Negative test - too much shift for mask
+
 define i32 @not_lowmask_sext_in_reg(i32 %x) {
 ; CHECK-LABEL: @not_lowmask_sext_in_reg(
 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
@@ -1019,6 +1023,8 @@
   ret i32 %and
 }
 
+; Negative test - too much shift for mask
+
 define i32 @not_lowmask_sext_in_reg2(i32 %x) {
 ; CHECK-LABEL: @not_lowmask_sext_in_reg2(
 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 21
@@ -1039,7 +1045,7 @@
 ; CHECK-NEXT:    [[L:%.*]] = shl <2 x i32> [[X:%.*]], <i32 20, i32 20>
 ; CHECK-NEXT:    [[R:%.*]] = ashr exact <2 x i32> [[L]], <i32 20, i32 20>
 ; CHECK-NEXT:    store <2 x i32> [[R]], <2 x i32>* [[P:%.*]], align 8
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[R]], <i32 4095, i32 4095>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X]], <i32 4095, i32 4095>
 ; CHECK-NEXT:    ret <2 x i32> [[AND]]
 ;
   %l = shl <2 x i32> %x, <i32 20, i32 20>
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1817,9 +1817,9 @@
         return BinaryOperator::Create(BinOp, NewLHS, Y);
       }
     }
-    const APInt *ShiftC;
+    const APInt *ShiftC, *ShiftC2;
+    unsigned Width = Ty->getScalarSizeInBits();
     if (match(Op0, m_OneUse(m_SExt(m_AShr(m_Value(X), m_APInt(ShiftC)))))) {
-      unsigned Width = Ty->getScalarSizeInBits();
       if (*C == APInt::getLowBitsSet(Width, Width - ShiftC->getZExtValue())) {
         // We are clearing high bits that were potentially set by sext+ashr:
         // and (sext (ashr X, ShiftC)), C --> lshr (sext X), ShiftC
@@ -1828,6 +1828,12 @@
         return BinaryOperator::CreateLShr(Sext, ShAmtC);
       }
     }
+    // Peek through masking off the low bits of a sign-extend-in-register:
+    // and (ashr (shl X, ShiftC), ShiftC), C --> and X, C
+    if (match(Op0,
+              m_AShr(m_Shl(m_Value(X), m_APInt(ShiftC)), m_APInt(ShiftC2))) &&
+        ShiftC == ShiftC2 && (Width - ShiftC->getZExtValue()) > C->logBase2())
+      return BinaryOperator::CreateAnd(X, Op1);
   }
 
   ConstantInt *AndRHS;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91364.304870.patch
Type: text/x-patch
Size: 3008 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201112/20aa9ee3/attachment.bin>


More information about the llvm-commits mailing list