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 @@ -776,18 +776,22 @@ return LT.first * 2 * OpCost; } + // We cannot scalarize scalable vectors, so return Invalid. + if (isa(Ty)) + return InstructionCost::getInvalid(); + // Else, assume that we need to scalarize this op. // TODO: If one of the types get legalized by splitting, handle this // similarly to what getCastInstrCost() does. - if (auto *VTy = dyn_cast(Ty)) { - unsigned Num = cast(VTy)->getNumElements(); + if (auto *VTy = dyn_cast(Ty)) { InstructionCost Cost = thisT()->getArithmeticInstrCost( Opcode, VTy->getScalarType(), CostKind, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo, Args, CxtI); // Return the cost of multiple scalar invocation plus the cost of // inserting and extracting the values. SmallVector Tys(Args.size(), Ty); - return getScalarizationOverhead(VTy, Args, Tys) + Num * Cost; + return getScalarizationOverhead(VTy, Args, Tys) + + VTy->getNumElements() * Cost; } // We don't know anything about this scalar instruction. diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-remainder.ll b/llvm/test/Analysis/CostModel/AArch64/sve-remainder.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-remainder.ll @@ -0,0 +1,61 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py +; RUN: opt -cost-model -analyze -mtriple aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +define void @test_urem_srem_expand() { +; CHECK-LABEL: 'test_urem_srem_expand' +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_urem_0 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_urem_1 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_urem_2 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_urem_3 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_srem_0 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_srem_1 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_srem_2 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %legal_type_srem_3 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_urem_0 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_urem_1 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_urem_2 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_urem_3 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_srem_0 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_srem_1 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_srem_2 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %split_type_srem_3 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_urem_0 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_urem_1 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_urem_2 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_urem_3 = urem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_srem_0 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_srem_1 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_srem_2 = srem undef, undef +; CHECK-NEXT: Cost Model: Invalid cost for instruction: %widen_type_srem_3 = srem undef, undef +; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void +; +entry: + %legal_type_urem_0 = urem undef, undef + %legal_type_urem_1 = urem undef, undef + %legal_type_urem_2 = urem undef, undef + %legal_type_urem_3 = urem undef, undef + %legal_type_srem_0 = srem undef, undef + %legal_type_srem_1 = srem undef, undef + %legal_type_srem_2 = srem undef, undef + %legal_type_srem_3 = srem undef, undef + + %split_type_urem_0 = urem undef, undef + %split_type_urem_1 = urem undef, undef + %split_type_urem_2 = urem undef, undef + %split_type_urem_3 = urem undef, undef + %split_type_srem_0 = srem undef, undef + %split_type_srem_1 = srem undef, undef + %split_type_srem_2 = srem undef, undef + %split_type_srem_3 = srem undef, undef + + %widen_type_urem_0 = urem undef, undef + %widen_type_urem_1 = urem undef, undef + %widen_type_urem_2 = urem undef, undef + %widen_type_urem_3 = urem undef, undef + %widen_type_srem_0 = srem undef, undef + %widen_type_srem_1 = srem undef, undef + %widen_type_srem_2 = srem undef, undef + %widen_type_srem_3 = srem undef, undef + + ret void +}