Skip to content

Commit dc72b91

Browse files
authored
[AArch64] Report icmp as free if it can be folded into ands (#143286)
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.
1 parent de33390 commit dc72b91

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4353,15 +4353,26 @@ InstructionCost AArch64TTIImpl::getCmpSelInstrCost(
43534353
}
43544354
}
43554355

4356-
// Treat the icmp in icmp(and, 0) as free, as we can make use of ands.
4357-
// FIXME: This can apply to more conditions and add/sub if it can be shown to
4358-
// be profitable.
4356+
// Treat the icmp in icmp(and, 0) or icmp(and, -1/1) when it can be folded to
4357+
// icmp(and, 0) as free, as we can make use of ands, but only if the
4358+
// comparison is not unsigned.
43594359
if (ValTy->isIntegerTy() && ISD == ISD::SETCC && I &&
4360-
ICmpInst::isEquality(VecPred) &&
4360+
!CmpInst::isUnsigned(VecPred) &&
43614361
TLI->isTypeLegal(TLI->getValueType(DL, ValTy)) &&
4362-
match(I->getOperand(1), m_Zero()) &&
4363-
match(I->getOperand(0), m_And(m_Value(), m_Value())))
4364-
return 0;
4362+
match(I->getOperand(0), m_And(m_Value(), m_Value()))) {
4363+
if (match(I->getOperand(1), m_Zero()))
4364+
return 0;
4365+
4366+
// x >= 1 / x < 1 -> x > 0 / x <= 0
4367+
if (match(I->getOperand(1), m_One()) &&
4368+
(VecPred == CmpInst::ICMP_SLT || VecPred == CmpInst::ICMP_SGE))
4369+
return 0;
4370+
4371+
// x <= -1 / x > -1 -> x > 0 / x <= 0
4372+
if (match(I->getOperand(1), m_AllOnes()) &&
4373+
(VecPred == CmpInst::ICMP_SLE || VecPred == CmpInst::ICMP_SGT))
4374+
return 0;
4375+
}
43654376

43664377
// The base case handles scalable vectors fine for now, since it treats the
43674378
// cost as 1 * legalization cost.

llvm/test/Analysis/CostModel/AArch64/cmp.ll

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ define void @andcmp() {
5353
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c32 = icmp eq i32 %a32, 0
5454
; CHECK-NEXT: Cost Model: Found costs of 1 for: %a64 = and i64 undef, undef
5555
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64 = icmp ne i64 %a64, 0
56+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c32ge = icmp sge i32 %a32, 1
57+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c32le = icmp slt i32 %a32, 1
58+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c32leneg = icmp sle i32 %a32, -1
59+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c32gtneg = icmp sgt i32 %a32, -1
60+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64ge = icmp sge i64 %a64, 1
61+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64le = icmp slt i64 %a64, 1
62+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64leneg = icmp sle i64 %a64, -1
63+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64gtneg = icmp sgt i64 %a64, -1
5664
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %a128 = and i128 undef, undef
5765
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %c128 = icmp eq i128 %a128, 0
5866
; CHECK-NEXT: Cost Model: Found costs of 1 for: %av16i8 = and <16 x i8> undef, undef
@@ -62,7 +70,7 @@ define void @andcmp() {
6270
; CHECK-NEXT: Cost Model: Found costs of 1 for: %av4i32 = and <4 x i32> undef, undef
6371
; CHECK-NEXT: Cost Model: Found costs of 1 for: %cv4i32 = icmp ne <4 x i32> %av4i32, zeroinitializer
6472
; CHECK-NEXT: Cost Model: Found costs of 1 for: %c32not0 = icmp eq i32 %a32, 1
65-
; CHECK-NEXT: Cost Model: Found costs of 1 for: %c64sle = icmp sle i64 %a64, 0
73+
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: %c64sle = icmp sle i64 %a64, 0
6674
; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
6775
;
6876
%a8 = and i8 undef, undef
@@ -73,6 +81,17 @@ define void @andcmp() {
7381
%c32 = icmp eq i32 %a32, 0
7482
%a64 = and i64 undef, undef
7583
%c64 = icmp ne i64 %a64, 0
84+
85+
%c32ge = icmp sge i32 %a32, 1
86+
%c32le = icmp slt i32 %a32, 1
87+
%c32leneg = icmp sle i32 %a32, -1
88+
%c32gtneg = icmp sgt i32 %a32, -1
89+
90+
%c64ge = icmp sge i64 %a64, 1
91+
%c64le = icmp slt i64 %a64, 1
92+
%c64leneg = icmp sle i64 %a64, -1
93+
%c64gtneg = icmp sgt i64 %a64, -1
94+
7695
%a128 = and i128 undef, undef
7796
%c128 = icmp eq i128 %a128, zeroinitializer
7897
%av16i8 = and <16 x i8> undef, undef

0 commit comments

Comments
 (0)