Commit 623cff81 authored by Francesco Petrogalli's avatar Francesco Petrogalli
Browse files

[llvm][VectorUtils] Tweak VFShape for scalable vector functions.

Summary:
This patch makes sure that the field VFShape.VF is greater than zero
when demangling the vector function name of scalable vector functions
encoded in the "vector-function-abi-variant" attribute.

This change is required to be able to provide instances of VFShape
that can be used to query the VFDatabase for the vectorization passes,
as such passes always require a positive value for the Vectorization Factor (VF)
needed by the vectorization process.

It is not possible to extract the value of VFShape.VF from the mangled
name of scalable vector functions, because it is encoded as
`x`. Therefore, the VFABI demangling function has been modified to
extract such information from the IR declaration of the vector
function, under the assumption that _all_ vectors in the signature of
the vector function have the same number of lanes. Such assumption is
valid because it is also assumed by the Vector Function ABI
specifications supported by the demangling function (x86, AArch64, and
LLVM internal one).

The unit tests that demangle scalable names have been modified by
adding the IR module that carries the declaration of the vector
function name being demangled.

In particular, the demangling function fails in the following cases:

1. When the declaration of the scalable vector function is not
    present in the module.

2. When the value of VFSHape.VF is not greater than 0.

Reviewers: jdoerfert, sdesmalen, andwar

Reviewed By: jdoerfert

Subscribers: mgorny, kristof.beyls, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73286
parent 12c185ac
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -161,7 +161,12 @@ static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
///
/// \param MangledName -> input string in the format
/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
Optional<VFInfo> tryDemangleForVFABI(StringRef MangledName);
/// \param M -> Module used to retrive informations about the vector
/// function that are not possible to retrieve from the mangled
/// name. At the moment, this parameter is needed only to retrive the
/// Vectorization Factor of scalable vector functions from their
/// respective IR declarations.
Optional<VFInfo> tryDemangleForVFABI(StringRef MangledName, const Module &M);

