Skip to content

[TLI] Use the VFABI demangling when declaring vector variants. #76753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Type *, 4> 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<VFInfo> 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;
Expand Down Expand Up @@ -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);
}
};

Expand Down
26 changes: 26 additions & 0 deletions llvm/test/Transforms/Util/add-TLI-mappings.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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 <vscale x 2 x double> @_ZGVsMxv_sin(<vscale x 2 x double>, <vscale x 2 x i1>)
; SLEEFGNUABI: declare <4 x float> @_ZGVnN4v_log10f(<4 x float>)
; SLEEFGNUABI: declare <vscale x 4 x float> @_ZGVsMxv_log10f(<vscale x 4 x float>, <vscale x 4 x i1>)

; ARMPL: declare <2 x double> @armpl_vsinq_f64(<2 x double>)
; ARMPL: declare <vscale x 2 x double> @armpl_svsin_f64_x(<vscale x 2 x double>, <vscale x 2 x i1>)
; ARMPL: declare <4 x float> @armpl_vlog10q_f32(<4 x float>)
; ARMPL: declare <vscale x 4 x float> @armpl_svlog10_f32_x(<vscale x 4 x float>, <vscale x 4 x i1>)

attributes #0 = { nounwind readnone }

; SVML: attributes #[[SIN]] = { "vector-function-abi-variant"=
Expand Down