[llvm] 7783db5 - [InstCombine] try to fold low-mask of ashr to lshr

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 08:57:03 PDT 2022


Author: Sanjay Patel
Date: 2022-04-11T11:56:40-04:00
New Revision: 7783db55afefd3b0d83f4d1b727b6aaa2c2286d6

URL: https://github.com/llvm/llvm-project/commit/7783db55afefd3b0d83f4d1b727b6aaa2c2286d6
DIFF: https://github.com/llvm/llvm-project/commit/7783db55afefd3b0d83f4d1b727b6aaa2c2286d6.diff

LOG: [InstCombine] try to fold low-mask of ashr to lshr

With one-use, we handle this via demanded-bits.
But We need to handle extra uses to improve issue #54750.

https://alive2.llvm.org/ce/z/aDYkPv

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index f68787a1535fa..b8dba03e5e689 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1968,6 +1968,12 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
       }
     }
 
+    // If this 'and' clears the sign-bits added by ashr, replace with lshr:
+    // and (ashr X, ShiftC), C --> lshr X, ShiftC
+    if (match(Op0, m_AShr(m_Value(X), m_APInt(ShiftC))) && ShiftC->ult(Width) &&
+        C->isMask(Width - ShiftC->getZExtValue()))
+      return BinaryOperator::CreateLShr(X, ConstantInt::get(Ty, *ShiftC));
+
     const APInt *AddC;
     if (match(Op0, m_Add(m_Value(X), m_APInt(AddC)))) {
       // If we add zeros to every bit below a mask, the add has no effect:

diff  --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 429e9bceac710..07f0ae62ca396 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -406,7 +406,7 @@ define i32 @ashr_lowmask_use(i32 %x) {
 ; CHECK-LABEL: @ashr_lowmask_use(
 ; CHECK-NEXT:    [[A:%.*]] = ashr i32 [[X:%.*]], 1
 ; CHECK-NEXT:    call void @use32(i32 [[A]])
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], 2147483647
+; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[X]], 1
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %a = ashr i32 %x, 1
@@ -419,7 +419,7 @@ define <2 x i8> @ashr_lowmask_use_splat(<2 x i8> %x, <2 x i8>* %p) {
 ; CHECK-LABEL: @ashr_lowmask_use_splat(
 ; CHECK-NEXT:    [[A:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 7, i8 7>
 ; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 1, i8 1>
+; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i8> [[X]], <i8 7, i8 7>
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
 ;
   %a = ashr <2 x i8> %x, <i8 7, i8 7>
@@ -428,6 +428,8 @@ define <2 x i8> @ashr_lowmask_use_splat(<2 x i8> %x, <2 x i8>* %p) {
   ret <2 x i8> %r
 }
 
+; negative test - must keep all low bits
+
 define i32 @ashr_not_lowmask1_use(i32 %x) {
 ; CHECK-LABEL: @ashr_not_lowmask1_use(
 ; CHECK-NEXT:    [[A:%.*]] = ashr i32 [[X:%.*]], 24
@@ -441,6 +443,8 @@ define i32 @ashr_not_lowmask1_use(i32 %x) {
   ret i32 %r
 }
 
+; negative test - must keep all low bits
+
 define i32 @ashr_not_lowmask2_use(i32 %x) {
 ; CHECK-LABEL: @ashr_not_lowmask2_use(
 ; CHECK-NEXT:    [[A:%.*]] = ashr i32 [[X:%.*]], 24
@@ -454,6 +458,8 @@ define i32 @ashr_not_lowmask2_use(i32 %x) {
   ret i32 %r
 }
 
+; negative test - must keep only low bits
+
 define i32 @ashr_not_lowmask3_use(i32 %x) {
 ; CHECK-LABEL: @ashr_not_lowmask3_use(
 ; CHECK-NEXT:    [[A:%.*]] = ashr i32 [[X:%.*]], 24
@@ -1231,14 +1237,14 @@ define i32 @lowmask_sext_in_reg(i32 %x) {
   ret i32 %and
 }
 
-; Negative test - mismatched shift amounts
+; Mismatched shift amounts, but the mask op can be replaced by a shift.
 
 define i32 @lowmask_not_sext_in_reg(i32 %x) {
 ; CHECK-LABEL: @lowmask_not_sext_in_reg(
 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 19
 ; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[L]], 20
 ; CHECK-NEXT:    call void @use32(i32 [[R]])
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
+; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[L]], 20
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %l = shl i32 %x, 19


        


More information about the llvm-commits mailing list