[PATCH] D114272: [InstCombine] Add two optimizations for mul-and-icmp patterns
Fabian Wolff via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 8 11:43:32 PST 2022
fwolff updated this revision to Diff 406911.
fwolff added a comment.
In D114272#3299405 <https://reviews.llvm.org/D114272#3299405>, @RKSimon wrote:
> @fwolff Please can you rebase this patch?
Done!
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D114272/new/
https://reviews.llvm.org/D114272
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-mul-and.ll
Index: llvm/test/Transforms/InstCombine/icmp-mul-and.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-mul-and.ll
+++ llvm/test/Transforms/InstCombine/icmp-mul-and.ll
@@ -22,8 +22,8 @@
; CHECK-LABEL: @mul_mask_pow2_ne0_use1(
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 40
; CHECK-NEXT: call void @use(i8 [[MUL]])
-; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 8
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i8 %x, 40
@@ -241,11 +241,8 @@
define i1 @pr51551(i32 %x, i32 %y) {
; CHECK-LABEL: @pr51551(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[Y:%.*]], -8
-; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[TMP0]], 1
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[X:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], 3
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 3
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
@@ -260,11 +257,8 @@
define i1 @pr51551_2(i32 %x, i32 %y) {
; CHECK-LABEL: @pr51551_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[Y:%.*]], -8
-; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[TMP0]], 1
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[X:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1887,6 +1887,48 @@
return new ICmpInst(NewPred, X, SubOne(cast<Constant>(Cmp.getOperand(1))));
}
+ const APInt *C2;
+ if (And->hasOneUse() && C.isZero() && match(Y, m_APInt(C2))) {
+ const APInt *C1;
+ Value *X1;
+ // ((X1 * C1) & C2) ==/!= 0 -> ((X1 * (C1/C2)) & 1) ==/!= 0
+ // iff C2 is a power of 2 greater than 1 and C1 is a multiple of C2
+ if (match(X, m_Mul(m_Value(X1), m_APInt(C1))) && C2->isPowerOf2() &&
+ !C2->isOne() && (C1->urem(*C2)).isZero()) {
+ APInt NewDiv = C1->udiv(*C2);
+ auto *NewMul =
+ Builder.CreateMul(X1, ConstantInt::get(X1->getType(), NewDiv));
+ auto *NewAnd =
+ Builder.CreateAnd(NewMul, ConstantInt::get(NewMul->getType(), 1));
+ return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
+ }
+
+ Value *X2;
+ // ((X1 * X2) & C2) ==/!= 0 -> (X1 & C2) ==/!= 0
+ // iff (C2 + 1) is a power of 2 and (X2 & C2) == 1
+ if (match(X, m_Mul(m_Value(X1), m_Value(X2))) && C2->isMask()) {
+ unsigned TrailingOnes = C2->countTrailingOnes();
+ APInt ExpectedZero =
+ C2->usub_sat(APInt::getOneBitSet(C2->getBitWidth(), 0));
+
+ auto Check = [&](Value *Xi, Value *Xj) -> Instruction * {
+ KnownBits XiKnown = computeKnownBits(Xi, 0, &Cmp);
+ if (XiKnown.One.getLoBits(1).isOne() &&
+ XiKnown.Zero.getLoBits(TrailingOnes) == ExpectedZero) {
+ auto *NewAnd =
+ Builder.CreateAnd(Xj, ConstantInt::get(Xj->getType(), *C2));
+ return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
+ }
+ return nullptr;
+ };
+
+ if (Instruction *I = Check(X1, X2))
+ return I;
+ if (Instruction *I = Check(X2, X1))
+ return I;
+ }
+ }
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114272.406911.patch
Type: text/x-patch
Size: 3794 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220208/685d675f/attachment.bin>
More information about the llvm-commits
mailing list