Index: llvm/lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -994,8 +994,8 @@ // If type is to be expanded, split the vector. // <4 x i140> -> <2 x i140> if (LK.first == TypeExpandInteger) { - if (VT.getVectorElementCount() == ElementCount::getScalable(1)) - report_fatal_error("Cannot legalize this scalable vector"); + if (VT.getVectorElementCount().isScalable()) + return LegalizeKind(TypeScalarizeScalableVector, EltVT); return LegalizeKind(TypeSplitVector, VT.getHalfNumVectorElementsVT(Context)); } @@ -1058,7 +1058,7 @@ } if (VT.getVectorElementCount() == ElementCount::getScalable(1)) - report_fatal_error("Cannot legalize this vector"); + return LegalizeKind(TypeScalarizeScalableVector, EltVT); // Vectors with illegal element types are expanded. EVT NVT = EVT::getVectorVT(Context, EltVT, @@ -1823,6 +1823,9 @@ while (true) { LegalizeKind LK = getTypeConversion(C, MTy); + if (LK.first == TypeScalarizeScalableVector) + return std::make_pair(InstructionCost::getInvalid(), MVT::getVT(Ty)); + if (LK.first == TypeLegal) return std::make_pair(Cost, MTy.getSimpleVT()); Index: llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -1180,6 +1180,9 @@ return BaseT::getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace, CostKind); auto LT = TLI->getTypeLegalizationCost(DL, Src); + if (!LT.first.isValid()) + return LT.first; + return LT.first * 2; } @@ -1192,6 +1195,9 @@ Alignment, CostKind, I); auto *VT = cast(DataTy); auto LT = TLI->getTypeLegalizationCost(DL, DataTy); + if (!LT.first.isValid()) + return LT.first; + ElementCount LegalVF = LT.second.getVectorElementCount(); Optional MaxNumVScale = getMaxVScale(); assert(MaxNumVScale && "Expected valid max vscale value"); @@ -1218,6 +1224,8 @@ CostKind); auto LT = TLI->getTypeLegalizationCost(DL, Ty); + if (!LT.first.isValid()) + return LT.first; // TODO: consider latency as well for TCK_SizeAndLatency. if (CostKind == TTI::TCK_CodeSize || CostKind == TTI::TCK_SizeAndLatency) Index: llvm/test/Analysis/CostModel/AArch64/sve-illegal-types.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/CostModel/AArch64/sve-illegal-types.ll @@ -0,0 +1,49 @@ +; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s + +define @load_nxvi128(* %val) { +; CHECK-LABEL: 'load_nxvi128' +; CHECK-NEXT: Invalid cost for instruction: %load = load , * %val + %load = load , * %val + ret %load +} + +define void @store_nxvi128(* %ptrs, %val) { +; CHECK-LABEL: 'store_nxvi128' +; CHECK-NEXT: Invalid cost for instruction: store %val, * %ptrs + store %val, * %ptrs + ret void +} + +define @masked_load_nxvfp128(* %val, %mask, %passthru) { +; CHECK-LABEL: 'masked_load_nxvfp128' +; CHECK-NEXT: Invalid cost for instruction: %mload = call @llvm.masked.load.nxv4f128.p0nxv4f128(* %val, i32 8, %mask, %passthru) + %mload = call @llvm.masked.load.nxv4f128(* %val, i32 8, %mask, %passthru) + ret %mload +} + +define void @masked_store_nxvfp128( %val, * %ptrs, %mask) { +; CHECK-LABEL: 'masked_store_nxvfp128' +; CHECK-NEXT: Invalid cost for instruction: call void @llvm.masked.store.nxv4f128.p0nxv4f128( %val, * %ptrs, i32 8, %mask) + call void @llvm.masked.store.nxv4f128( %val, * %ptrs, i32 8, %mask) + ret void +} + +define @masked_gather_nxv2i128( %ld, %masks, %passthru) { +; CHECK-LABEL: 'masked_gather_nxv2i128' +; CHECK-NEXT: Invalid cost for instruction: %mgather = call @llvm.masked.gather.nxv2i128.nxv2p0i128( %ld, i32 0, %masks, %passthru) + %mgather = call @llvm.masked.gather.nxv2i128( %ld, i32 0, %masks, %passthru) + ret %mgather +} + +define void @masked_scatter_nxv4i128( %val, %ptrs, %masks) { +; CHECK-LABEL: 'masked_scatter_nxv4i128' +; CHECK-NEXT: Invalid cost for instruction: call void @llvm.masked.scatter.nxv4i128.nxv4p0i128( %val, %ptrs, i32 0, %masks) + call void @llvm.masked.scatter.nxv4i128( %val, %ptrs, i32 0, %masks) + ret void +} + +declare @llvm.masked.load.nxv4f128(*, i32, , ) +declare @llvm.masked.gather.nxv2i128(, i32, , ) + +declare void @llvm.masked.store.nxv4f128(, *, i32, ) +declare void @llvm.masked.scatter.nxv4i128(, , i32, )