Skip to content

Commit

Permalink
[TLI] Use the VFABI demangling when declaring vector variants. (#76753)
Browse files Browse the repository at this point in the history
When creating a declaration for a vector variant, in order to determine
the argument types we need to consult the VFABI demangler. This will
allow us to add TLI mappings with linear arguments (see #76060).
  • Loading branch information
labrinea committed Jan 3, 2024
1 parent a93c17c commit ec7a231
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 23 deletions.
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

0 comments on commit ec7a231

Please sign in to comment.