/// Retrieve the `VFParamKind` from a string token.
VFParamKind getVFParamKindFromString(const StringRef Token);
@@ -200,7 +205,8 @@ class VFDatabase {
    SmallVector<std::string, 8> ListOfStrings;
    VFABI::getVectorVariantNames(CI, ListOfStrings);
    for (const auto &MangledName : ListOfStrings) {
      const Optional<VFInfo> Shape = VFABI::tryDemangleForVFABI(MangledName);
      const Optional<VFInfo> Shape =
          VFABI::tryDemangleForVFABI(MangledName, *(CI.getModule()));
      // A match is found via scalar and vector names, and also by
      // ensuring that the variant described in the attribute has a
      // corresponding definition or declaration of the vector
+73 −1
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ ParseRet tryParseMask(StringRef &MangledName, bool &IsMasked) {
///
ParseRet tryParseVLEN(StringRef &ParseString, unsigned &VF, bool &IsScalable) {
  if (ParseString.consume_front("x")) {
    // Set VF to 0, to be later adjusted to a value grater than zero
    // by looking at the signature of the vector function with
    // `getECFromSignature`.
    VF = 0;
    IsScalable = true;
    return ParseRet::OK;
@@ -78,6 +81,10 @@ ParseRet tryParseVLEN(StringRef &ParseString, unsigned &VF, bool &IsScalable) {
  if (ParseString.consumeInteger(10, VF))
    return ParseRet::Error;

  // The token `0` is invalid for VLEN.
  if (VF == 0)
    return ParseRet::Error;

  IsScalable = false;
  return ParseRet::OK;
}
@@ -287,11 +294,50 @@ ParseRet tryParseAlign(StringRef &ParseString, Align &Alignment) {

  return ParseRet::None;
}
#ifndef NDEBUG
// Verify the assumtion that all vectors in the signature of a vector
// function have the same number of elements.
bool verifyAllVectorsHaveSameWidth(FunctionType *Signature) {
  SmallVector<VectorType *, 2> VecTys;
  if (auto *RetTy = dyn_cast<VectorType>(Signature->getReturnType()))
    VecTys.push_back(RetTy);
  for (auto *Ty : Signature->params())
    if (auto *VTy = dyn_cast<VectorType>(Ty))
      VecTys.push_back(VTy);

  if (VecTys.size() <= 1)
    return true;

  assert(VecTys.size() > 1 && "Invalid number of elements.");
  const ElementCount EC = VecTys[0]->getElementCount();
  return llvm::all_of(
      llvm::make_range(VecTys.begin() + 1, VecTys.end()),
      [&EC](VectorType *VTy) { return (EC == VTy->getElementCount()); });
}

#endif // NDEBUG

// Extract the VectorizationFactor from a given function signature,
// under the assumtion that all vectors have the same number of
// elements, i.e. same ElementCount.Min.
ElementCount getECFromSignature(FunctionType *Signature) {
  assert(verifyAllVectorsHaveSameWidth(Signature) &&
         "Invalid vector signature.");

  if (auto *RetTy = dyn_cast<VectorType>(Signature->getReturnType()))
    return RetTy->getElementCount();
  for (auto *Ty : Signature->params())
    if (auto *VTy = dyn_cast<VectorType>(Ty))
      return VTy->getElementCount();

  return ElementCount(/*Min=*/1, /*Scalable=*/false);
}
} // namespace

// Format of the ABI name:
// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
Optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName) {
Optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName,
                                            const Module &M) {
  const StringRef OriginalName = MangledName;
  // Assume there is no custom name <redirection>, and therefore the
  // vector name consists of
@@ -402,6 +448,32 @@ Optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName) {
    assert(Parameters.back().ParamKind == VFParamKind::GlobalPredicate &&
           "The global predicate must be the last parameter");

  // Adjust the VF for scalable signatures. The EC.Min is not encoded
  // in the name of the function, but it is encoded in the IR
  // signature of the function. We need to extract this information
  // because it is needed by the loop vectorizer, which reasons in
  // terms of VectorizationFactor or ElementCount. In particular, we
  // need to make sure that the VF field of the VFShape class is never
  // set to 0.
  if (IsScalable) {
    const Function *F = M.getFunction(VectorName);
    // The declaration of the function must be present in the module
    // to be able to retrieve its signature.
    if (!F)
      return None;
    const ElementCount EC = getECFromSignature(F->getFunctionType());
    VF = EC.Min;
  }

  // Sanity checks.
  // 1. We don't accept a zero lanes vectorization factor.
  // 2. We don't accept the demangling if the vector function is not
  // present in the module.
  if (VF == 0)
    return None;
  if (!M.getFunction(VectorName))
    return None;

  const VFShape Shape({VF, IsScalable, Parameters});
  return VFInfo({Shape, std::string(ScalarName), std::string(VectorName), ISA});
}
+1 −1
Original line number Diff line number Diff line
@@ -1175,7 +1175,7 @@ void VFABI::getVectorVariantNames(
  for (auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) {
#ifndef NDEBUG
    LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << S << "'\n");
    Optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S);
    Optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S, *(CI.getModule()));
    assert(Info.hasValue() && "Invalid name for a VFABI variant.");
    assert(CI.getModule()->getFunction(Info.getValue().VectorName) &&
           "Vector function is missing.");
+1 −1
Original line number Diff line number Diff line
@@ -301,7 +301,7 @@ void VFABI::setVectorVariantNames(
#ifndef NDEBUG
  for (const std::string &VariantMapping : VariantMappings) {
    LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
    Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping);
    Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *M);
    assert(VI.hasValue() && "Cannot add an invalid VFABI name.");
    assert(M->getNamedValue(VI.getValue().VectorName) &&
           "Cannot add variant to attribute: "
+2 −0
Original line number Diff line number Diff line
set(LLVM_LINK_COMPONENTS
  Analysis
  AsmParser
  Core
  Support
)
add_llvm_fuzzer(vfabi-demangler-fuzzer
Loading