[PATCH] D152673: [InstCombine] Canonicalize `(X^(X-1)) u{ge, lt} X` as pow2 test
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 12 17:52:49 PDT 2023
goldstein.w.n updated this revision to Diff 530734.
goldstein.w.n added a comment.
Fix fmt
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D152673/new/
https://reviews.llvm.org/D152673
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/ispow2.ll
Index: llvm/test/Transforms/InstCombine/ispow2.ll
===================================================================
--- llvm/test/Transforms/InstCombine/ispow2.ll
+++ llvm/test/Transforms/InstCombine/ispow2.ll
@@ -1144,9 +1144,8 @@
define i1 @blsmsk_is_p2_or_z(i32 %xx, i32 %yy) {
; CHECK-LABEL: @blsmsk_is_p2_or_z(
; CHECK-NEXT: [[X:%.*]] = or i32 [[XX:%.*]], [[YY:%.*]]
-; CHECK-NEXT: [[XM1:%.*]] = add i32 [[X]], -1
-; CHECK-NEXT: [[Y:%.*]] = xor i32 [[X]], [[XM1]]
-; CHECK-NEXT: [[R:%.*]] = icmp uge i32 [[X]], [[Y]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
+; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[TMP1]], 2
; CHECK-NEXT: ret i1 [[R]]
;
%x = or i32 %xx, %yy
@@ -1158,9 +1157,8 @@
define i1 @blsmsk_isnt_p2_or_z(i32 %x) {
; CHECK-LABEL: @blsmsk_isnt_p2_or_z(
-; CHECK-NEXT: [[XM1:%.*]] = add i32 [[X:%.*]], -1
-; CHECK-NEXT: [[Y:%.*]] = xor i32 [[XM1]], [[X]]
-; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[Y]], [[X]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[R:%.*]] = icmp ugt i32 [[TMP1]], 1
; CHECK-NEXT: ret i1 [[R]]
;
%xm1 = add i32 %x, -1
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4812,28 +4812,44 @@
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
const CmpInst::Predicate Pred = I.getPredicate();
Value *A = nullptr;
- // (A & (A-1)) == 0 --> ctpop(A) < 2 (two commuted variants)
- // ((A-1) & A) != 0 --> ctpop(A) > 1 (two commuted variants)
- if (!match(Op0, m_OneUse(m_c_And(m_Add(m_Value(A), m_AllOnes()),
- m_Deferred(A)))) ||
- !match(Op1, m_ZeroInt()))
- A = nullptr;
-
- // (A & -A) == A --> ctpop(A) < 2 (four commuted variants)
- // (-A & A) != A --> ctpop(A) > 1 (four commuted variants)
- if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1)))))
- A = Op1;
- else if (match(Op1,
- m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0)))))
- A = Op0;
+ bool CheckIs;
+ if (I.isEquality()) {
+ // (A & (A-1)) == 0 --> ctpop(A) < 2 (two commuted variants)
+ // ((A-1) & A) != 0 --> ctpop(A) > 1 (two commuted variants)
+ if (!match(Op0, m_OneUse(m_c_And(m_Add(m_Value(A), m_AllOnes()),
+ m_Deferred(A)))) ||
+ !match(Op1, m_ZeroInt()))
+ A = nullptr;
+
+ // (A & -A) == A --> ctpop(A) < 2 (four commuted variants)
+ // (-A & A) != A --> ctpop(A) > 1 (four commuted variants)
+ if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1)))))
+ A = Op1;
+ else if (match(Op1,
+ m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0)))))
+ A = Op0;
+
+ CheckIs = Pred == ICmpInst::ICMP_EQ;
+ } else if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_ULT) {
+ // (A ^ (A-1)) u>= A --> ctpop(A) < 2 (two commuted variants)
+ // ((A-1) ^ A) u< A --> ctpop(A) > 1 (two commuted variants)
+ if (match(Op0, m_OneUse(m_c_Xor(m_Add(m_Specific(Op1), m_AllOnes()),
+ m_Specific(Op1)))))
+ A = Op1;
+ else if (match(Op1, m_OneUse(m_c_Xor(m_Add(m_Specific(Op0), m_AllOnes()),
+ m_Specific(Op0)))))
+ A = Op0;
+
+ CheckIs = Pred == ICmpInst::ICMP_UGE;
+ }
if (A) {
Type *Ty = A->getType();
CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A);
- return Pred == ICmpInst::ICMP_EQ ? new ICmpInst(ICmpInst::ICMP_ULT, CtPop,
- ConstantInt::get(Ty, 2))
- : new ICmpInst(ICmpInst::ICMP_UGT, CtPop,
- ConstantInt::get(Ty, 1));
+ return CheckIs ? new ICmpInst(ICmpInst::ICMP_ULT, CtPop,
+ ConstantInt::get(Ty, 2))
+ : new ICmpInst(ICmpInst::ICMP_UGT, CtPop,
+ ConstantInt::get(Ty, 1));
}
return nullptr;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152673.530734.patch
Type: text/x-patch
Size: 4272 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230613/9cfd95de/attachment.bin>
More information about the llvm-commits
mailing list