[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:10:35 PDT 2022
bcl5980 updated this revision to Diff 472128.
bcl5980 added a comment.
origin version rebased.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D136582/new/
https://reviews.llvm.org/D136582
Files:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.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
@@ -2236,9 +2236,8 @@
; C2 is negative pow2
define i10 @sub_to_and_nuw(i10 %x) {
; CHECK-LABEL: @sub_to_and_nuw(
-; CHECK-NEXT: [[SUB:%.*]] = sub nuw i10 71, [[X:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 120
-; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i10 443, [[AND]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i10 [[X:%.*]], 120
+; CHECK-NEXT: [[R:%.*]] = add nuw nsw i10 [[TMP1]], 379
; CHECK-NEXT: ret i10 [[R]]
;
%sub = sub nuw i10 71, %x
@@ -2253,9 +2252,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
@@ -2342,9 +2340,8 @@
define <2 x i8> @sub_to_and_vector1(<2 x i8> %x) {
; CHECK-LABEL: @sub_to_and_vector1(
-; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i8> <i8 71, i8 71>, [[X:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SUB]], <i8 120, i8 120>
-; CHECK-NEXT: [[R:%.*]] = sub nsw <2 x i8> <i8 55, i8 55>, [[AND]]
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 120, i8 120>
+; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[TMP1]], <i8 -9, i8 -9>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%sub = sub nuw <2 x i8> <i8 71, i8 71>, %x
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2032,12 +2032,34 @@
}
const APInt *Op0C;
- if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) {
- // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
- // zero.
- KnownBits RHSKnown = computeKnownBits(Op1, 0, &I);
- if ((*Op0C | RHSKnown.Zero).isAllOnes())
- return BinaryOperator::CreateXor(Op1, Op0);
+ if (match(Op0, m_APInt(Op0C))) {
+ if (Op0C->isMask()) {
+ // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
+ // zero.
+ KnownBits RHSKnown = computeKnownBits(Op1, 0, &I);
+ if ((*Op0C | RHSKnown.Zero).isAllOnes())
+ return BinaryOperator::CreateXor(Op1, Op0);
+ }
+
+ // C - ((C3 -nuw X) & C2) --> (C - (C2 & C3)) + (X & C2) when:
+ // (C3 - (C2 & C3) + 1) is pow2
+ // ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1)
+ // C2 is negative pow2 || sub nuw
+ const APInt *C2, *C3;
+ BinaryOperator *InnerSub;
+ if (match(Op1, m_OneUse(m_And(m_BinOp(InnerSub), m_APInt(C2)))) &&
+ match(InnerSub, m_Sub(m_APInt(C3), m_Value(X)))) {
+ APInt C2AndC3 = *C2 & *C3;
+ APInt C2AndC3Minus1 = C2AndC3 - 1;
+ APInt C2AddC3 = *C2 + *C3;
+ if ((InnerSub->hasNoUnsignedWrap() || C2->isNegatedPowerOf2()) &&
+ (*C3 - C2AndC3Minus1).isPowerOf2() &&
+ C2AndC3Minus1.isSubsetOf(C2AddC3)) {
+ Value *And = Builder.CreateAnd(X, ConstantInt::get(I.getType(), *C2));
+ return BinaryOperator::CreateAdd(
+ And, ConstantInt::get(I.getType(), *Op0C - C2AndC3));
+ }
+ }
}
{
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136582.472128.patch
Type: text/x-patch
Size: 3520 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221031/0c1880e1/attachment.bin>
More information about the llvm-commits
mailing list