[llvm] [VFABI] Move the Vector ABI demangling utility to LLVMCore. (PR #77513)

Alexandros Lamprineas via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 9 11:10:46 PST 2024


https://github.com/labrinea created https://github.com/llvm/llvm-project/pull/77513

This fixes #71892 allowing us to check magled names in the IR verifier.

>From 1e5330c25d3721f6ff5a6e136647584b3b5b4101 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas <alexandros.lamprineas at arm.com>
Date: Tue, 9 Jan 2024 18:55:09 +0000
Subject: [PATCH] [VFABI] Move the Vector ABI demangling utility to LLVMCore.

This fixes #71892 allowing us to check magled names in the IR verifier.
---
 llvm/include/llvm/Analysis/VectorUtils.h      | 187 +--------------
 llvm/include/llvm/IR/VFABIDemangler.h         | 217 ++++++++++++++++++
 .../llvm/Transforms/Utils/ModuleUtils.h       |   6 -
 llvm/lib/Analysis/CMakeLists.txt              |   1 -
 llvm/lib/Analysis/VectorUtils.cpp             |  90 --------
 llvm/lib/CodeGen/ReplaceWithVeclib.cpp        |   1 +
 llvm/lib/IR/CMakeLists.txt                    |   1 +
 .../VFABIDemangler.cpp}                       | 130 ++++++++++-
 llvm/lib/IR/Verifier.cpp                      |   8 +
 .../Transforms/Utils/InjectTLIMappings.cpp    |   1 +
 llvm/lib/Transforms/Utils/ModuleUtils.cpp     |  29 ---
 .../LoopVectorize/AArch64/scalable-call.ll    |   2 +-
 .../Verifier/vector-function-abi-variant.ll   |  16 ++
 .../vfabi-demangler-fuzzer.cpp                |   2 +-
 llvm/unittests/Analysis/CMakeLists.txt        |   1 -
 llvm/unittests/IR/CMakeLists.txt              |   1 +
 .../VFABIDemanglerTest.cpp}                   |  18 +-
 .../unittests/Transforms/Utils/CMakeLists.txt |   1 -
 .../unittests/Transforms/Utils/VFABIUtils.cpp |  52 -----
 .../gn/secondary/llvm/lib/Analysis/BUILD.gn   |   1 -
 llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn  |   1 +
 .../llvm/unittests/Analysis/BUILD.gn          |   1 -
 .../gn/secondary/llvm/unittests/IR/BUILD.gn   |   1 +
 .../llvm/unittests/Transforms/Utils/BUILD.gn  |   1 -
 24 files changed, 392 insertions(+), 377 deletions(-)
 create mode 100644 llvm/include/llvm/IR/VFABIDemangler.h
 rename llvm/lib/{Analysis/VFABIDemangling.cpp => IR/VFABIDemangler.cpp} (80%)
 create mode 100644 llvm/test/Verifier/vector-function-abi-variant.ll
 rename llvm/unittests/{Analysis/VectorFunctionABITest.cpp => IR/VFABIDemanglerTest.cpp} (98%)
 delete mode 100644 llvm/unittests/Transforms/Utils/VFABIUtils.cpp

diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index b1ecc8777c1698..7a92e62b53c53d 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -16,197 +16,12 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/LoopAccessAnalysis.h"
+#include "llvm/IR/VFABIDemangler.h"
 #include "llvm/Support/CheckedArithmetic.h"
 
 namespace llvm {
 class TargetLibraryInfo;
 
-/// Describes the type of Parameters
-enum class VFParamKind {
-  Vector,            // No semantic information.
-  OMP_Linear,        // declare simd linear(i)
-  OMP_LinearRef,     // declare simd linear(ref(i))
-  OMP_LinearVal,     // declare simd linear(val(i))
-  OMP_LinearUVal,    // declare simd linear(uval(i))
-  OMP_LinearPos,     // declare simd linear(i:c) uniform(c)
-  OMP_LinearValPos,  // declare simd linear(val(i:c)) uniform(c)
-  OMP_LinearRefPos,  // declare simd linear(ref(i:c)) uniform(c)
-  OMP_LinearUValPos, // declare simd linear(uval(i:c)) uniform(c)
-  OMP_Uniform,       // declare simd uniform(i)
-  GlobalPredicate,   // Global logical predicate that acts on all lanes
-                     // of the input and output mask concurrently. For
-                     // example, it is implied by the `M` token in the
-                     // Vector Function ABI mangled name.
-  Unknown
-};
-
-/// Describes the type of Instruction Set Architecture
-enum class VFISAKind {
-  AdvancedSIMD, // AArch64 Advanced SIMD (NEON)
-  SVE,          // AArch64 Scalable Vector Extension
-  SSE,          // x86 SSE
-  AVX,          // x86 AVX
-  AVX2,         // x86 AVX2
-  AVX512,       // x86 AVX512
-  LLVM,         // LLVM internal ISA for functions that are not
-  // attached to an existing ABI via name mangling.
-  Unknown // Unknown ISA
-};
-
-/// Encapsulates information needed to describe a parameter.
-///
-/// The description of the parameter is not linked directly to
-/// OpenMP or any other vector function description. This structure
-/// is extendible to handle other paradigms that describe vector
-/// functions and their parameters.
-struct VFParameter {
-  unsigned ParamPos;         // Parameter Position in Scalar Function.
-  VFParamKind ParamKind;     // Kind of Parameter.
-  int LinearStepOrPos = 0;   // Step or Position of the Parameter.
-  Align Alignment = Align(); // Optional alignment in bytes, defaulted to 1.
-
-  // Comparison operator.
-  bool operator==(const VFParameter &Other) const {
-    return std::tie(ParamPos, ParamKind, LinearStepOrPos, Alignment) ==
-           std::tie(Other.ParamPos, Other.ParamKind, Other.LinearStepOrPos,
-                    Other.Alignment);
-  }
-};
-
-/// Contains the information about the kind of vectorization
-/// available.
-///
-/// This object in independent on the paradigm used to
-/// represent vector functions. in particular, it is not attached to
-/// any target-specific ABI.
-struct VFShape {
-  ElementCount VF;                        // Vectorization factor.
-  SmallVector<VFParameter, 8> Parameters; // List of parameter information.
-  // Comparison operator.
-  bool operator==(const VFShape &Other) const {
-    return std::tie(VF, Parameters) == std::tie(Other.VF, Other.Parameters);
-  }
-
-  /// Update the parameter in position P.ParamPos to P.
-  void updateParam(VFParameter P) {
-    assert(P.ParamPos < Parameters.size() && "Invalid parameter position.");
-    Parameters[P.ParamPos] = P;
-    assert(hasValidParameterList() && "Invalid parameter list");
-  }
-
-  /// Retrieve the VFShape that can be used to map a scalar function to itself,
-  /// with VF = 1.
-  static VFShape getScalarShape(const FunctionType *FTy) {
-    return VFShape::get(FTy, ElementCount::getFixed(1),
-                        /*HasGlobalPredicate*/ false);
-  }
-
-  /// Retrieve the basic vectorization shape of the function, where all
-  /// parameters are mapped to VFParamKind::Vector with \p EC lanes. Specifies
-  /// whether the function has a Global Predicate argument via \p HasGlobalPred.
-  static VFShape get(const FunctionType *FTy, ElementCount EC,
-                     bool HasGlobalPred) {
-    SmallVector<VFParameter, 8> Parameters;
-    for (unsigned I = 0; I < FTy->getNumParams(); ++I)
-      Parameters.push_back(VFParameter({I, VFParamKind::Vector}));
-    if (HasGlobalPred)
-      Parameters.push_back(
-          VFParameter({FTy->getNumParams(), VFParamKind::GlobalPredicate}));
-
-    return {EC, Parameters};
-  }
-  /// Validation check on the Parameters in the VFShape.
-  bool hasValidParameterList() const;
-};
-
-/// Holds the VFShape for a specific scalar to vector function mapping.
-struct VFInfo {
-  VFShape Shape;          /// Classification of the vector function.
-  std::string ScalarName; /// Scalar Function Name.
-  std::string VectorName; /// Vector Function Name associated to this VFInfo.
-  VFISAKind ISA;          /// Instruction Set Architecture.
-
-  /// Returns the index of the first parameter with the kind 'GlobalPredicate',
-  /// if any exist.
-  std::optional<unsigned> getParamIndexForOptionalMask() const {
-    unsigned ParamCount = Shape.Parameters.size();
-    for (unsigned i = 0; i < ParamCount; ++i)
-      if (Shape.Parameters[i].ParamKind == VFParamKind::GlobalPredicate)
-        return i;
-
-    return std::nullopt;
-  }
-
-  /// Returns true if at least one of the operands to the vectorized function
-  /// has the kind 'GlobalPredicate'.
-  bool isMasked() const { return getParamIndexForOptionalMask().has_value(); }
-};
-
-namespace VFABI {
-/// LLVM Internal VFABI ISA token for vector functions.
-static constexpr char const *_LLVM_ = "_LLVM_";
-/// Prefix for internal name redirection for vector function that
-/// tells the compiler to scalarize the call using the scalar name
-/// of the function. For example, a mangled name like
-/// `_ZGV_LLVM_N2v_foo(_LLVM_Scalarize_foo)` would tell the
-/// vectorizer to vectorize the scalar call `foo`, and to scalarize
-/// it once vectorization is done.
-static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
-
-/// Function to construct a VFInfo out of a mangled names in the
-/// following format:
-///
-/// <VFABI_name>{(<redirection>)}
-///
-/// where <VFABI_name> is the name of the vector function, mangled according
-/// to the rules described in the Vector Function ABI of the target vector
-/// extension (or <isa> from now on). The <VFABI_name> is in the following
-/// format:
-///
-/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
-///
-/// This methods support demangling rules for the following <isa>:
-///
-/// * AArch64: https://developer.arm.com/docs/101129/latest
-///
-/// * x86 (libmvec): https://sourceware.org/glibc/wiki/libmvec and
-///  https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt
-///
-/// \param MangledName -> input string in the format
-/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
-/// \param FTy -> FunctionType of the scalar function which we're trying to find
-/// a vectorized variant for. This is required to determine the vectorization
-/// factor for scalable vectors, since the mangled name doesn't encode that;
-/// it needs to be derived from the widest element types of vector arguments
-/// or return values.
-std::optional<VFInfo> tryDemangleForVFABI(StringRef MangledName,
-                                          const FunctionType *FTy);
-
-/// Retrieve the `VFParamKind` from a string token.
-VFParamKind getVFParamKindFromString(const StringRef Token);
-
-// Name of the attribute where the variant mappings are stored.
-static constexpr char const *MappingsAttrName = "vector-function-abi-variant";
-
-/// Populates a set of strings representing the Vector Function ABI variants
-/// associated to the CallInst CI. If the CI does not contain the
-/// vector-function-abi-variant attribute, we return without populating
-/// VariantMappings, i.e. callers of getVectorVariantNames need not check for
-/// the presence of the attribute (see InjectTLIMappings).
-void getVectorVariantNames(const CallInst &CI,
-                           SmallVectorImpl<std::string> &VariantMappings);
-
-/// Constructs a FunctionType by applying vector function information to the
-/// type of a matching scalar function.
-/// \param Info gets the vectorization factor (VF) and the VFParamKind of the
-/// parameters.
-/// \param ScalarFTy gets the Type information of parameters, as it is not
-/// stored in \p Info.
-/// \returns a pointer to a newly created vector FunctionType
-FunctionType *createFunctionType(const VFInfo &Info,
-                                 const FunctionType *ScalarFTy);
-} // end namespace VFABI
-
 /// The Vector Function Database.
 ///
 /// Helper class used to find the vector functions associated to a
diff --git a/llvm/include/llvm/IR/VFABIDemangler.h b/llvm/include/llvm/IR/VFABIDemangler.h
new file mode 100644
index 00000000000000..8450d4ce541e13
--- /dev/null
+++ b/llvm/include/llvm/IR/VFABIDemangler.h
@@ -0,0 +1,217 @@
+//===- VFABIDemangler.h - Vector Function ABI demangler ------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the VFABI demangling utility.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VFABIDEMANGLER_H
+#define LLVM_IR_VFABIDEMANGLER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/TypeSize.h"
+
+namespace llvm {
+
+/// Describes the type of Parameters
+enum class VFParamKind {
+  Vector,            // No semantic information.
+  OMP_Linear,        // declare simd linear(i)
+  OMP_LinearRef,     // declare simd linear(ref(i))
+  OMP_LinearVal,     // declare simd linear(val(i))
+  OMP_LinearUVal,    // declare simd linear(uval(i))
+  OMP_LinearPos,     // declare simd linear(i:c) uniform(c)
+  OMP_LinearValPos,  // declare simd linear(val(i:c)) uniform(c)
+  OMP_LinearRefPos,  // declare simd linear(ref(i:c)) uniform(c)
+  OMP_LinearUValPos, // declare simd linear(uval(i:c)) uniform(c)
+  OMP_Uniform,       // declare simd uniform(i)
+  GlobalPredicate,   // Global logical predicate that acts on all lanes
+                     // of the input and output mask concurrently. For
+                     // example, it is implied by the `M` token in the
+                     // Vector Function ABI mangled name.
+  Unknown
+};
+
+/// Describes the type of Instruction Set Architecture
+enum class VFISAKind {
+  AdvancedSIMD, // AArch64 Advanced SIMD (NEON)
+  SVE,          // AArch64 Scalable Vector Extension
+  SSE,          // x86 SSE
+  AVX,          // x86 AVX
+  AVX2,         // x86 AVX2
+  AVX512,       // x86 AVX512
+  LLVM,         // LLVM internal ISA for functions that are not
+  // attached to an existing ABI via name mangling.
+  Unknown // Unknown ISA
+};
+
+/// Encapsulates information needed to describe a parameter.
+///
+/// The description of the parameter is not linked directly to
+/// OpenMP or any other vector function description. This structure
+/// is extendible to handle other paradigms that describe vector
+/// functions and their parameters.
+struct VFParameter {
+  unsigned ParamPos;         // Parameter Position in Scalar Function.
+  VFParamKind ParamKind;     // Kind of Parameter.
+  int LinearStepOrPos = 0;   // Step or Position of the Parameter.
+  Align Alignment = Align(); // Optional alignment in bytes, defaulted to 1.
+
+  // Comparison operator.
+  bool operator==(const VFParameter &Other) const {
+    return std::tie(ParamPos, ParamKind, LinearStepOrPos, Alignment) ==
+           std::tie(Other.ParamPos, Other.ParamKind, Other.LinearStepOrPos,
+                    Other.Alignment);
+  }
+};
+
+/// Contains the information about the kind of vectorization
+/// available.
+///
+/// This object in independent on the paradigm used to
+/// represent vector functions. in particular, it is not attached to
+/// any target-specific ABI.
+struct VFShape {
+  ElementCount VF;                        // Vectorization factor.
+  SmallVector<VFParameter, 8> Parameters; // List of parameter information.
+  // Comparison operator.
+  bool operator==(const VFShape &Other) const {
+    return std::tie(VF, Parameters) == std::tie(Other.VF, Other.Parameters);
+  }
+
+  /// Update the parameter in position P.ParamPos to P.
+  void updateParam(VFParameter P) {
+    assert(P.ParamPos < Parameters.size() && "Invalid parameter position.");
+    Parameters[P.ParamPos] = P;
+    assert(hasValidParameterList() && "Invalid parameter list");
+  }
+
+  /// Retrieve the VFShape that can be used to map a scalar function to itself,
+  /// with VF = 1.
+  static VFShape getScalarShape(const FunctionType *FTy) {
+    return VFShape::get(FTy, ElementCount::getFixed(1),
+                        /*HasGlobalPredicate*/ false);
+  }
+
+  /// Retrieve the basic vectorization shape of the function, where all
+  /// parameters are mapped to VFParamKind::Vector with \p EC lanes. Specifies
+  /// whether the function has a Global Predicate argument via \p HasGlobalPred.
+  static VFShape get(const FunctionType *FTy, ElementCount EC,
+                     bool HasGlobalPred) {
+    SmallVector<VFParameter, 8> Parameters;
+    for (unsigned I = 0; I < FTy->getNumParams(); ++I)
+      Parameters.push_back(VFParameter({I, VFParamKind::Vector}));
+    if (HasGlobalPred)
+      Parameters.push_back(
+          VFParameter({FTy->getNumParams(), VFParamKind::GlobalPredicate}));
+
+    return {EC, Parameters};
+  }
+  /// Validation check on the Parameters in the VFShape.
+  bool hasValidParameterList() const;
+};
+
+/// Holds the VFShape for a specific scalar to vector function mapping.
+struct VFInfo {
+  VFShape Shape;          /// Classification of the vector function.
+  std::string ScalarName; /// Scalar Function Name.
+  std::string VectorName; /// Vector Function Name associated to this VFInfo.
+  VFISAKind ISA;          /// Instruction Set Architecture.
+
+  /// Returns the index of the first parameter with the kind 'GlobalPredicate',
+  /// if any exist.
+  std::optional<unsigned> getParamIndexForOptionalMask() const {
+    unsigned ParamCount = Shape.Parameters.size();
+    for (unsigned i = 0; i < ParamCount; ++i)
+      if (Shape.Parameters[i].ParamKind == VFParamKind::GlobalPredicate)
+        return i;
+
+    return std::nullopt;
+  }
+
+  /// Returns true if at least one of the operands to the vectorized function
+  /// has the kind 'GlobalPredicate'.
+  bool isMasked() const { return getParamIndexForOptionalMask().has_value(); }
+};
+
+namespace VFABI {
+/// LLVM Internal VFABI ISA token for vector functions.
+static constexpr char const *_LLVM_ = "_LLVM_";
+/// Prefix for internal name redirection for vector function that
+/// tells the compiler to scalarize the call using the scalar name
+/// of the function. For example, a mangled name like
+/// `_ZGV_LLVM_N2v_foo(_LLVM_Scalarize_foo)` would tell the
+/// vectorizer to vectorize the scalar call `foo`, and to scalarize
+/// it once vectorization is done.
+static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
+
+/// Function to construct a VFInfo out of a mangled names in the
+/// following format:
+///
+/// <VFABI_name>{(<redirection>)}
+///
+/// where <VFABI_name> is the name of the vector function, mangled according
+/// to the rules described in the Vector Function ABI of the target vector
+/// extension (or <isa> from now on). The <VFABI_name> is in the following
+/// format:
+///
+/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
+///
+/// This methods support demangling rules for the following <isa>:
+///
+/// * AArch64: https://developer.arm.com/docs/101129/latest
+///
+/// * x86 (libmvec): https://sourceware.org/glibc/wiki/libmvec and
+///  https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt
+///
+/// \param MangledName -> input string in the format
+/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
+/// \param FTy -> FunctionType of the scalar function which we're trying to find
+/// a vectorized variant for. This is required to determine the vectorization
+/// factor for scalable vectors, since the mangled name doesn't encode that;
+/// it needs to be derived from the widest element types of vector arguments
+/// or return values.
+std::optional<VFInfo> tryDemangleForVFABI(StringRef MangledName,
+                                          const FunctionType *FTy);
+
+/// Retrieve the `VFParamKind` from a string token.
+VFParamKind getVFParamKindFromString(const StringRef Token);
+
+// Name of the attribute where the variant mappings are stored.
+static constexpr char const *MappingsAttrName = "vector-function-abi-variant";
+
+/// Populates a set of strings representing the Vector Function ABI variants
+/// associated to the CallInst CI. If the CI does not contain the
+/// vector-function-abi-variant attribute, we return without populating
+/// VariantMappings, i.e. callers of getVectorVariantNames need not check for
+/// the presence of the attribute (see InjectTLIMappings).
+void getVectorVariantNames(const CallInst &CI,
+                           SmallVectorImpl<std::string> &VariantMappings);
+
+/// Constructs a FunctionType by applying vector function information to the
+/// type of a matching scalar function.
+/// \param Info gets the vectorization factor (VF) and the VFParamKind of the
+/// parameters.
+/// \param ScalarFTy gets the Type information of parameters, as it is not
+/// stored in \p Info.
+/// \returns a pointer to a newly created vector FunctionType
+FunctionType *createFunctionType(const VFInfo &Info,
+                                 const FunctionType *ScalarFTy);
+
+/// Overwrite the Vector Function ABI variants attribute with the names provide
+/// in \p VariantMappings.
+void setVectorVariantNames(CallInst *CI, ArrayRef<std::string> VariantMappings);
+
+} // end namespace VFABI
+
+} // namespace llvm
+
+#endif // LLVM_IR_VFABIDEMANGLER_H
diff --git a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
index e37547cb4efff4..1ec87505544f83 100644
--- a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -143,12 +143,6 @@ void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName,
 bool lowerGlobalIFuncUsersAsGlobalCtor(
     Module &M, ArrayRef<GlobalIFunc *> IFuncsToLower = {});
 
-class CallInst;
-namespace VFABI {
-/// Overwrite the Vector Function ABI variants attribute with the names provide
-/// in \p VariantMappings.
-void setVectorVariantNames(CallInst *CI, ArrayRef<std::string> VariantMappings);
-} // End VFABI namespace
 } // End llvm namespace
 
 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 34ff6bb74c106f..35ea03f42f82b1 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -141,7 +141,6 @@ add_llvm_component_library(LLVMAnalysis
   ValueLatticeUtils.cpp
   ValueTracking.cpp
   VectorUtils.cpp
-  VFABIDemangling.cpp
   ${GeneratedMLSources}
 
   ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index 5b57f0a25cec81..41d2f63d3b1750 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -1460,93 +1460,3 @@ void InterleaveGroup<Instruction>::addMetadata(Instruction *NewInst) const {
 }
 }
 
