[PATCH] D136582: [InstCombine] fold `sub + and` pattern with specific const value

chenglin.bi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 31 14:06:35 PDT 2022


bcl5980 updated this revision to Diff 472123.
bcl5980 added a comment.

Update based on @spatel 's suggestion. 
I haven't update the summary for now because we can't make sure this patch is the final solution or not.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136582/new/

https://reviews.llvm.org/D136582

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


Index: llvm/test/Transforms/InstCombine/sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sub.ll
+++ llvm/test/Transforms/InstCombine/sub.ll
@@ -2253,9 +2253,8 @@
 ; ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1)
 define i10 @sub_to_and_negpow2(i10 %x) {
 ; CHECK-LABEL: @sub_to_and_negpow2(
-; CHECK-NEXT:    [[SUB:%.*]] = sub i10 71, [[X:%.*]]
-; CHECK-NEXT:    [[AND:%.*]] = and i10 [[SUB]], -8
-; CHECK-NEXT:    [[R:%.*]] = sub i10 33, [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i10 [[X:%.*]], -8
+; CHECK-NEXT:    [[R:%.*]] = add i10 [[TMP1]], -31
 ; CHECK-NEXT:    ret i10 [[R]]
 ;
   %sub = sub i10 71, %x
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2035,6 +2035,18 @@
                                 ConstantInt::getNullValue(Ty));
     }
 
+    // If all bits affected by a sub are included in a high-bit-mask, do the
+    // mask op before the adjusted sub. Example:
+    // (0x0f - X) & 0xf8 --> 0x08 - (X & 0xf8)
+    const APInt *SubC;
+    if (C->isNegatedPowerOf2() &&
+        match(Op0, m_OneUse(m_Sub(m_APInt(SubC), m_Value(X)))) &&
+        (~*C).isSubsetOf(*SubC)) {
+      Value *NewAnd = Builder.CreateAnd(X, *C);
+      Constant *NewSubC = ConstantInt::get(Ty, *C & *SubC);
+      return BinaryOperator::CreateSub(NewSubC, NewAnd);
+    }
+
     Constant *C1, *C2;
     const APInt *C3 = C;
     Value *X;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136582.472123.patch
Type: text/x-patch
Size: 1607 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221031/0b1dcb50/attachment.bin>


More information about the llvm-commits mailing list