diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index 734339e5c7a05..9fb9758c96197 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -811,15 +811,20 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, {ISD::CTPOP, MVT::v2i32, 3}, {ISD::CTPOP, MVT::v4i16, 2}, {ISD::CTPOP, MVT::v8i8, 1}, - {ISD::CTPOP, MVT::i32, 5}, + {ISD::CTPOP, MVT::i32, 4}, }; + EVT VT = TLI->getValueType(DL, RetTy, true); + // i8 ctpop can avoid the uaddlv after cnt since only one byte is active, + // making it cheaper than the legalized i32 cost. + if (VT == MVT::i8) + return 4; + auto LT = getTypeLegalizationCost(RetTy); MVT MTy = LT.second; if (const auto *Entry = CostTableLookup(CtpopCostTbl, ISD::CTPOP, MTy)) { - // Extra cost of +1 when illegal vector types are legalized by promoting + // Extra cost of +1 when illegal vector/scalar types are legalized by promoting // the integer type. - int ExtraCost = MTy.isVector() && MTy.getScalarSizeInBits() != - RetTy->getScalarSizeInBits() + int ExtraCost = MTy.getScalarSizeInBits() != RetTy->getScalarSizeInBits() ? 1 : 0; return LT.first * Entry->Cost + ExtraCost; diff --git a/llvm/test/Analysis/CostModel/AArch64/ctpop.ll b/llvm/test/Analysis/CostModel/AArch64/ctpop.ll index 013432991f5ae..1a48d9d37d03e 100644 --- a/llvm/test/Analysis/CostModel/AArch64/ctpop.ll +++ b/llvm/test/Analysis/CostModel/AArch64/ctpop.ll @@ -16,7 +16,7 @@ define i64 @test_ctpop_i64(i64 %a) { define i32 @test_ctpop_i32(i32 %a) { ; CHECK-LABEL: 'test_ctpop_i32' -; CHECK-NEXT: Cost Model: Found costs of 5 for: %ctpop = call i32 @llvm.ctpop.i32(i32 %a) +; CHECK-NEXT: Cost Model: Found costs of 4 for: %ctpop = call i32 @llvm.ctpop.i32(i32 %a) ; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i32 %ctpop ; %ctpop = call i32 @llvm.ctpop.i32(i32 %a) @@ -34,7 +34,7 @@ define i16 @test_ctpop_i16(i16 %a) { define i8 @test_ctpop_i8(i8 %a) { ; CHECK-LABEL: 'test_ctpop_i8' -; CHECK-NEXT: Cost Model: Found costs of 5 for: %ctpop = call i8 @llvm.ctpop.i8(i8 %a) +; CHECK-NEXT: Cost Model: Found costs of 4 for: %ctpop = call i8 @llvm.ctpop.i8(i8 %a) ; CHECK-NEXT: Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i8 %ctpop ; %ctpop = call i8 @llvm.ctpop.i8(i8 %a) diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-neon-compare.ll b/llvm/test/Analysis/CostModel/AArch64/sve-neon-compare.ll new file mode 100644 index 0000000000000..7852e47e5846f --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-neon-compare.ll @@ -0,0 +1,44 @@ +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s --check-prefix=NEON +; RUN: opt < %s -passes='print' -disable-output -mattr=+sve 2>&1 | FileCheck %s --check-prefix=SVE + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" +target triple = "aarch64-unknown-linux-gnu" + +; --- Fixed-width (NEON) types --- + +define <16 x i8> @smin_v16i8(<16 x i8> %a, <16 x i8> %b) { +; NEON: cost of {{.*}} call {{.*}} @llvm.smin.v16i8 +; SVE: cost of {{.*}} call {{.*}} @llvm.smin.v16i8 + %r = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a, <16 x i8> %b) + ret <16 x i8> %r +} + +define <4 x i32> @smin_v4i32(<4 x i32> %a, <4 x i32> %b) { +; NEON: cost of {{.*}} call {{.*}} @llvm.smin.v4i32 +; SVE: cost of {{.*}} call {{.*}} @llvm.smin.v4i32 + %r = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %a, <4 x i32> %b) + ret <4 x i32> %r +} + +; --- Scalable (SVE) types --- + +define @smin_nxv16i8( %a, %b) { +; NEON: cost of {{.*}} call {{.*}} @llvm.smin.nxv16i8 +; SVE: cost of {{.*}} call {{.*}} @llvm.smin.nxv16i8 + %r = call @llvm.smin.nxv16i8( %a, %b) + ret %r +} + +define @smin_nxv4i32( %a, %b) { +; NEON: cost of {{.*}} call {{.*}} @llvm.smin.nxv4i32 +; SVE: cost of {{.*}} call {{.*}} @llvm.smin.nxv4i32 + %r = call @llvm.smin.nxv4i32( %a, %b) + ret %r +} + +define @smin_nxv2i64( %a, %b) { +; NEON: cost of {{.*}} call {{.*}} @llvm.smin.nxv2i64 +; SVE: cost of {{.*}} call {{.*}} @llvm.smin.nxv2i64 + %r = call @llvm.smin.nxv2i64( %a, %b) + ret %r +}