-void VFABI::getVectorVariantNames(
-    const CallInst &CI, SmallVectorImpl<std::string> &VariantMappings) {
-  const StringRef S = CI.getFnAttr(VFABI::MappingsAttrName).getValueAsString();
-  if (S.empty())
-    return;
-
-  SmallVector<StringRef, 8> ListAttr;
-  S.split(ListAttr, ",");
-
-  for (const auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) {
-    std::optional<VFInfo> Info =
-        VFABI::tryDemangleForVFABI(S, CI.getFunctionType());
-    if (Info && CI.getModule()->getFunction(Info->VectorName)) {
-      LLVM_DEBUG(dbgs() << "VFABI: Adding mapping '" << S << "' for " << CI
-                        << "\n");
-      VariantMappings.push_back(std::string(S));
-    } else
-      LLVM_DEBUG(dbgs() << "VFABI: Invalid mapping '" << S << "'\n");
-  }
-}
-
-FunctionType *VFABI::createFunctionType(const VFInfo &Info,
-                                        const FunctionType *ScalarFTy) {
-  // Create vector parameter types
-  SmallVector<Type *, 8> VecTypes;
-  ElementCount VF = Info.Shape.VF;
-  int ScalarParamIndex = 0;
-  for (auto VFParam : Info.Shape.Parameters) {
-    if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
-      VectorType *MaskTy =
-          VectorType::get(Type::getInt1Ty(ScalarFTy->getContext()), VF);
-      VecTypes.push_back(MaskTy);
-      continue;
-    }
-
-    Type *OperandTy = ScalarFTy->getParamType(ScalarParamIndex++);
-    if (VFParam.ParamKind == VFParamKind::Vector)
-      OperandTy = VectorType::get(OperandTy, VF);
-    VecTypes.push_back(OperandTy);
-  }
-
-  auto *RetTy = ScalarFTy->getReturnType();
-  if (!RetTy->isVoidTy())
-    RetTy = VectorType::get(RetTy, VF);
-  return FunctionType::get(RetTy, VecTypes, false);
-}
-
-bool VFShape::hasValidParameterList() const {
-  for (unsigned Pos = 0, NumParams = Parameters.size(); Pos < NumParams;
-       ++Pos) {
-    assert(Parameters[Pos].ParamPos == Pos && "Broken parameter list.");
-
-    switch (Parameters[Pos].ParamKind) {
-    default: // Nothing to check.
-      break;
-    case VFParamKind::OMP_Linear:
-    case VFParamKind::OMP_LinearRef:
-    case VFParamKind::OMP_LinearVal:
-    case VFParamKind::OMP_LinearUVal:
-      // Compile time linear steps must be non-zero.
-      if (Parameters[Pos].LinearStepOrPos == 0)
-        return false;
-      break;
-    case VFParamKind::OMP_LinearPos:
-    case VFParamKind::OMP_LinearRefPos:
-    case VFParamKind::OMP_LinearValPos:
-    case VFParamKind::OMP_LinearUValPos:
-      // The runtime linear step must be referring to some other
-      // parameters in the signature.
-      if (Parameters[Pos].LinearStepOrPos >= int(NumParams))
-        return false;
-      // The linear step parameter must be marked as uniform.
-      if (Parameters[Parameters[Pos].LinearStepOrPos].ParamKind !=
-          VFParamKind::OMP_Uniform)
-        return false;
-      // The linear step parameter can't point at itself.
-      if (Parameters[Pos].LinearStepOrPos == int(Pos))
-        return false;
-      break;
-    case VFParamKind::GlobalPredicate:
-      // The global predicate must be the unique. Can be placed anywhere in the
-      // signature.
-      for (unsigned NextPos = Pos + 1; NextPos < NumParams; ++NextPos)
-        if (Parameters[NextPos].ParamKind == VFParamKind::GlobalPredicate)
-          return false;
-      break;
-    }
-  }
-  return true;
-}
diff --git a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
index 56025aa5c45fb3..f671d808de7792 100644
--- a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
+++ b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
@@ -25,6 +25,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstIterator.h"
+#include "llvm/IR/VFABIDemangler.h"
 #include "llvm/Support/TypeSize.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 5fe3d8029e7d35..f1668ee3be63b5 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -69,6 +69,7 @@ add_llvm_component_library(LLVMCore
   ValueSymbolTable.cpp
   VectorBuilder.cpp
   Verifier.cpp
