[llvm] [AArch64] Report icmp as free if it can be folded into ands (PR #143286)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 16 06:12:13 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/143286
>From 7d6bc03e3dc0d6911a2db3242caf8f7d00cf165a Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 7 Jun 2025 16:28:30 -0400
Subject: [PATCH] [AArch64] Report icmp as free if it can be folded into ands
Since changing the backend to fold x >= 1 / x < 1 -> x > 0 / x <= 0 and x <= -1 / x > -1 -> x > 0 / x <= 0, this should be reflected in the cost.
---
.../AArch64/AArch64TargetTransformInfo.cpp | 25 +++++++++++++------
llvm/test/Analysis/CostModel/AArch64/cmp.ll | 2 +-
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 0232ac421aeda..ed051f295752e 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -4353,15 +4353,26 @@ InstructionCost AArch64TTIImpl::getCmpSelInstrCost(
}
}
- // Treat the icmp in icmp(and, 0) as free, as we can make use of ands.
- // FIXME: This can apply to more conditions and add/sub if it can be shown to
- // be profitable.
+ // Treat the icmp in icmp(and, 0) or icmp(and, -1/1) when it can be folded to
+ // icmp(and, 0) as free, as we can make use of ands, but only if the
+ // comparison is not unsigned.
if (ValTy->isIntegerTy() && ISD == ISD::SETCC && I &&
- ICmpInst::isEquality(VecPred) &&
+ !CmpInst::isUnsigned(VecPred) &&
TLI->isTypeLegal(TLI->getValueType(DL, ValTy)) &&
- match(I->getOperand(1), m_Zero()) &&
- match(I->getOperand(0), m_And(m_Value(), m_Value())))
- return 0;
+ match(I->getOperand(0), m_And(m_Value(), m_Value()))) {
+ if (match(I->getOperand(1), m_Zero()))
+ return 0;
+
+ // x >= 1 / x < 1 -> x > 0 / x <= 0
+ if (match(I->getOperand(1), m_One()) &&
+ (VecPred == CmpInst::ICMP_SLT || VecPred == CmpInst::ICMP_SGE))
+ return 0;
+
+ // x <= -1 / x > -1 -> x > 0 / x <= 0
+ if (match(I->getOperand(1), m_AllOnes()) &&
+ (VecPred == CmpInst::ICMP_SLE || VecPred == CmpInst::ICMP_SGT))
+ return 0;
+ }
// The base case handles scalable vectors fine for now, since it treats the
// cost as 1 * legalization cost.
diff --git a/llvm/test/Analysis/CostModel/AArch64/cmp.ll b/llvm/test/Analysis/CostModel/AArch64/cmp.ll
index aba113865af10..a09e64303fdf4 100644
--- a/llvm/test/Analysis/CostModel/AArch64/cmp.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/cmp.ll
@@ -62,7 +62,7 @@ define void @andcmp() {
; CHECK-NEXT: Cost Model: Found costs of 1 for: %av4i32 = and <4 x i32> undef, undef
; CHECK-NEXT: Cost Model: Found costs of 1 for: %cv4i32 = icmp ne <4 x i32> %av4i32, zeroinitializer
; CHECK-NEXT: Cost Model: Found costs of 1 for: %c32not0 = icmp eq i32 %a32, 1
-; CHECK-NEXT: Cost Model: Found costs of 1 for: %c64sle = icmp sle i64 %a64, 0
+; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64sle = icmp sle i64 %a64, 0
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
;
%a8 = and i8 undef, undef
More information about the llvm-commits
mailing list