Skip to content

Commit 38db22f

Browse files
committed
Fix mechanism propagating mangled names for TLI function mappings
Currently the mappings from TLI are used to generate the list of available "scalar to vector" mappings attached to scalar calls as "vector-function-abi-variant" LLVM IR attribute. Function names from TLI are wrapped in mangled name following the pattern: _ZGV<isa><mask><vlen><parameters>_<scalar_name>[(<vector_redirection>)] The problem is the mangled name uses _LLVM_ as the ISA name which prevents the compiler to compute vectorization factor for scalable vectors as it cannot make any decision based on the _LLVM_ ISA. If we use "s" as the ISA name, the compiler can make decisions based on VFABI specification where SVE spacific rules are described. This patch is only a refactoring stage where there is no change to the compiler's behaviour.
1 parent e52899e commit 38db22f

File tree

8 files changed

+711
-744
lines changed

8 files changed

+711
-744
lines changed

llvm/include/llvm/Analysis/TargetLibraryInfo.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,25 @@ class Triple;
2727
/// Describes a possible vectorization of a function.
2828
/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
2929
/// by a factor 'VectorizationFactor'.
30+
/// The MangledName string holds scalar-to-vector mapping:
31+
/// _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
32+
///
33+
/// where:
34+
///
35+
/// <isa> = "_LLVM_"
36+
/// <mask> = "M" if masked, "N" if no mask.
37+
/// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
38+
/// field of the `VecDesc` struct. If the number of lanes is scalable
39+
/// then 'x' is printed instead.
40+
/// <vparams> = "v", as many as are the numArgs.
41+
/// <scalarname> = the name of the scalar function.
42+
/// <vectorname> = the name of the vector function.
3043
struct VecDesc {
3144
StringRef ScalarFnName;
3245
StringRef VectorFnName;
3346
ElementCount VectorizationFactor;
3447
bool Masked;
48+
StringRef MangledName;
3549
};
3650

3751
enum LibFunc : unsigned {
@@ -163,18 +177,18 @@ class TargetLibraryInfoImpl {
163177
/// Return true if the function F has a vector equivalent with vectorization
164178
/// factor VF.
165179
bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
166-
return !(getVectorizedFunction(F, VF, false).empty() &&
167-
getVectorizedFunction(F, VF, true).empty());
180+
return !(getVectorizedFunction(F, VF, false).first.empty() &&
181+
getVectorizedFunction(F, VF, true).first.empty());
168182
}
169183

170184
/// Return true if the function F has a vector equivalent with any
171185
/// vectorization factor.
172186
bool isFunctionVectorizable(StringRef F) const;
173187

174-
/// Return the name of the equivalent of F, vectorized with factor VF. If no
175-
/// such mapping exists, return the empty string.
176-
StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
177-
bool Masked) const;
188+
/// Return the name of the equivalent of F, vectorized with factor VF and it's
189+
/// mangled name. If no such mapping exists, return empty strings.
190+
std::pair<StringRef, StringRef>
191+
getVectorizedFunction(StringRef F, const ElementCount &VF, bool Masked) const;
178192

