[PATCH] D154126: [InstCombine] Transform (A > 0) | (A < 0) -> zext (A != 0) fold
Hongyu Chen via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 30 16:25:52 PDT 2023
XChy updated this revision to Diff 536476.
XChy set the repository for this revision to rG LLVM Github Monorepo.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D154126/new/
https://reviews.llvm.org/D154126
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/and-or-icmps.ll
Index: llvm/test/Transforms/InstCombine/and-or-icmps.ll
===================================================================
--- llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -2571,10 +2571,8 @@
define i32 @icmp_slt_0_or_icmp_sgt_0_i32(i32 %x) {
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i32(
-; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[X:%.*]], 0
-; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i32
-; CHECK-NEXT: [[E:%.*]] = or i32 [[X_LOBIT]], [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 0
+; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[E]]
;
%A = icmp slt i32 %x, 0
@@ -2587,10 +2585,8 @@
define i64 @icmp_slt_0_or_icmp_sgt_0_i64(i64 %x) {
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64(
-; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[X:%.*]], 0
-; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i64 [[X]], 63
-; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i64
-; CHECK-NEXT: [[E:%.*]] = or i64 [[X_LOBIT]], [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[X:%.*]], 0
+; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i64
; CHECK-NEXT: ret i64 [[E]]
;
%A = icmp slt i64 %x, 0
@@ -2659,10 +2655,8 @@
define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2(<2 x i64> %x) {
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2(
-; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i64> [[X:%.*]], zeroinitializer
-; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i64> [[X]], <i64 63, i64 63>
-; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[B]] to <2 x i64>
-; CHECK-NEXT: [[E:%.*]] = or <2 x i64> [[X_LOBIT]], [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer
+; CHECK-NEXT: [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
; CHECK-NEXT: ret <2 x i64> [[E]]
;
%A = icmp slt <2 x i64> %x, <i64 0,i64 0>
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1712,6 +1712,31 @@
assert(I.isBitwiseLogicOp() && "Unexpected opcode for bitwise logic folding");
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+ // ( A << (X - 1) ) | ((A > 0) zext to iX)
+ // <=> A < 0 | A > 0
+ // <=> (A != 0) zext to iX
+ Value *A;
+ const APInt *B;
+ ICmpInst::Predicate Pred;
+
+ auto MatchOrZextIcmp = [&](Value *Op0, Value *Op1) -> bool {
+ return match(Op0, m_LShr(m_Value(A), m_APInt(B))) &&
+ match(Op1, m_ZExt(m_ICmp(Pred, m_Specific(A), m_Zero())));
+ };
+
+ if (LogicOpc == Instruction::Or &&
+ (MatchOrZextIcmp(Op0, Op1) || MatchOrZextIcmp(Op1, Op0)) &&
+ Pred == ICmpInst::ICMP_SGT) {
+ uint64_t X = A->getType()->getScalarSizeInBits();
+
+ if (B->getZExtValue() == X - 1) {
+ Value *Cmp =
+ Builder.CreateICmpNE(A, Constant::getNullValue(A->getType()));
+ return new ZExtInst(Cmp, A->getType());
+ }
+ }
+
CastInst *Cast0 = dyn_cast<CastInst>(Op0);
if (!Cast0)
return nullptr;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154126.536476.patch
Type: text/x-patch
Size: 3164 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230630/c6bed4fa/attachment.bin>
More information about the llvm-commits
mailing list