+  VFABIDemangler.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
diff --git a/llvm/lib/Analysis/VFABIDemangling.cpp b/llvm/lib/IR/VFABIDemangler.cpp
similarity index 80%
rename from llvm/lib/Analysis/VFABIDemangling.cpp
rename to llvm/lib/IR/VFABIDemangler.cpp
index 8562d8fbfa1ede..7fb2ff6f150d40 100644
--- a/llvm/lib/Analysis/VFABIDemangling.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -1,4 +1,4 @@
-//===- VFABIDemangling.cpp - Vector Function ABI demangling utilities. ---===//
+//===- VFABIDemangler.cpp - Vector Function ABI demangler -----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,14 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/IR/VFABIDemangler.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <limits>
 
 using namespace llvm;
 
-#define DEBUG_TYPE "vfabi-demangling"
+#define DEBUG_TYPE "vfabi-demangler"
 
 namespace {
 /// Utilities for the Vector Function ABI name parser.
@@ -519,3 +523,123 @@ VFParamKind VFABI::getVFParamKindFromString(const StringRef Token) {
                    " that have a textual representation in the mangled name"
                    " of the Vector Function ABI");
 }
+
+void VFABI::getVectorVariantNames(
+    const CallInst &CI, SmallVectorImpl<std::string> &VariantMappings) {
+  const StringRef S = CI.getFnAttr(VFABI::MappingsAttrName).getValueAsString();
+  if (S.empty())
+    return;
+
+  SmallVector<StringRef, 8> ListAttr;
+  S.split(ListAttr, ",");
+
+  for (const auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) {
+    std::optional<VFInfo> Info =
+        VFABI::tryDemangleForVFABI(S, CI.getFunctionType());
+    if (Info && CI.getModule()->getFunction(Info->VectorName)) {
+      LLVM_DEBUG(dbgs() << "VFABI: Adding mapping '" << S << "' for " << CI
+                        << "\n");
+      VariantMappings.push_back(std::string(S));
+    } else
+      LLVM_DEBUG(dbgs() << "VFABI: Invalid mapping '" << S << "'\n");
+  }
+}
+
+FunctionType *VFABI::createFunctionType(const VFInfo &Info,
+                                        const FunctionType *ScalarFTy) {
+  // Create vector parameter types
+  SmallVector<Type *, 8> VecTypes;
+  ElementCount VF = Info.Shape.VF;
+  int ScalarParamIndex = 0;
+  for (auto VFParam : Info.Shape.Parameters) {
+    if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
+      VectorType *MaskTy =
+          VectorType::get(Type::getInt1Ty(ScalarFTy->getContext()), VF);
+      VecTypes.push_back(MaskTy);
+      continue;
+    }
+
+    Type *OperandTy = ScalarFTy->getParamType(ScalarParamIndex++);
+    if (VFParam.ParamKind == VFParamKind::Vector)
+      OperandTy = VectorType::get(OperandTy, VF);
+    VecTypes.push_back(OperandTy);
+  }
+
+  auto *RetTy = ScalarFTy->getReturnType();
+  if (!RetTy->isVoidTy())
+    RetTy = VectorType::get(RetTy, VF);
+  return FunctionType::get(RetTy, VecTypes, false);
+}
+
+void VFABI::setVectorVariantNames(CallInst *CI,
+                                  ArrayRef<std::string> VariantMappings) {
+  if (VariantMappings.empty())
+    return;
+
+  SmallString<256> Buffer;
+  llvm::raw_svector_ostream Out(Buffer);
+  for (const std::string &VariantMapping : VariantMappings)
+    Out << VariantMapping << ",";
+  // Get rid of the trailing ','.
+  assert(!Buffer.str().empty() && "Must have at least one char.");
+  Buffer.pop_back();
+
+  Module *M = CI->getModule();
+#ifndef NDEBUG
+  for (const std::string &VariantMapping : VariantMappings) {
+    LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
+    std::optional<VFInfo> VI =
+        VFABI::tryDemangleForVFABI(VariantMapping, CI->getFunctionType());
+    assert(VI && "Cannot add an invalid VFABI name.");
+    assert(M->getNamedValue(VI->VectorName) &&
+           "Cannot add variant to attribute: "
+           "vector function declaration is missing.");
+  }
+#endif
+  CI->addFnAttr(
+      Attribute::get(M->getContext(), MappingsAttrName, Buffer.str()));
+}
+
+bool VFShape::hasValidParameterList() const {
+  for (unsigned Pos = 0, NumParams = Parameters.size(); Pos < NumParams;
+       ++Pos) {
+    assert(Parameters[Pos].ParamPos == Pos && "Broken parameter list.");
+
+    switch (Parameters[Pos].ParamKind) {
+    default: // Nothing to check.
+      break;
+    case VFParamKind::OMP_Linear:
+    case VFParamKind::OMP_LinearRef:
+    case VFParamKind::OMP_LinearVal:
+    case VFParamKind::OMP_LinearUVal:
+      // Compile time linear steps must be non-zero.
+      if (Parameters[Pos].LinearStepOrPos == 0)
+        return false;
+      break;
+    case VFParamKind::OMP_LinearPos:
+    case VFParamKind::OMP_LinearRefPos:
+    case VFParamKind::OMP_LinearValPos:
+    case VFParamKind::OMP_LinearUValPos:
+      // The runtime linear step must be referring to some other
+      // parameters in the signature.
+      if (Parameters[Pos].LinearStepOrPos >= int(NumParams))
+        return false;
+      // The linear step parameter must be marked as uniform.
+      if (Parameters[Parameters[Pos].LinearStepOrPos].ParamKind !=
+          VFParamKind::OMP_Uniform)
+        return false;
+      // The linear step parameter can't point at itself.
+      if (Parameters[Pos].LinearStepOrPos == int(Pos))
+        return false;
+      break;
+    case VFParamKind::GlobalPredicate:
+      // The global predicate must be the unique. Can be placed anywhere in the
+      // signature.
+      for (unsigned NextPos = Pos + 1; NextPos < NumParams; ++NextPos)
+        if (Parameters[NextPos].ParamKind == VFParamKind::GlobalPredicate)
+          return false;
+      break;
+    }
+  }
+  return true;
+}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index aeaca21a99cc5e..7d5735886e15d9 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -106,6 +106,7 @@
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Use.h"
 #include "llvm/IR/User.h"
