diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -1157,14 +1157,11 @@ if (ICA.isTypeBasedOnly()) return getTypeBasedIntrinsicInstrCost(ICA, CostKind); - // TODO: Handle scalable vectors? Type *RetTy = ICA.getReturnType(); - if (isa(RetTy)) - return BaseT::getIntrinsicInstrCost(ICA, CostKind); ElementCount VF = ICA.getVectorFactor(); ElementCount RetVF = - (RetTy->isVectorTy() ? cast(RetTy)->getElementCount() + (RetTy->isVectorTy() ? cast(RetTy)->getElementCount() : ElementCount::getFixed(1)); assert((RetVF.isScalar() || VF.isScalar()) && "VF > 1 and RetVF is a vector type"); @@ -1277,12 +1274,16 @@ for (const Value *Op : Args) { Type *OpTy = Op->getType(); assert(VF.isScalar() || !OpTy->isVectorTy()); - Types.push_back(VF.isScalar() ? OpTy : FixedVectorType::get( - OpTy, VF.getKnownMinValue())); + Types.push_back(VF.isScalar() ? OpTy : VectorType::get(OpTy, VF)); } - if (VF.isVector() && !RetTy->isVoidTy()) - RetTy = FixedVectorType::get(RetTy, VF.getKnownMinValue()); + // TODO: Handle the remaining intrinsic with scalable vector type + if (isa(RetTy)) + return BaseT::getIntrinsicInstrCost(ICA, CostKind); + + if (VF.isVector() && !RetTy->isVoidTy()) { + RetTy = VectorType::get(RetTy, VF); + } // Compute the scalarization overhead based on Args for a vector // intrinsic. A vectorizer will pass a scalar RetTy and VF > 1, while diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-cctz-ctlz.ll b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-cctz-ctlz.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-cctz-ctlz.ll @@ -0,0 +1,31 @@ +; Checks getIntrinsicInstrCost in BasicTTIImpl.h with SVE for CTLZ and CCTZ + +; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s + +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +; Check for CTLZ + +define void @ctlz_nxv4i32( %A) { +; CHECK-LABEL: 'ctlz_nxv4i32' +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NETX: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + %1 = tail call @llvm.ctlz.nxv4i32( %A, i1 true) + ret void +} + +; Check for CCTZ + +define void @cttz_nxv4i32( %A) { +; CHECK-LABEL: 'cttz_nxv4i32' +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NETX: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + %1 = tail call @llvm.cttz.nxv4i32( %A, i1 true) + ret void +} + +declare @llvm.ctlz.nxv4i32(, i1) +declare @llvm.cttz.nxv4i32(, i1) diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-gather.ll b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-gather.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-gather.ll @@ -0,0 +1,31 @@ +; Check getIntrinsicInstrCost in BasicTTIImpl.h for masked gather + +; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s + +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +define @masked_gather_nxv4i32( %ld, %masks, %passthru) { +; CHECK-LABEL: 'masked_gather_nxv4i32' +; CHECK: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + + %res = call @llvm.masked.gather.nxv4i32( %ld, i32 0, %masks, %passthru) + ret %res +} + + +define <4 x i32> @masked_gather_v4i32(<4 x i32*> %ld, <4 x i1> %masks, <4 x i32> %passthru) { +; CHECK-LABEL: 'masked_gather_v4i32' +; CHECK: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + + %res = call <4 x i32> @llvm.masked.gather.v4i32(<4 x i32*> %ld, i32 0, <4 x i1> %masks, <4 x i32> %passthru) + ret <4 x i32> %res +} + + +declare @llvm.masked.gather.nxv4i32( %ptrs, i32 %align, %masks, %passthru) +declare <4 x i32> @llvm.masked.gather.v4i32(<4 x i32*> %ptrs, i32 %align, <4 x i1> %masks, <4 x i32> %passthru) diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-scatter.ll b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-scatter.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-getIntrinsicInstrCost-scatter.ll @@ -0,0 +1,31 @@ +; Check getIntrinsicInstrCost in BasicTTIImpl.h with for masked scatter + +; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s + +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + + +define void @masked_scatter_nxv4i32( %data, %ptrs, %masks) { +; CHECK-LABEL: 'masked_scatter_nxv4i32' +; CHECK: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + + call void @llvm.masked.scatter.nxv4i32( %data, %ptrs, i32 0, %masks) + ret void +} + + +define void @masked_scatter_v4i32(<4 x i32> %data, <4 x i32*> %ptrs, <4 x i1> %masks) { +; CHECK-LABEL: 'masked_scatter_v4i32' +; CHECK: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: +; CHECK-NEXT: Cost Model: Found an estimated cost of {{[0-9]+}} for instruction: + + call void @llvm.masked.scatter.v4i32(<4 x i32> %data, <4 x i32*> %ptrs, i32 0, <4 x i1> %masks) + ret void +} + +declare void @llvm.masked.scatter.nxv4i32( %data, %ptrs, i32 %align, %masks) +declare void @llvm.masked.scatter.v4i32(<4 x i32> %data, <4 x i32*> %ptrs, i32 %align, <4 x i1> %masks)