179193
/// Set to true iff i32 parameters to library functions should have signext
180194
/// or zeroext attributes if they correspond to C-level int or unsigned int,
@@ -350,8 +364,9 @@ class TargetLibraryInfo {
350364
bool isFunctionVectorizable(StringRef F) const {
351365
return Impl->isFunctionVectorizable(F);
352366
}
353-
StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
354-
bool Masked = false) const {
367+
std::pair<StringRef, StringRef>
368+
getVectorizedFunction(StringRef F, const ElementCount &VF,
369+
bool Masked = false) const {
355370
return Impl->getVectorizedFunction(F, VF, Masked);
356371
}
357372

llvm/include/llvm/Analysis/VecFuncs.def

Lines changed: 667 additions & 667 deletions
Large diffs are not rendered by default.

llvm/include/llvm/Analysis/VectorUtils.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -182,27 +182,6 @@ static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
182182
std::optional<VFInfo> tryDemangleForVFABI(StringRef MangledName,
183183
const Module &M);
184184

185-
/// This routine mangles the given VectorName according to the LangRef
186-
/// specification for vector-function-abi-variant attribute and is specific to
187-
/// the TLI mappings. It is the responsibility of the caller to make sure that
188-
/// this is only used if all parameters in the vector function are vector type.
189-
/// This returned string holds scalar-to-vector mapping:
190-
/// _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
191-
///
192-
/// where:
193-
///
194-
/// <isa> = "_LLVM_"
195-
/// <mask> = "M" if masked, "N" if no mask.
196-
/// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
197-
/// field of the `VecDesc` struct. If the number of lanes is scalable
198-
/// then 'x' is printed instead.
199-
/// <vparams> = "v", as many as are the numArgs.
200-
/// <scalarname> = the name of the scalar function.
201-
/// <vectorname> = the name of the vector function.
202-
std::string mangleTLIVectorName(StringRef VectorName, StringRef ScalarName,
203-
unsigned numArgs, ElementCount VF,
204-
bool Masked = false);
205-
206185
/// Retrieve the `VFParamKind` from a string token.
207186
VFParamKind getVFParamKindFromString(const StringRef Token);
208187

llvm/lib/Analysis/TargetLibraryInfo.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,17 +1203,20 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
12031203
case SLEEFGNUABI: {
12041204
const VecDesc VecFuncs_VF2[] = {
12051205
#define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS
1206-
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF) {SCAL, VEC, VF, /* MASK = */ false},
1206+
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MANGLN) \
1207+
{SCAL, VEC, VF, /* MASK = */ false, MANGLN},
12071208
#include "llvm/Analysis/VecFuncs.def"
12081209
};
12091210
const VecDesc VecFuncs_VF4[] = {
12101211
#define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS
1211-
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF) {SCAL, VEC, VF, /* MASK = */ false},
1212+
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MANGLN) \
1213+
{SCAL, VEC, VF, /* MASK = */ false, MANGLN},
12121214
#include "llvm/Analysis/VecFuncs.def"
12131215
};
12141216
const VecDesc VecFuncs_VFScalable[] = {
12151217
#define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS
1216-
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK) {SCAL, VEC, VF, MASK},
1218+
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, MANGLN) \
1219+
{SCAL, VEC, VF, MASK, MANGLN},
12171220
#include "llvm/Analysis/VecFuncs.def"
12181221
};
12191222

@@ -1232,7 +1235,8 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
12321235
case ArmPL: {
12331236
const VecDesc VecFuncs[] = {
12341237
#define TLI_DEFINE_ARMPL_VECFUNCS
1235-
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK) {SCAL, VEC, VF, MASK},
1238+
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, MANGLN) \
1239+
{SCAL, VEC, VF, MASK, MANGLN},
12361240
#include "llvm/Analysis/VecFuncs.def"
12371241
};
12381242

@@ -1261,20 +1265,19 @@ bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
12611265
return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName;
12621266
}
12631267

1264-
StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
1265-
const ElementCount &VF,
1266-
bool Masked) const {
1268+
std::pair<StringRef, StringRef> TargetLibraryInfoImpl::getVectorizedFunction(
1269+
StringRef F, const ElementCount &VF, bool Masked) const {
12671270
F = sanitizeFunctionName(F);
12681271
if (F.empty())
1269-
return F;
1272+
return std::make_pair(F, StringRef());
12701273
std::vector<VecDesc>::const_iterator I =
12711274
llvm::lower_bound(VectorDescs, F, compareWithScalarFnName);
12721275
while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) {
12731276
if ((I->VectorizationFactor == VF) && (I->Masked == Masked))
1274-
return I->VectorFnName;
1277+
return std::make_pair(I->VectorFnName, I->MangledName);
12751278
++I;
12761279
}
1277-
return StringRef();
1280+
return std::make_pair(StringRef(), StringRef());
12781281
}
12791282

12801283
TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F,

llvm/lib/Analysis/VectorUtils.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,22 +1453,6 @@ void InterleaveGroup<Instruction>::addMetadata(Instruction *NewInst) const {
14531453
}
14541454
}
14551455