+#include "llvm/IR/VFABIDemangler.h"
 #include "llvm/IR/Value.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
@@ -2259,6 +2260,13 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
       CheckFailed(
           "invalid value for 'branch-target-enforcement' attribute: " + S, V);
   }
+
+  if (auto A = Attrs.getFnAttr("vector-function-abi-variant"); A.isValid()) {
+    StringRef S = A.getValueAsString();
+    const std::optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S, FT);
+    if (!Info)
+      CheckFailed("invalid name for a VFABI variant: " + S, V);
+  }
 }
 
 void Verifier::verifyFunctionMetadata(
diff --git a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
index ea313563066586..9bfac2ac9167ef 100644
--- a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
+++ b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
@@ -19,6 +19,7 @@
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/InstIterator.h"
+#include "llvm/IR/VFABIDemangler.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace llvm;
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 7de0959ca57ef3..209a6a34a3c9ca 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -329,35 +329,6 @@ std::string llvm::getUniqueModuleId(Module *M) {
   return ("." + Str).str();
 }
 
-void VFABI::setVectorVariantNames(CallInst *CI,
-                                  ArrayRef<std::string> VariantMappings) {
-  if (VariantMappings.empty())
-    return;
-
-  SmallString<256> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
-  for (const std::string &VariantMapping : VariantMappings)
-    Out << VariantMapping << ",";
-  // Get rid of the trailing ','.
-  assert(!Buffer.str().empty() && "Must have at least one char.");
-  Buffer.pop_back();
-
-  Module *M = CI->getModule();
-#ifndef NDEBUG
-  for (const std::string &VariantMapping : VariantMappings) {
-    LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
-    std::optional<VFInfo> VI =
-        VFABI::tryDemangleForVFABI(VariantMapping, CI->getFunctionType());
-    assert(VI && "Cannot add an invalid VFABI name.");
-    assert(M->getNamedValue(VI->VectorName) &&
-           "Cannot add variant to attribute: "
-           "vector function declaration is missing.");
-  }
-#endif
-  CI->addFnAttr(
-      Attribute::get(M->getContext(), MappingsAttrName, Buffer.str()));
-}
-
 void llvm::embedBufferInModule(Module &M, MemoryBufferRef Buf,
                                StringRef SectionName, Align Alignment) {
   // Embed the memory buffer into the module.
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/scalable-call.ll b/llvm/test/Transforms/LoopVectorize/AArch64/scalable-call.ll
index 84f67310021bf1..333bb20fd0d9aa 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/scalable-call.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/scalable-call.ll
@@ -191,7 +191,7 @@ for.cond.cleanup:                                 ; preds = %for.body
 ; Even though there are no function mappings attached to the call
 ; in the loop below we can still vectorize the loop because SVE has
 ; hardware support in the form of the 'fqsrt' instruction.
-define void @vec_sqrt_no_mapping(ptr noalias nocapture %dst, ptr noalias nocapture readonly %src, i64 %n) #0 {
+define void @vec_sqrt_no_mapping(ptr noalias nocapture %dst, ptr noalias nocapture readonly %src, i64 %n) {
 ; CHECK: @vec_sqrt_no_mapping
 ; CHECK: call fast <vscale x 2 x float> @llvm.sqrt.nxv2f32
 entry:
diff --git a/llvm/test/Verifier/vector-function-abi-variant.ll b/llvm/test/Verifier/vector-function-abi-variant.ll
new file mode 100644
index 00000000000000..345e262df48b59
--- /dev/null
+++ b/llvm/test/Verifier/vector-function-abi-variant.ll
@@ -0,0 +1,16 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @cond_call() {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %for.body, %entry
+  %foo.ret = call i64 @foo()
+  br label %for.body
+}
+
+declare i64 @foo() #0
+
+attributes #0 = {"vector-function-abi-variant"="_ZGV_LLVM_M4v_foo(vector_foo)" }
+; CHECK:      invalid name for a VFABI variant: _ZGV_LLVM_M4v_foo(vector_foo)
+; CHECK-NEXT: ptr @foo
diff --git a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
index a6ca3bc4484e3f..e1041bd4eef998 100644
--- a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
+++ b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
@@ -10,8 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Analysis/VectorUtils.h"
 #include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/VFABIDemangler.h"
 
 using namespace llvm;
 
diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt
index 847430bf17697a..c50f39a2c59a83 100644
--- a/llvm/unittests/Analysis/CMakeLists.txt
+++ b/llvm/unittests/Analysis/CMakeLists.txt
@@ -41,7 +41,6 @@ set(ANALYSIS_TEST_SOURCES
   PluginInlineOrderAnalysisTest.cpp
   ProfileSummaryInfoTest.cpp
   ScalarEvolutionTest.cpp
-  VectorFunctionABITest.cpp
   SparsePropagation.cpp
   TargetLibraryInfoTest.cpp
   TensorSpecTest.cpp
diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt
index 5f553c01d67131..803164b8f1eac6 100644
--- a/llvm/unittests/IR/CMakeLists.txt
+++ b/llvm/unittests/IR/CMakeLists.txt
@@ -49,6 +49,7 @@ add_llvm_unittest(IRTests
   VectorBuilderTest.cpp
   VectorTypesTest.cpp
   VerifierTest.cpp
+  VFABIDemanglerTest.cpp
   VPIntrinsicTest.cpp
   CoreBindings.cpp
   )
diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/IR/VFABIDemanglerTest.cpp
similarity index 98%
rename from llvm/unittests/Analysis/VectorFunctionABITest.cpp
rename to llvm/unittests/IR/VFABIDemanglerTest.cpp
index d8a7d8245bb0f3..d7485217951c42 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/IR/VFABIDemanglerTest.cpp
@@ -1,4 +1,4 @@
-//===------- VectorFunctionABITest.cpp - VFABI unit tests  ---------===//
+//===------- VFABIDemanglerTest.cpp - VFABI unit tests  -------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/IR/VFABIDemangler.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
 #include "gtest/gtest.h"
 #include <optional>
 
@@ -38,8 +41,8 @@ class VFABIParserTest : public ::testing::Test {
   /// Reset the data needed for the test.
   void reset(const StringRef ScalarFTyStr) {
     M = parseAssemblyString("declare void @dummy()", Err, Ctx);
-    EXPECT_NE(M.get(), nullptr) << "Loading an invalid module.\n "
-                                << Err.getMessage() << "\n";
+    EXPECT_NE(M.get(), nullptr)
+        << "Loading an invalid module.\n " << Err.getMessage() << "\n";
     Type *Ty = parseType(ScalarFTyStr, Err, *(M.get()));
     ScalarFTy = dyn_cast<FunctionType>(Ty);
     EXPECT_NE(ScalarFTy, nullptr)
@@ -794,6 +797,15 @@ TEST_F(VFABIAttrTest, Read) {
   EXPECT_EQ(Mappings, Exp);
 }
 
+TEST_F(VFABIAttrTest, Write) {
+  Mappings.push_back("_ZGVnN8v_g");
+  Mappings.push_back("_ZGVnN2v_g(custom_vg)");
+  VFABI::setVectorVariantNames(CI, Mappings);
+  const StringRef S =
+      CI->getFnAttr("vector-function-abi-variant").getValueAsString();
+  EXPECT_EQ(S, "_ZGVnN8v_g,_ZGVnN2v_g(custom_vg)");
+}
+
 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
   SMDiagnostic Err;
   std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
diff --git a/llvm/unittests/Transforms/Utils/CMakeLists.txt b/llvm/unittests/Transforms/Utils/CMakeLists.txt
index d1714a7532d5ff..2974811d6c4125 100644
--- a/llvm/unittests/Transforms/Utils/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Utils/CMakeLists.txt
@@ -30,7 +30,6 @@ add_llvm_unittest(UtilsTests
   SSAUpdaterBulkTest.cpp
   UnrollLoopTest.cpp
   ValueMapperTest.cpp
-  VFABIUtils.cpp
   ProfDataUtilTest.cpp
   )
 
diff --git a/llvm/unittests/Transforms/Utils/VFABIUtils.cpp b/llvm/unittests/Transforms/Utils/VFABIUtils.cpp
deleted file mode 100644
index 4ac9b45a403c54..00000000000000
--- a/llvm/unittests/Transforms/Utils/VFABIUtils.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//===------- VFABIUtils.cpp - VFABI Unittests  ----------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-class VFABIAttrTest : public testing::Test {
-protected:
-  void SetUp() override {
-    M = parseAssemblyString(IR, Err, Ctx);
-    // Get the only call instruction in the block, which is the first
-    // instruction.
-    CI = dyn_cast<CallInst>(&*(instructions(M->getFunction("f")).begin()));
-  }
-  const char *IR = "define i32 @f(i32 %a) {\n"
-                   " %1 = call i32 @g(i32 %a) #0\n"
-                   "  ret i32 %1\n"
-                   "}\n"
-                   "declare i32 @g(i32)\n"
-                   "declare <2 x i32> @custom_vg(<2 x i32>)"
-                   "declare <4 x i32> @_ZGVnN4v_g(<4 x i32>)"
-                   "declare <8 x i32> @_ZGVnN8v_g(<8 x i32>)"
-                   "attributes #0 = { "
-                   "\"vector-function-abi-variant\"=\""
-                   "_ZGVnN2v_g(custom_vg),_ZGVnN4v_g\" }";
-  LLVMContext Ctx;
-  SMDiagnostic Err;
-  std::unique_ptr<Module> M;
-  CallInst *CI;
-  SmallVector<std::string, 8> Mappings;
-};
-
-TEST_F(VFABIAttrTest, Write) {
-  Mappings.push_back("_ZGVnN8v_g");
-  Mappings.push_back("_ZGVnN2v_g(custom_vg)");
-  VFABI::setVectorVariantNames(CI, Mappings);
-  const StringRef S =
-      CI->getFnAttr("vector-function-abi-variant").getValueAsString();
-  EXPECT_EQ(S, "_ZGVnN8v_g,_ZGVnN2v_g(custom_vg)");
-}
diff --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
index 6939cbfb5e0cfc..27f7e2b395ec07 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
@@ -126,7 +126,6 @@ static_library("Analysis") {
     "TypeBasedAliasAnalysis.cpp",
     "TypeMetadataUtils.cpp",
     "UniformityAnalysis.cpp",
-    "VFABIDemangling.cpp",
     "ValueLattice.cpp",
     "ValueLatticeUtils.cpp",
     "ValueTracking.cpp",
diff --git a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
index 8c2e8abad4a54d..896b031a7bd3fd 100644
--- a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
@@ -83,5 +83,6 @@ static_library("IR") {
     "ValueSymbolTable.cpp",
     "VectorBuilder.cpp",
     "Verifier.cpp",
+    "VFABIDemangler.cpp",
   ]
 }
diff --git a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
index c24f99555ce361..dc65732eb72bf1 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
@@ -50,7 +50,6 @@ unittest("AnalysisTests") {
     "UnrollAnalyzerTest.cpp",
     "ValueLatticeTest.cpp",
     "ValueTrackingTest.cpp",
-    "VectorFunctionABITest.cpp",
     "VectorUtilsTest.cpp",
   ]
 
diff --git a/llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn
index 1f3b19b8c6b5f6..dc1131b68df86d 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn
@@ -52,5 +52,6 @@ unittest("IRTests") {
     "VectorBuilderTest.cpp",
     "VectorTypesTest.cpp",
     "VerifierTest.cpp",
+    "VFABIDemanglerTest.cpp,"
   ]
 }
diff --git a/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
index f8169e86089917..380ed71a2bc010 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
@@ -32,7 +32,6 @@ unittest("UtilsTests") {
     "ScalarEvolutionExpanderTest.cpp",
     "SizeOptsTest.cpp",
     "UnrollLoopTest.cpp",
-    "VFABIUtils.cpp",
     "ValueMapperTest.cpp",
   ]
 }



More information about the llvm-commits mailing list