[PATCH] D112634: [InstCombine] canonicalize icmp with trunc op into mask and cmp, part 2
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 27 10:00:29 PDT 2021
spatel created this revision.
spatel added a reviewer: lebedev.ri.
Herald added subscribers: hiraditya, mcrosier.
spatel requested review of this revision.
Herald added a project: LLVM.
If C is a high-bit mask:
(trunc X) u< C --> (X & C) != C (are any masked-high-bits clear?)
This extends the fold added with:
acabad9ff6bf <https://reviews.llvm.org/rGacabad9ff6bf13e00305d9d8621ee8eafc1f8b08>
We discussed using decomposeBitTestICmp() to generalize this, but that function doesn't line up with the other fold that I was imagining (maybe there's some way to adapt/invert the logic?).
This patch also modifies the code to create the mask constant from the earlier patch in an attempt to make the bit-masking relationships clearer. I can make that an NFC pre-commit to be safer.
Here are Alive2 generalizations for both of the folds:
https://alive2.llvm.org/ce/z/u-ZpC_ (the previous patch)
https://alive2.llvm.org/ce/z/Kdp4jc (this patch)
https://reviews.llvm.org/D112634
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-trunc.ll
Index: llvm/test/Transforms/InstCombine/icmp-trunc.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-trunc.ll
+++ llvm/test/Transforms/InstCombine/icmp-trunc.ll
@@ -71,8 +71,8 @@
define i1 @ult_192(i32 %x) {
; CHECK-LABEL: @ult_192(
-; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T]], -64
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 192
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 192
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
@@ -82,8 +82,8 @@
define <2 x i1> @ult_2044_splat(<2 x i16> %x) {
; CHECK-LABEL: @ult_2044_splat(
-; CHECK-NEXT: [[T:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i11>
-; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i11> [[T]], <i11 -4, i11 -4>
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 2044, i16 2044>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], <i16 2044, i16 2044>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4598,19 +4598,30 @@
// The trunc masks high bits while the compare may effectively mask low bits.
Value *X;
const APInt *C;
- if (match(Op0, m_OneUse(m_Trunc(m_Value(X)))) && match(Op1, m_Power2(C))) {
- if (Pred == ICmpInst::ICMP_ULT) {
- // (trunc X) u< Pow2C --> (X & MaskC) == 0
- unsigned SrcBits = X->getType()->getScalarSizeInBits();
- unsigned DstBits = Op0->getType()->getScalarSizeInBits();
- APInt MaskC = APInt::getOneBitSet(SrcBits, DstBits) - C->zext(SrcBits);
+ if (!match(Op0, m_OneUse(m_Trunc(m_Value(X)))) || !match(Op1, m_APInt(C)))
+ return nullptr;
+
+ unsigned SrcBits = X->getType()->getScalarSizeInBits();
+ if (Pred == ICmpInst::ICMP_ULT) {
+ // If C is a power-of-2:
+ // (trunc X) u< C --> X & (~C + 1) == 0 (are all masked-high-bits clear?)
+ if (C->isPowerOf2()) {
+ Constant *MaskC = ConstantInt::get(X->getType(), (~*C + 1).zext(SrcBits));
Value *And = Builder.CreateAnd(X, MaskC);
Constant *Zero = ConstantInt::getNullValue(X->getType());
return new ICmpInst(ICmpInst::ICMP_EQ, And, Zero);
}
- // TODO: Handle ugt.
+ // If C is a high-bit mask:
+ // (trunc X) u< C --> (X & C) != C (are any masked-high-bits clear?)
+ if ((~(*C)).isMask()) {
+ Constant *MaskC = ConstantInt::get(X->getType(), C->zext(SrcBits));
+ Value *And = Builder.CreateAnd(X, MaskC);
+ return new ICmpInst(ICmpInst::ICMP_NE, And, MaskC);
+ }
}
+ // TODO: Handle ugt.
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112634.382703.patch
Type: text/x-patch
Size: 2831 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211027/7efdfd1c/attachment.bin>
More information about the llvm-commits
mailing list