diff --git a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp index 0990c750af55f..ea31356306658 100644 --- a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp +++ b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp @@ -33,37 +33,37 @@ STATISTIC(NumVFDeclAdded, STATISTIC(NumCompUsedAdded, "Number of `@llvm.compiler.used` operands that have been added."); -/// A helper function that adds the vector function declaration that -/// vectorizes the CallInst CI with a vectorization factor of VF -/// lanes. The TLI assumes that all parameters and the return type of -/// CI (other than void) need to be widened to a VectorType of VF -/// lanes. +/// A helper function that adds the vector variant declaration for vectorizing +/// the CallInst \p CI with a vectorization factor of \p VF lanes. For each +/// mapping, TLI provides a VABI prefix, which contains all information required +/// to create vector function declaration. static void addVariantDeclaration(CallInst &CI, const ElementCount &VF, - bool Predicate, const StringRef VFName) { + const VecDesc *VD) { Module *M = CI.getModule(); + FunctionType *ScalarFTy = CI.getFunctionType(); - // Add function declaration. - Type *RetTy = ToVectorTy(CI.getType(), VF); - SmallVector Tys; - for (Value *ArgOperand : CI.args()) - Tys.push_back(ToVectorTy(ArgOperand->getType(), VF)); - assert(!CI.getFunctionType()->isVarArg() && - "VarArg functions are not supported."); - if (Predicate) - Tys.push_back(ToVectorTy(Type::getInt1Ty(RetTy->getContext()), VF)); - FunctionType *FTy = FunctionType::get(RetTy, Tys, /*isVarArg=*/false); - Function *VectorF = - Function::Create(FTy, Function::ExternalLinkage, VFName, M); - VectorF->copyAttributesFrom(CI.getCalledFunction()); + assert(!ScalarFTy->isVarArg() && "VarArg functions are not supported."); + + const std::optional Info = VFABI::tryDemangleForVFABI( + VD->getVectorFunctionABIVariantString(), ScalarFTy); + + assert(Info && "Failed to demangle vector variant"); + assert(Info->Shape.VF == VF && "Mangled name does not match VF"); + + const StringRef VFName = VD->getVectorFnName(); + FunctionType *VectorFTy = VFABI::createFunctionType(*Info, ScalarFTy); + Function *VecFunc = + Function::Create(VectorFTy, Function::ExternalLinkage, VFName, M); + VecFunc->copyAttributesFrom(CI.getCalledFunction()); ++NumVFDeclAdded; LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added to the module: `" << VFName - << "` of type " << *(VectorF->getType()) << "\n"); + << "` of type " << *VectorFTy << "\n"); // Make function declaration (without a body) "sticky" in the IR by // listing it in the @llvm.compiler.used intrinsic. - assert(!VectorF->size() && "VFABI attribute requires `@llvm.compiler.used` " + assert(!VecFunc->size() && "VFABI attribute requires `@llvm.compiler.used` " "only on declarations."); - appendToCompilerUsed(*M, {VectorF}); + appendToCompilerUsed(*M, {VecFunc}); LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << VFName << "` to `@llvm.compiler.used`.\n"); ++NumCompUsedAdded; @@ -100,7 +100,7 @@ static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) { } Function *VariantF = M->getFunction(VD->getVectorFnName()); if (!VariantF) - addVariantDeclaration(CI, VF, Predicate, VD->getVectorFnName()); + addVariantDeclaration(CI, VF, VD); } }; diff --git a/llvm/test/Transforms/Util/add-TLI-mappings.ll b/llvm/test/Transforms/Util/add-TLI-mappings.ll index a40798665a50d..67ca00b8e2cf4 100644 --- a/llvm/test/Transforms/Util/add-TLI-mappings.ll +++ b/llvm/test/Transforms/Util/add-TLI-mappings.ll @@ -65,6 +65,32 @@ define float @call_llvm.log10.f32(float %in) { } declare float @llvm.log10.f32(float) #0 + +; SVML: declare <2 x double> @__svml_sin2(<2 x double>) +; SVML: declare <4 x double> @__svml_sin4(<4 x double>) +; SVML: declare <8 x double> @__svml_sin8(<8 x double>) +; SVML: declare <4 x float> @__svml_log10f4(<4 x float>) +; SVML: declare <8 x float> @__svml_log10f8(<8 x float>) +; SVML: declare <16 x float> @__svml_log10f16(<16 x float>) + +; MASSV: declare <2 x double> @__sind2(<2 x double>) +; MASSV: declare <4 x float> @__log10f4(<4 x float>) + +; LIBMVEC-X86: declare <2 x double> @_ZGVbN2v_sin(<2 x double>) +; LIBMVEC-X86: declare <4 x double> @_ZGVdN4v_sin(<4 x double>) + +; ACCELERATE: declare <4 x float> @vlog10f(<4 x float>) + +; SLEEFGNUABI: declare <2 x double> @_ZGVnN2v_sin(<2 x double>) +; SLEEFGNUABI: declare @_ZGVsMxv_sin(, ) +; SLEEFGNUABI: declare <4 x float> @_ZGVnN4v_log10f(<4 x float>) +; SLEEFGNUABI: declare @_ZGVsMxv_log10f(, ) + +; ARMPL: declare <2 x double> @armpl_vsinq_f64(<2 x double>) +; ARMPL: declare @armpl_svsin_f64_x(, ) +; ARMPL: declare <4 x float> @armpl_vlog10q_f32(<4 x float>) +; ARMPL: declare @armpl_svlog10_f32_x(, ) + attributes #0 = { nounwind readnone } ; SVML: attributes #[[SIN]] = { "vector-function-abi-variant"=