1456-
std::string VFABI::mangleTLIVectorName(StringRef VectorName,
1457-
StringRef ScalarName, unsigned numArgs,
1458-
ElementCount VF, bool Masked) {
1459-
SmallString<256> Buffer;
1460-
llvm::raw_svector_ostream Out(Buffer);
1461-
Out << "_ZGV" << VFABI::_LLVM_ << (Masked ? "M" : "N");
1462-
if (VF.isScalable())
1463-
Out << 'x';
1464-
else
1465-
Out << VF.getFixedValue();
1466-
for (unsigned I = 0; I < numArgs; ++I)
1467-
Out << "v";
1468-
Out << "_" << ScalarName << "(" << VectorName << ")";
1469-
return std::string(Out.str());
1470-
}
1471-
14721456
void VFABI::getVectorVariantNames(
14731457
const CallInst &CI, SmallVectorImpl<std::string> &VariantMappings) {
14741458
const StringRef S = CI.getFnAttr(VFABI::MappingsAttrName).getValueAsString();

llvm/lib/CodeGen/ReplaceWithVeclib.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
155155
// Try to find the mapping for the scalar version of this intrinsic
156156
// and the exact vector width of the call operands in the
157157
// TargetLibraryInfo.
158-
const std::string TLIName =
159-
std::string(TLI.getVectorizedFunction(ScalarName, VF));
158+
StringRef TLIName = TLI.getVectorizedFunction(ScalarName, VF).first;
160159

161160
LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Looking up TLI mapping for `"
162161
<< ScalarName << "` and vector width " << VF << ".\n");

llvm/lib/Transforms/Utils/InjectTLIMappings.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,13 @@ static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
9191
Mappings.end());
9292

9393
auto AddVariantDecl = [&](const ElementCount &VF, bool Predicate) {
94-
const std::string TLIName =
95-
std::string(TLI.getVectorizedFunction(ScalarName, VF, Predicate));
96-
if (!TLIName.empty()) {
97-
std::string MangledName = VFABI::mangleTLIVectorName(
98-
TLIName, ScalarName, CI.arg_size(), VF, Predicate);
99-
if (!OriginalSetOfMappings.count(MangledName)) {
100-
Mappings.push_back(MangledName);
94+
StringRef TLIName;
95+
StringRef MangledName;
96+
std::tie(TLIName, MangledName) =
97+
TLI.getVectorizedFunction(ScalarName, VF, Predicate);
98+
if (!TLIName.empty() && !MangledName.empty()) {
99+
if (!OriginalSetOfMappings.count(std::string(MangledName))) {
100+
Mappings.push_back(std::string(MangledName));
101101
++NumCallInjected;
102102
}
103103
Function *VariantF = M->getFunction(TLIName);

llvm/unittests/Analysis/VectorFunctionABITest.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,6 @@ class VFABIParserTest : public ::testing::Test {
9898
};
9999
} // unnamed namespace
100100

101-
// This test makes sure correct mangling occurs for given string.
102-
TEST_F(VFABIParserTest, ManglingVectorTLINames) {
103-
EXPECT_EQ(
104-
VFABI::mangleTLIVectorName("vec", "scalar", 3, ElementCount::getFixed(4)),
105-
"_ZGV_LLVM_N4vvv_scalar(vec)");
106-
EXPECT_EQ(VFABI::mangleTLIVectorName("vec", "scalar", 3,
107-
ElementCount::getScalable(4)),
108-
"_ZGV_LLVM_Nxvvv_scalar(vec)");
109-
EXPECT_EQ(VFABI::mangleTLIVectorName("custom.call.v5", "custom.call", 1,
110-
ElementCount::getFixed(5)),
111-
"_ZGV_LLVM_N5v_custom.call(custom.call.v5)");
112-
}
113-
114101
// This test makes sure that the demangling method succeeds only on
115102
// valid values of the string.
116103
TEST_F(VFABIParserTest, OnlyValidNames) {

0 commit comments

Comments
 (0)