[llvm] [VFABI] Improve VFABI unit tests (PR #73907)

Paschalis Mpeis via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 07:24:27 PST 2023


https://github.com/paschalis-mpeis updated https://github.com/llvm/llvm-project/pull/73907

>From 0ad4a31a051930353b1168b18216ff570b43f5c3 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Tue, 28 Nov 2023 17:49:49 +0000
Subject: [PATCH 1/6] [VFABI] Improve VFABI unit tests

Do checks for scalar parameter counts for all mappings with
`matchScalarParametersNum`. It is not part of `invokeParser` so it can
be selectively applied only to tests that supply valid mangled names.

Also, minor reformatting and typo fixes.
---
 .../Analysis/VectorFunctionABITest.cpp        | 161 ++++++++++++------
 1 file changed, 105 insertions(+), 56 deletions(-)

diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index e496d87c06de6bc..a95c27ed61d3e18 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -1,4 +1,4 @@
-//===------- VectorFunctionABITest.cpp - VFABI Unittests  ---------===//
+//===------- VectorFunctionABITest.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,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/InstIterator.h"
@@ -14,7 +15,7 @@
 using namespace llvm;
 
 namespace {
-// Test fixture needed that holds the veariables needed by the parser.
+// Test fixture needed that holds the variables needed by the parser.
 class VFABIParserTest : public ::testing::Test {
 private:
   // Parser output.
@@ -34,6 +35,7 @@ class VFABIParserTest : public ::testing::Test {
         << "The function must be present in the module\n";
     // Reset the VFInfo
     Info = VFInfo();
+    ScalarParametersNum = 0;
   }
 
   // Data needed to load the optional IR passed to invokeParser
@@ -44,10 +46,11 @@ class VFABIParserTest : public ::testing::Test {
   FunctionCallee F;
 
 protected:
-  // Referencies to the parser output field.
+  // References to the parser output field.
   ElementCount &VF = Info.Shape.VF;
   VFISAKind &ISA = Info.ISA;
   SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
+  size_t ScalarParametersNum;
   std::string &ScalarName = Info.ScalarName;
   std::string &VectorName = Info.VectorName;
   // Invoke the parser. We need to make sure that a function exist in
@@ -78,23 +81,21 @@ class VFABIParserTest : public ::testing::Test {
 
     // Fake the arguments to the CallInst.
     SmallVector<Value *> Args;
-    for (Type *ParamTy : FTy->params()) {
+    for (Type *ParamTy : FTy->params())
       Args.push_back(Constant::getNullValue(ParamTy->getScalarType()));
-    }
     std::unique_ptr<CallInst> CI(CallInst::Create(F, Args));
     const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(CI.get()));
     if (OptInfo) {
       Info = *OptInfo;
+      ScalarParametersNum = Info.Shape.getScalarShape(*CI).Parameters.size();
       return true;
     }
-
     return false;
   }
 
   // Checks that 1. the last Parameter in the Shape is of type
-  // VFParamKind::GlobalPredicate and 2. it is the only one of such
-  // type.
-  bool IsMasked() const {
+  // VFParamKind::GlobalPredicate and 2. it is the only one of such type.
+  bool isMasked() const {
     const auto NGlobalPreds =
         std::count_if(Info.Shape.Parameters.begin(),
                       Info.Shape.Parameters.end(), [](const VFParameter PK) {
@@ -103,6 +104,12 @@ class VFABIParserTest : public ::testing::Test {
     return NGlobalPreds == 1 && Info.Shape.Parameters.back().ParamKind ==
                                     VFParamKind::GlobalPredicate;
   }
+
+  // Checks that the number of vectorized parameters matches the scalar ones.
+  // Takes into account that vectorized calls may also have a Mask.
+  bool matchScalarParametersNum() {
+    return (Parameters.size() - isMasked()) == ScalarParametersNum;
+  }
 };
 } // unnamed namespace
 
@@ -140,8 +147,10 @@ TEST_F(VFABIParserTest, OnlyValidNames) {
 }
 
 TEST_F(VFABIParserTest, ParamListParsing) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo", "",
+                           "void(double, i32, i32, ptr, i32)"));
   EXPECT_EQ(Parameters.size(), (unsigned)5);
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 16}));
   EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
@@ -168,9 +177,12 @@ TEST_F(VFABIParserTest, ScalarNameAndVectorName_03) {
 }
 
 TEST_F(VFABIParserTest, Parse) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin", "sin",
+                   "void(double, i32, i32, i32, ptr, i32, i32, i32, ptr)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_FALSE(IsMasked());
+  EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_EQ(Parameters.size(), (unsigned)9);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
@@ -187,9 +199,11 @@ TEST_F(VFABIParserTest, Parse) {
 }
 
 TEST_F(VFABIParserTest, ParseVectorName) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin", "double(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_FALSE(IsMasked());
+  EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_EQ(Parameters.size(), (unsigned)1);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
@@ -198,9 +212,11 @@ TEST_F(VFABIParserTest, ParseVectorName) {
 }
 
 TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin", "",
+                           "double(i32, i32, i32, ptr)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_FALSE(IsMasked());
+  EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_EQ(Parameters.size(), (unsigned)4);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
@@ -213,17 +229,19 @@ TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
 
 TEST_F(VFABIParserTest, ParseScalableSVE) {
   EXPECT_TRUE(invokeParser("_ZGVsMxv_sin(custom_vg)", "sin", "i32(i32)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getScalable(4));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_EQ(ScalarName, "sin");
   EXPECT_EQ(VectorName, "custom_vg");
 }
 
 TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin", "", "double(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_EQ(ScalarName, "sin");
   EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
@@ -250,7 +268,9 @@ TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
 }
 
 TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
-  EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin", "",
+                           "void(i32, i32, ptr, i32, i32, i32, ptr, i32)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(Parameters.size(), (unsigned)8);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
@@ -300,7 +320,8 @@ TEST_F(VFABIParserTest, InvalidParameter) {
 }
 
 TEST_F(VFABIParserTest, Align) {
-  EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin", "", "void(i32)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(Parameters.size(), (unsigned)1);
   EXPECT_EQ(Parameters[0].Alignment, Align(2));
 
@@ -318,9 +339,10 @@ TEST_F(VFABIParserTest, Align) {
 }
 
 TEST_F(VFABIParserTest, ParseUniform) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2u_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2u_sin", "", "void(i32)"));
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_FALSE(IsMasked());
+  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_EQ(Parameters.size(), (unsigned)1);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
@@ -350,58 +372,70 @@ TEST_F(VFABIParserTest, ISAIndependentMangling) {
 #define __COMMON_CHECKS                                                        \
   do {                                                                         \
     EXPECT_EQ(VF, ElementCount::getFixed(2));                                  \
-    EXPECT_FALSE(IsMasked());                                                  \
+    EXPECT_FALSE(isMasked());                                                  \
+    EXPECT_TRUE(matchScalarParametersNum());                                   \
     EXPECT_EQ(Parameters.size(), (unsigned)10);                                \
     EXPECT_EQ(Parameters, ExpectedParams);                                     \
     EXPECT_EQ(ScalarName, "sin");                                              \
   } while (0)
 
+  const StringRef IRTy =
+      "void(double, i32, i32, i32, ptr, i32, i32, i32, i32, i32)";
+
   // Advanced SIMD: <isa> = "n"
-  EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // SVE: <isa> = "s"
-  EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::SVE);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // SSE: <isa> = "b"
-  EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::SSE);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX: <isa> = "c"
-  EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX2: <isa> = "d"
-  EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX2);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX512: <isa> = "e"
-  EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX512);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // LLVM: <isa> = "_LLVM_" internal vector function.
-  EXPECT_TRUE(invokeParser(
-      "_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)", "vectorf"));
+  EXPECT_TRUE(
+      invokeParser("_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)",
+                   "vectorf", IRTy));
   EXPECT_EQ(ISA, VFISAKind::LLVM);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "vectorf");
 
   // Unknown ISA (randomly using "q"). This test will need update if
   // some targets decide to use "q" as their ISA token.
-  EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
   EXPECT_EQ(ISA, VFISAKind::Unknown);
   __COMMON_CHECKS;
   EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
@@ -422,9 +456,10 @@ TEST_F(VFABIParserTest, MissingVectorNameTermination) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingNEON) {
-  EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -433,9 +468,10 @@ TEST_F(VFABIParserTest, ParseMaskingNEON) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -444,9 +480,10 @@ TEST_F(VFABIParserTest, ParseMaskingSVE) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingSSE) {
-  EXPECT_TRUE(invokeParser("_ZGVbM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVbM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SSE);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -455,9 +492,10 @@ TEST_F(VFABIParserTest, ParseMaskingSSE) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX) {
-  EXPECT_TRUE(invokeParser("_ZGVcM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVcM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -466,9 +504,10 @@ TEST_F(VFABIParserTest, ParseMaskingAVX) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX2) {
-  EXPECT_TRUE(invokeParser("_ZGVdM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVdM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX2);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -477,9 +516,10 @@ TEST_F(VFABIParserTest, ParseMaskingAVX2) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX512) {
-  EXPECT_TRUE(invokeParser("_ZGVeM2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVeM2v_sin", "", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX512);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -489,9 +529,10 @@ TEST_F(VFABIParserTest, ParseMaskingAVX512) {
 
 TEST_F(VFABIParserTest, ParseMaskingLLVM) {
   EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_sin(custom_vector_sin)",
-                           "custom_vector_sin"));
+                           "custom_vector_sin", "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::LLVM);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -503,12 +544,14 @@ TEST_F(VFABIParserTest, ParseMaskingLLVM) {
 TEST_F(VFABIParserTest, ParseScalableMaskingLLVM) {
   EXPECT_FALSE(
       invokeParser("_ZGV_LLVM_Mxv_sin(custom_vector_sin)", "sin", "i32(i32)"));
+  EXPECT_TRUE(matchScalarParametersNum());
 }
 
 TEST_F(VFABIParserTest, ParseScalableMaskingSVE) {
   EXPECT_TRUE(
       invokeParser("_ZGVsMxv_sin(custom_vector_sin)", "sin", "i32(i32)"));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(VF, ElementCount::getScalable(4));
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
@@ -520,9 +563,10 @@ TEST_F(VFABIParserTest, ParseScalableMaskingSVE) {
 
 TEST_F(VFABIParserTest, ParseScalableMaskingSVESincos) {
   EXPECT_TRUE(invokeParser("_ZGVsMxvl8l8_sincos(custom_vector_sincos)",
-                           "sincos", "void(double, double *, double *)"));
+                           "sincos", "void(double, ptr, ptr)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getScalable(2));
-  EXPECT_TRUE(IsMasked());
+  EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_EQ(Parameters.size(), (unsigned)4);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -538,12 +582,14 @@ TEST_F(VFABIParserTest, ParseScalableMaskingSVESincos) {
 TEST_F(VFABIParserTest, ParseWiderReturnTypeSVE) {
   EXPECT_TRUE(
       invokeParser("_ZGVsMxvv_foo(vector_foo)", "foo", "i64(i32, i32)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getScalable(2));
 }
 
 // Make sure we handle void return types.
 TEST_F(VFABIParserTest, ParseVoidReturnTypeSVE) {
   EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "foo", "void(i16)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getScalable(8));
 }
 
@@ -556,7 +602,6 @@ TEST_F(VFABIParserTest, ParseUnsupportedElementTypeSVE) {
 TEST_F(VFABIParserTest, ParseUnsupportedReturnTypeSVE) {
   EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "foo", "fp128(float)"));
 }
-
 class VFABIAttrTest : public testing::Test {
 protected:
   void SetUp() override {
@@ -593,15 +638,18 @@ TEST_F(VFABIAttrTest, Read) {
 
 TEST_F(VFABIParserTest, LLVM_InternalISA) {
   EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
-  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
+  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name",
+                           "void(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(ISA, VFISAKind::LLVM);
 }
 
 TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
   EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)",
-                           "__svml_powf4"));
+                           "__svml_powf4", "void(float, float)"));
+  EXPECT_TRUE(matchScalarParametersNum());
   EXPECT_EQ(VF, ElementCount::getFixed(4));
-  EXPECT_FALSE(IsMasked());
+  EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::LLVM);
   EXPECT_EQ(Parameters.size(), (unsigned)2);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
@@ -615,6 +663,7 @@ TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
   // `custom_vg` is added to the module.
   EXPECT_FALSE(invokeParser(MangledName));
   EXPECT_TRUE(invokeParser(MangledName, "sin", "double(double)"));
+  EXPECT_TRUE(matchScalarParametersNum());
 }
 
 TEST_F(VFABIParserTest, ZeroIsInvalidVLEN) {
@@ -641,9 +690,9 @@ define void @call(void () * %f) {
   ret void
 }
 )IR");
-  auto F = dyn_cast_or_null<Function>(M->getNamedValue("call"));
+  auto *F = dyn_cast_or_null<Function>(M->getNamedValue("call"));
   ASSERT_TRUE(F);
-  auto CI = dyn_cast<CallInst>(&F->front().front());
+  auto *CI = dyn_cast<CallInst>(&F->front().front());
   ASSERT_TRUE(CI);
   ASSERT_TRUE(CI->isIndirectCall());
   auto Mappings = VFDatabase::getMappings(*CI);

>From c84bca8183aa19fe47ddc3064ebda71e74de3580 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Thu, 30 Nov 2023 14:31:26 +0000
Subject: [PATCH 2/6] Further cleanup and simplication of VFABI tests.

`tryDemangleForVFABI` and `VFShape`'s `getScalarShape`, `get` use
`FunctionType` instead of `CallInst`.

Each successful parsing should provide a vector name, and do checks for
the names, number of arguments, and vector parameter types, eg:

```
EXPECT_EQ(ScalarName, "foo");
EXPECT_EQ(VectorName, "vector_foo");
...
EXPECT_TRUE(matchScalarParamNum());
...
EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::OMP_Linear, 2}));
```

Replace method names to `foo` and `vector_foo` for the scalar and vector
variants respectively.
Using only `i32` for parameters when it's not relevant, except when
the VF Elements are explicitly checked, `ptr` for references, and `void`
for most return types.

All `VFABIParserTest` tests are now listed contiguously in the source.
---
 llvm/include/llvm/Analysis/VectorUtils.h      |  19 +-
 llvm/lib/Analysis/VFABIDemangling.cpp         |   4 +-
 llvm/lib/Analysis/VectorUtils.cpp             |   3 +-
 llvm/lib/Transforms/Utils/ModuleUtils.cpp     |   3 +-
 .../Transforms/Vectorize/SLPVectorizer.cpp    |  15 +-
 .../vfabi-demangler-fuzzer.cpp                |   2 +-
 .../Analysis/VectorFunctionABITest.cpp        | 592 ++++++++++--------
 llvm/unittests/Analysis/VectorUtilsTest.cpp   |   6 +-
 8 files changed, 353 insertions(+), 291 deletions(-)

diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index d54b63fd4f5328f..549c07c40baaa90 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -96,8 +96,8 @@ struct VFShape {
 
   // Retrieve the VFShape that can be used to map a (scalar) function to itself,
   // with VF = 1.
-  static VFShape getScalarShape(const CallInst &CI) {
-    return VFShape::get(CI, ElementCount::getFixed(1),
+  static VFShape getScalarShape(const FunctionType *FTy) {
+    return VFShape::get(FTy, ElementCount::getFixed(1),
                         /*HasGlobalPredicate*/ false);
   }
 
@@ -105,13 +105,14 @@ struct VFShape {
   // 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 CallInst &CI, ElementCount EC, bool HasGlobalPred) {
+  static VFShape get(const FunctionType *FTy, ElementCount EC,
+                     bool HasGlobalPred) {
     SmallVector<VFParameter, 8> Parameters;
-    for (unsigned I = 0; I < CI.arg_size(); ++I)
+    for (unsigned I = 0; I < FTy->getNumParams(); ++I)
       Parameters.push_back(VFParameter({I, VFParamKind::Vector}));
     if (HasGlobalPred)
       Parameters.push_back(
-          VFParameter({CI.arg_size(), VFParamKind::GlobalPredicate}));
+          VFParameter({FTy->getNumParams(), VFParamKind::GlobalPredicate}));
 
     return {EC, Parameters};
   }
@@ -174,13 +175,13 @@ static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
 ///
 /// \param MangledName -> input string in the format
 /// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
-/// \param CI -> A call to the scalar function which we're trying to find
+/// \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 CallInst &CI);
+                                          const FunctionType *FTy);
 
 /// Retrieve the `VFParamKind` from a string token.
 VFParamKind getVFParamKindFromString(const StringRef Token);
@@ -227,7 +228,7 @@ class VFDatabase {
       return;
     for (const auto &MangledName : ListOfStrings) {
       const std::optional<VFInfo> Shape =
-          VFABI::tryDemangleForVFABI(MangledName, CI);
+          VFABI::tryDemangleForVFABI(MangledName, CI.getFunctionType());
       // 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
@@ -276,7 +277,7 @@ class VFDatabase {
   /// @{
   /// Retrieve the Function with VFShape \p Shape.
   Function *getVectorizedFunction(const VFShape &Shape) const {
-    if (Shape == VFShape::getScalarShape(CI))
+    if (Shape == VFShape::getScalarShape(CI.getFunctionType()))
       return CI.getCalledFunction();
 
     for (const auto &Info : ScalarToVectorMappings)
diff --git a/llvm/lib/Analysis/VFABIDemangling.cpp b/llvm/lib/Analysis/VFABIDemangling.cpp
index 88f61cfeb9ba4e5..92af314a41caad1 100644
--- a/llvm/lib/Analysis/VFABIDemangling.cpp
+++ b/llvm/lib/Analysis/VFABIDemangling.cpp
@@ -369,7 +369,7 @@ getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA,
 // Format of the ABI name:
 // _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
 std::optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName,
-                                                 const CallInst &CI) {
+                                                 const FunctionType *FTy) {
   const StringRef OriginalName = MangledName;
   // Assume there is no custom name <redirection>, and therefore the
   // vector name consists of
@@ -434,7 +434,7 @@ std::optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName,
   // demangled parameter types and the scalar function signature.
   std::optional<ElementCount> EC;
   if (ParsedVF.second) {
-    EC = getScalableECFromSignature(CI.getFunctionType(), ISA, Parameters);
+    EC = getScalableECFromSignature(FTy, ISA, Parameters);
     if (!EC)
       return std::nullopt;
   } else
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index 96f39ff7e409ede..91d8c31fa062def 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -1466,7 +1466,8 @@ void VFABI::getVectorVariantNames(
   S.split(ListAttr, ",");
 
   for (const auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) {
-    std::optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S, CI);
+    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");
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index fc42df75875e1e9..7de0959ca57ef3e 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -346,7 +346,8 @@ void VFABI::setVectorVariantNames(CallInst *CI,
 #ifndef NDEBUG
   for (const std::string &VariantMapping : VariantMappings) {
     LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
-    std::optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *CI);
+    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: "
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index a9ee101566e9795..1fa4b8e28ee9163 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -5479,7 +5479,8 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
     Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
 
     VFShape Shape = VFShape::get(
-        *CI, ElementCount::getFixed(static_cast<unsigned int>(VL.size())),
+        CI->getFunctionType(),
+        ElementCount::getFixed(static_cast<unsigned int>(VL.size())),
         false /*HasGlobalPred*/);
     Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
 
@@ -6474,9 +6475,10 @@ getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
   auto IntrinsicCost =
     TTI->getIntrinsicInstrCost(CostAttrs, TTI::TCK_RecipThroughput);
 
-  auto Shape = VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
-                                     VecTy->getNumElements())),
-                            false /*HasGlobalPred*/);
+  auto Shape = VFShape::get(
+      CI->getFunctionType(),
+      ElementCount::getFixed(static_cast<unsigned>(VecTy->getNumElements())),
+      false /*HasGlobalPred*/);
   Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
   auto LibCost = IntrinsicCost;
   if (!CI->isNoBuiltin() && VecFunc) {
@@ -11667,8 +11669,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
       Function *CF;
       if (!UseIntrinsic) {
         VFShape Shape =
-            VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
-                                  VecTy->getNumElements())),
+            VFShape::get(CI->getFunctionType(),
+                         ElementCount::getFixed(
+                             static_cast<unsigned>(VecTy->getNumElements())),
                          false /*HasGlobalPred*/);
         CF = VFDatabase(*CI).getVectorizedFunction(Shape);
       } else {
diff --git a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
index 09dc15c9e36667b..f81bf6d10b63e01 100644
--- a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
+++ b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
@@ -38,7 +38,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
       Args.push_back(Constant::getNullValue(ParamTy));
     }
     std::unique_ptr<CallInst> CI(CallInst::Create(F, Args));
-    const auto Info = VFABI::tryDemangleForVFABI(MangledName, *(CI.get()));
+    const auto Info = VFABI::tryDemangleForVFABI(MangledName, CI->getFunctionType()));
 
     // Do not optimize away the return value. Inspired by
     // https://github.com/google/benchmark/blob/main/include/benchmark/benchmark.h#L307-L345
diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index a95c27ed61d3e18..50c3fdebd762fef 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -35,22 +35,22 @@ class VFABIParserTest : public ::testing::Test {
         << "The function must be present in the module\n";
     // Reset the VFInfo
     Info = VFInfo();
-    ScalarParametersNum = 0;
+    ScalarFuncParametersNum = 0;
   }
 
   // Data needed to load the optional IR passed to invokeParser
   LLVMContext Ctx;
   SMDiagnostic Err;
   std::unique_ptr<Module> M;
-  FunctionType *FTy;
+  FunctionType *FTy = nullptr;
   FunctionCallee F;
 
 protected:
   // References to the parser output field.
   ElementCount &VF = Info.Shape.VF;
   VFISAKind &ISA = Info.ISA;
-  SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
-  size_t ScalarParametersNum;
+  SmallVector<VFParameter, 8> &VecFuncParameters = Info.Shape.Parameters;
+  size_t ScalarFuncParametersNum = 0;
   std::string &ScalarName = Info.ScalarName;
   std::string &VectorName = Info.VectorName;
   // Invoke the parser. We need to make sure that a function exist in
@@ -70,24 +70,17 @@ class VFABIParserTest : public ::testing::Test {
   // generic fixed-length case can use as signature `void()`.
   //
   bool invokeParser(const StringRef MangledName,
-                    const StringRef ScalarName = "",
                     const StringRef IRType = "void()") {
-    StringRef Name = MangledName;
-    if (!ScalarName.empty())
-      Name = ScalarName;
     // Reset the VFInfo and the Module to be able to invoke
     // `invokeParser` multiple times in the same test.
-    reset(Name, IRType);
+    reset(MangledName, IRType);
 
     // Fake the arguments to the CallInst.
-    SmallVector<Value *> Args;
-    for (Type *ParamTy : FTy->params())
-      Args.push_back(Constant::getNullValue(ParamTy->getScalarType()));
-    std::unique_ptr<CallInst> CI(CallInst::Create(F, Args));
-    const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(CI.get()));
+    const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, FTy);
     if (OptInfo) {
       Info = *OptInfo;
-      ScalarParametersNum = Info.Shape.getScalarShape(*CI).Parameters.size();
+      ScalarFuncParametersNum =
+          Info.Shape.getScalarShape(FTy).Parameters.size();
       return true;
     }
     return false;
@@ -107,8 +100,8 @@ class VFABIParserTest : public ::testing::Test {
 
   // Checks that the number of vectorized parameters matches the scalar ones.
   // Takes into account that vectorized calls may also have a Mask.
-  bool matchScalarParametersNum() {
-    return (Parameters.size() - isMasked()) == ScalarParametersNum;
+  bool matchScalarParamNum() {
+    return (VecFuncParameters.size() - isMasked()) == ScalarFuncParametersNum;
   }
 };
 } // unnamed namespace
@@ -138,224 +131,264 @@ TEST_F(VFABIParserTest, OnlyValidNames) {
   EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
   // Missing _ separator.
   EXPECT_FALSE(invokeParser("_ZGVnN2vfoo"));
-  // Missing <vectorname>. Using `fakename` because the string being
-  // parsed is not a valid function name that `invokeParser` can add.
-  EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()", "fakename"));
-  // Unterminated name. Using `fakename` because the string being
-  // parsed is not a valid function name that `invokeParser` can add.
-  EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar", "fakename"));
+  // Missing <vectorname>.
+  EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()"));
+  // Unterminated name.
+  EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar"));
 }
 
 TEST_F(VFABIParserTest, ParamListParsing) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo", "",
-                           "void(double, i32, i32, ptr, i32)"));
-  EXPECT_EQ(Parameters.size(), (unsigned)5);
-  EXPECT_TRUE(matchScalarParametersNum());
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 16}));
-  EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
-  EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
-  EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, 1}));
+  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo(vector_foo)",
+                           "void(i32, i32, i32, ptr, i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)5);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::OMP_Linear, 16}));
+  EXPECT_EQ(VecFuncParameters[2],
+            VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
+  EXPECT_EQ(VecFuncParameters[3],
+            VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
+  EXPECT_EQ(VecFuncParameters[4], VFParameter({4, VFParamKind::OMP_Linear, 1}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ScalarNameAndVectorName_01) {
-  EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "_ZGVnM2v_sin");
+  EXPECT_TRUE(invokeParser("_ZGVnM2v_foo(vector_foo)"));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ScalarNameAndVectorName_02) {
-  EXPECT_TRUE(invokeParser("_ZGVnM2v_sin(UserFunc)", "UserFunc"));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "UserFunc");
+  EXPECT_TRUE(invokeParser("_ZGVnM2v_foo(vector_foo)"));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ScalarNameAndVectorName_03) {
-  EXPECT_TRUE(invokeParser("_ZGVnM2v___sin_sin_sin"));
-  EXPECT_EQ(ScalarName, "__sin_sin_sin");
-  EXPECT_EQ(VectorName, "_ZGVnM2v___sin_sin_sin");
+  EXPECT_TRUE(invokeParser("_ZGVnM2v___foo_bar_abc(fooBarAbcVec)"));
+  EXPECT_EQ(ScalarName, "__foo_bar_abc");
+  EXPECT_EQ(VectorName, "fooBarAbcVec");
 }
 
 TEST_F(VFABIParserTest, Parse) {
   EXPECT_TRUE(
-      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin", "sin",
-                   "void(double, i32, i32, i32, ptr, i32, i32, i32, ptr)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_foo(vector_foo)",
+                   "void(i32, i32, i32, i32, ptr, i32, i32, i32, ptr)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-  EXPECT_EQ(Parameters.size(), (unsigned)9);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
-  EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
-  EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
-  EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
-  EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
-  EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
-  EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
-  EXPECT_EQ(Parameters[8], VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)9);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
+  EXPECT_EQ(VecFuncParameters[2],
+            VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
+  EXPECT_EQ(VecFuncParameters[3],
+            VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
+  EXPECT_EQ(VecFuncParameters[4],
+            VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
+  EXPECT_EQ(VecFuncParameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
+  EXPECT_EQ(VecFuncParameters[6],
+            VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
+  EXPECT_EQ(VecFuncParameters[7],
+            VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
+  EXPECT_EQ(VecFuncParameters[8],
+            VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseVectorName) {
-  EXPECT_TRUE(
-      invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin", "double(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVnN2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-  EXPECT_EQ(Parameters.size(), (unsigned)1);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "my_v_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)1);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin", "",
-                           "double(i32, i32, i32, ptr)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_foo(vector_foo)",
+                           "void(i32, i32, i32, ptr)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-  EXPECT_EQ(Parameters.size(), (unsigned)4);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
-  EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
-  EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "_ZGVnN2ln1Ln10Un100Rn1000_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)4);
+  EXPECT_EQ(VecFuncParameters[0],
+            VFParameter({0, VFParamKind::OMP_Linear, -1}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
+  EXPECT_EQ(VecFuncParameters[2],
+            VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
+  EXPECT_EQ(VecFuncParameters[3],
+            VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseScalableSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsMxv_sin(custom_vg)", "sin", "i32(i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getScalable(4));
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "custom_vg");
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin", "", "double(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, NotAVectorFunctionABIName) {
   // Vector names should start with `_ZGV`.
-  EXPECT_FALSE(invokeParser("ZGVnN2v_sin"));
+  EXPECT_FALSE(invokeParser("ZGVnN2v_foo"));
 }
 
 TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
-  EXPECT_FALSE(invokeParser("_ZGVnN2ls_sin"))
+  EXPECT_FALSE(invokeParser("_ZGVnN2ls_foo"))
       << "A number should be present after \"ls\".";
-  EXPECT_TRUE(invokeParser("_ZGVnN2ls2_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVnN2Rs_sin"))
+  EXPECT_TRUE(invokeParser("_ZGVnN2ls2_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVnN2Rs_foo"))
       << "A number should be present after \"Rs\".";
-  EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVnN2Ls_sin"))
+  EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVnN2Ls_foo"))
       << "A number should be present after \"Ls\".";
-  EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVnN2Us_sin"))
+  EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVnN2Us_foo"))
       << "A number should be present after \"Us\".";
-  EXPECT_TRUE(invokeParser("_ZGVnN2Us8_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2Us8_foo"));
 }
 
 TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
-  EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin", "",
+  EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_foo(vector_foo)",
                            "void(i32, i32, ptr, i32, i32, i32, ptr, i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
-  EXPECT_EQ(Parameters.size(), (unsigned)8);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
-  EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
-  EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
-  EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, -1}));
-  EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
-  EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
-  EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)8);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
+  EXPECT_EQ(VecFuncParameters[2],
+            VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
+  EXPECT_EQ(VecFuncParameters[3],
+            VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
+  EXPECT_EQ(VecFuncParameters[4],
+            VFParameter({4, VFParamKind::OMP_Linear, -1}));
+  EXPECT_EQ(VecFuncParameters[5],
+            VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
+  EXPECT_EQ(VecFuncParameters[6],
+            VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
+  EXPECT_EQ(VecFuncParameters[7],
+            VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ISA) {
-  EXPECT_TRUE(invokeParser("_ZGVqN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVqN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::Unknown);
 
-  EXPECT_TRUE(invokeParser("_ZGVnN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
 
-  EXPECT_TRUE(invokeParser("_ZGVsN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVsN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::SVE);
 
-  EXPECT_TRUE(invokeParser("_ZGVbN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVbN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::SSE);
 
-  EXPECT_TRUE(invokeParser("_ZGVcN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVcN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::AVX);
 
-  EXPECT_TRUE(invokeParser("_ZGVdN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVdN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::AVX2);
 
-  EXPECT_TRUE(invokeParser("_ZGVeN2v_sin"));
+  EXPECT_TRUE(invokeParser("_ZGVeN2v_foo"));
   EXPECT_EQ(ISA, VFISAKind::AVX512);
 }
 
 TEST_F(VFABIParserTest, LLVM_ISA) {
-  EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
-  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
+  EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_foo"));
+  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_foo(vector_foo)", "void(i32)"));
   EXPECT_EQ(ISA, VFISAKind::LLVM);
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)1);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, InvalidMask) {
-  EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsK2v_foo"));
 }
 
 TEST_F(VFABIParserTest, InvalidParameter) {
-  EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsM2vX_foo"));
 }
 
 TEST_F(VFABIParserTest, Align) {
-  EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin", "", "void(i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
-  EXPECT_EQ(Parameters.size(), (unsigned)1);
-  EXPECT_EQ(Parameters[0].Alignment, Align(2));
+  EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)1);
+  EXPECT_EQ(VecFuncParameters[0].Alignment, Align(2));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 
   // Missing alignment value.
-  EXPECT_FALSE(invokeParser("_ZGVsM2l2a_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsM2l2a_foo"));
   // Invalid alignment token "x".
-  EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_foo"));
   // Alignment MUST be associated to a paramater.
-  EXPECT_FALSE(invokeParser("_ZGVsM2a2_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsM2a2_foo"));
   // Alignment must be a power of 2.
-  EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_sin"));
-  EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_foo"));
+  EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_foo"));
 }
 
 TEST_F(VFABIParserTest, ParseUniform) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2u_sin", "", "void(i32)"));
+  EXPECT_TRUE(invokeParser("_ZGVnN2u_foo(vector_foo)", "void(i32)"));
   EXPECT_EQ(VF, ElementCount::getFixed(2));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_FALSE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-  EXPECT_EQ(Parameters.size(), (unsigned)1);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "_ZGVnN2u_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)1);
+  EXPECT_EQ(VecFuncParameters[0],
+            VFParameter({0, VFParamKind::OMP_Uniform, 0}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 
   // Uniform doesn't expect extra data.
-  EXPECT_FALSE(invokeParser("_ZGVnN2u0_sin"));
+  EXPECT_FALSE(invokeParser("_ZGVnN2u0_foo"));
 }
 
 TEST_F(VFABIParserTest, ISAIndependentMangling) {
   // This test makes sure that the mangling of the parameters in
   // independent on the <isa> token.
+  const StringRef IRTy =
+      "void(i32, i32, i32, i32, ptr, i32, i32, i32, i32, i32)";
   const SmallVector<VFParameter, 8> ExpectedParams = {
       VFParameter({0, VFParamKind::Vector, 0}),
       VFParameter({1, VFParamKind::OMP_LinearPos, 2}),
@@ -373,72 +406,62 @@ TEST_F(VFABIParserTest, ISAIndependentMangling) {
   do {                                                                         \
     EXPECT_EQ(VF, ElementCount::getFixed(2));                                  \
     EXPECT_FALSE(isMasked());                                                  \
-    EXPECT_TRUE(matchScalarParametersNum());                                   \
-    EXPECT_EQ(Parameters.size(), (unsigned)10);                                \
-    EXPECT_EQ(Parameters, ExpectedParams);                                     \
-    EXPECT_EQ(ScalarName, "sin");                                              \
+    EXPECT_TRUE(matchScalarParamNum())                                         \
+        << "Different number of Scalar parameters";                            \
+    EXPECT_EQ(VecFuncParameters.size(), (unsigned)10);                         \
+    EXPECT_EQ(VecFuncParameters, ExpectedParams);                              \
+    EXPECT_EQ(ScalarName, "foo");                                              \
+    EXPECT_EQ(VectorName, "vector_foo");                                       \
   } while (0)
 
-  const StringRef IRTy =
-      "void(double, i32, i32, i32, ptr, i32, i32, i32, i32, i32)";
-
   // Advanced SIMD: <isa> = "n"
-  EXPECT_TRUE(
-      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // SVE: <isa> = "s"
-  EXPECT_TRUE(
-      invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::SVE);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // SSE: <isa> = "b"
-  EXPECT_TRUE(
-      invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::SSE);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX: <isa> = "c"
-  EXPECT_TRUE(
-      invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX2: <isa> = "d"
-  EXPECT_TRUE(
-      invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX2);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // AVX512: <isa> = "e"
-  EXPECT_TRUE(
-      invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::AVX512);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
   // LLVM: <isa> = "_LLVM_" internal vector function.
-  EXPECT_TRUE(
-      invokeParser("_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)",
-                   "vectorf", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::LLVM);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "vectorf");
 
   // Unknown ISA (randomly using "q"). This test will need update if
   // some targets decide to use "q" as their ISA token.
-  EXPECT_TRUE(
-      invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin", "", IRTy));
+  EXPECT_TRUE(invokeParser(
+      "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_foo(vector_foo)", IRTy));
   EXPECT_EQ(ISA, VFISAKind::Unknown);
   __COMMON_CHECKS;
-  EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
 
 #undef __COMMON_CHECKS
 }
@@ -456,123 +479,181 @@ TEST_F(VFABIParserTest, MissingVectorNameTermination) {
 }
 
 TEST_F(VFABIParserTest, ParseMaskingNEON) {
-  EXPECT_TRUE(invokeParser("_ZGVnM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVnM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingSSE) {
-  EXPECT_TRUE(invokeParser("_ZGVbM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVbM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SSE);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX) {
-  EXPECT_TRUE(invokeParser("_ZGVcM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVcM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX2) {
-  EXPECT_TRUE(invokeParser("_ZGVdM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVdM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX2);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingAVX512) {
-  EXPECT_TRUE(invokeParser("_ZGVeM2v_sin", "", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVeM2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::AVX512);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseMaskingLLVM) {
-  EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_sin(custom_vector_sin)",
-                           "custom_vector_sin", "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::LLVM);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "custom_vector_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseScalableMaskingLLVM) {
-  EXPECT_FALSE(
-      invokeParser("_ZGV_LLVM_Mxv_sin(custom_vector_sin)", "sin", "i32(i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_FALSE(invokeParser("_ZGV_LLVM_Mxv_foo(vector_foo)"));
+}
+
+TEST_F(VFABIParserTest, LLVM_InternalISA) {
+  EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_foo"));
+  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_foo(vector_foo)", "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)1);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(ISA, VFISAKind::LLVM);
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
+}
+
+TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
+  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)",
+                           "void(float, float)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VF, ElementCount::getFixed(4));
+  EXPECT_FALSE(isMasked());
+  EXPECT_EQ(ISA, VFISAKind::LLVM);
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1], VFParameter({1, VFParamKind::Vector}));
+  EXPECT_EQ(ScalarName, "llvm.pow.f32");
+  EXPECT_EQ(VectorName, "__svml_powf4");
+}
+
+TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
+  const char *MangledName = "_ZGVsMxv_sin(custom_vg)";
+  // The parser succeeds only when the correct function definition of
+  // `custom_vg` is added to the module.
+  EXPECT_FALSE(invokeParser(MangledName));
+  EXPECT_TRUE(invokeParser(MangledName, "void(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "sin");
+  EXPECT_EQ(VectorName, "custom_vg");
+}
+
+TEST_F(VFABIParserTest, ZeroIsInvalidVLEN) {
+  EXPECT_FALSE(invokeParser("_ZGVeM0v_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVeN0v_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVsM0v_foo"));
+  EXPECT_FALSE(invokeParser("_ZGVsN0v_foo"));
 }
 
 TEST_F(VFABIParserTest, ParseScalableMaskingSVE) {
-  EXPECT_TRUE(
-      invokeParser("_ZGVsMxv_sin(custom_vector_sin)", "sin", "i32(i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "i32(i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(VF, ElementCount::getScalable(4));
   EXPECT_EQ(ISA, VFISAKind::SVE);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(ScalarName, "sin");
-  EXPECT_EQ(VectorName, "custom_vector_sin");
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseScalableMaskingSVESincos) {
   EXPECT_TRUE(invokeParser("_ZGVsMxvl8l8_sincos(custom_vector_sincos)",
-                           "sincos", "void(double, ptr, ptr)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+                           "void(double, ptr, ptr)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getScalable(2));
   EXPECT_TRUE(isMasked());
   EXPECT_EQ(ISA, VFISAKind::SVE);
-  EXPECT_EQ(Parameters.size(), (unsigned)4);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 8}));
-  EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_Linear, 8}));
-  EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)4);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1], VFParameter({1, VFParamKind::OMP_Linear, 8}));
+  EXPECT_EQ(VecFuncParameters[2], VFParameter({2, VFParamKind::OMP_Linear, 8}));
+  EXPECT_EQ(VecFuncParameters[3],
+            VFParameter({3, VFParamKind::GlobalPredicate}));
   EXPECT_EQ(ScalarName, "sincos");
   EXPECT_EQ(VectorName, "custom_vector_sincos");
 }
@@ -580,27 +661,39 @@ TEST_F(VFABIParserTest, ParseScalableMaskingSVESincos) {
 // Make sure that we get the correct VF if the return type is wider than any
 // parameter type.
 TEST_F(VFABIParserTest, ParseWiderReturnTypeSVE) {
-  EXPECT_TRUE(
-      invokeParser("_ZGVsMxvv_foo(vector_foo)", "foo", "i64(i32, i32)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsMxvv_foo(vector_foo)", "i64(i32, i32)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)3);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1], VFParameter({1, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[2],
+            VFParameter({2, VFParamKind::GlobalPredicate}));
   EXPECT_EQ(VF, ElementCount::getScalable(2));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 // Make sure we handle void return types.
 TEST_F(VFABIParserTest, ParseVoidReturnTypeSVE) {
-  EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "foo", "void(i16)"));
-  EXPECT_TRUE(matchScalarParametersNum());
+  EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "void(i16)"));
+  EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
+  EXPECT_EQ(VecFuncParameters.size(), (unsigned)2);
+  EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VecFuncParameters[1],
+            VFParameter({1, VFParamKind::GlobalPredicate}));
   EXPECT_EQ(VF, ElementCount::getScalable(8));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
 }
 
 // Make sure we reject unsupported parameter types.
 TEST_F(VFABIParserTest, ParseUnsupportedElementTypeSVE) {
-  EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "foo", "void(i128)"));
+  EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "void(i128)"));
 }
 
 // Make sure we reject unsupported return types
 TEST_F(VFABIParserTest, ParseUnsupportedReturnTypeSVE) {
-  EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "foo", "fp128(float)"));
+  EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "fp128(float)"));
 }
 class VFABIAttrTest : public testing::Test {
 protected:
@@ -636,43 +729,6 @@ TEST_F(VFABIAttrTest, Read) {
   EXPECT_EQ(Mappings, Exp);
 }
 
-TEST_F(VFABIParserTest, LLVM_InternalISA) {
-  EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
-  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name",
-                           "void(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
-  EXPECT_EQ(ISA, VFISAKind::LLVM);
-}
-
-TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
-  EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)",
-                           "__svml_powf4", "void(float, float)"));
-  EXPECT_TRUE(matchScalarParametersNum());
-  EXPECT_EQ(VF, ElementCount::getFixed(4));
-  EXPECT_FALSE(isMasked());
-  EXPECT_EQ(ISA, VFISAKind::LLVM);
-  EXPECT_EQ(Parameters.size(), (unsigned)2);
-  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::Vector}));
-  EXPECT_EQ(ScalarName, "llvm.pow.f32");
-}
-
-TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
-  const char *MangledName = "_ZGVsMxv_sin(custom_vg)";
-  // The parser succeds only when the correct function definition of
-  // `custom_vg` is added to the module.
-  EXPECT_FALSE(invokeParser(MangledName));
-  EXPECT_TRUE(invokeParser(MangledName, "sin", "double(double)"));
-  EXPECT_TRUE(matchScalarParametersNum());
-}
-
-TEST_F(VFABIParserTest, ZeroIsInvalidVLEN) {
-  EXPECT_FALSE(invokeParser("_ZGVeM0v_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVeN0v_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVsM0v_sin"));
-  EXPECT_FALSE(invokeParser("_ZGVsN0v_sin"));
-}
-
 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/Analysis/VectorUtilsTest.cpp b/llvm/unittests/Analysis/VectorUtilsTest.cpp
index c7419e0321235e5..1b3a8b0259f0176 100644
--- a/llvm/unittests/Analysis/VectorUtilsTest.cpp
+++ b/llvm/unittests/Analysis/VectorUtilsTest.cpp
@@ -580,7 +580,7 @@ class VFShapeAPITest : public testing::Test {
   SmallVector<VFParameter, 8> &ExpectedParams = Expected.Parameters;
 
   void buildShape(ElementCount VF, bool HasGlobalPred) {
-    Shape = VFShape::get(*CI, VF, HasGlobalPred);
+    Shape = VFShape::get(CI->getFunctionType(), VF, HasGlobalPred);
   }
 
   bool validParams(ArrayRef<VFParameter> Parameters) {
@@ -619,11 +619,11 @@ TEST_F(VFShapeAPITest, API_buildVFShape) {
 
 TEST_F(VFShapeAPITest, API_getScalarShape) {
   buildShape(/*VF*/ ElementCount::getFixed(1), /*HasGlobalPred*/ false);
-  EXPECT_EQ(VFShape::getScalarShape(*CI), Shape);
+  EXPECT_EQ(VFShape::getScalarShape(CI->getFunctionType()), Shape);
 }
 
 TEST_F(VFShapeAPITest, API_getVectorizedFunction) {
-  VFShape ScalarShape = VFShape::getScalarShape(*CI);
+  VFShape ScalarShape = VFShape::getScalarShape(CI->getFunctionType());
   EXPECT_EQ(VFDatabase(*CI).getVectorizedFunction(ScalarShape),
             M->getFunction("g"));
 

>From f8d6c2c6dd2b106b9f4780f6319af133be66057f Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Thu, 30 Nov 2023 17:51:23 +0000
Subject: [PATCH 3/6] Addressing 2nd review round.

- Clean up duplicate ISA tests.
- Added an extra test to clearly show that the mangled name becomes the
  VectorName, when no VectorName is specified.
---
 .../Analysis/VectorFunctionABITest.cpp        | 68 +++++++------------
 1 file changed, 24 insertions(+), 44 deletions(-)

diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index 50c3fdebd762fef..3adf6e97a7b7ddc 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -21,18 +21,15 @@ class VFABIParserTest : public ::testing::Test {
   // Parser output.
   VFInfo Info;
   // Reset the data needed for the test.
-  void reset(const StringRef Name, const StringRef IRType) {
+  void reset(const StringRef SFunTy) {
     M = parseAssemblyString("declare void @dummy()", Err, Ctx);
     EXPECT_NE(M.get(), nullptr) << "Loading an invalid module.\n "
                                 << Err.getMessage() << "\n";
-    Type *Ty = parseType(IRType, Err, *(M.get()));
-    FTy = dyn_cast<FunctionType>(Ty);
-    EXPECT_NE(FTy, nullptr) << "Invalid function type string: " << IRType
+    Type *Ty = parseType(SFunTy, Err, *(M.get()));
+    ScalarFTy = dyn_cast<FunctionType>(Ty);
+    EXPECT_NE(ScalarFTy, nullptr) << "Invalid function type string: " << SFunTy
                             << "\n"
                             << Err.getMessage() << "\n";
-    F = M->getOrInsertFunction(Name, FTy);
-    EXPECT_NE(F.getCallee(), nullptr)
-        << "The function must be present in the module\n";
     // Reset the VFInfo
     Info = VFInfo();
     ScalarFuncParametersNum = 0;
@@ -42,7 +39,7 @@ class VFABIParserTest : public ::testing::Test {
   LLVMContext Ctx;
   SMDiagnostic Err;
   std::unique_ptr<Module> M;
-  FunctionType *FTy = nullptr;
+  FunctionType *ScalarFTy = nullptr;
   FunctionCallee F;
 
 protected:
@@ -64,23 +61,23 @@ class VFABIParserTest : public ::testing::Test {
   // use to create the function in the module if it differs from the
   // standard mangled name.
   //
-  // \p IRType -> FunctionType string to be used for the signature of
+  // \p STy -> FunctionType string to be used for the signature of
   // the vector function.  The correct signature is needed by the
   // parser only for scalable functions. For the sake of testing, the
   // generic fixed-length case can use as signature `void()`.
   //
   bool invokeParser(const StringRef MangledName,
-                    const StringRef IRType = "void()") {
-    // Reset the VFInfo and the Module to be able to invoke
-    // `invokeParser` multiple times in the same test.
-    reset(MangledName, IRType);
+                    const StringRef SFunTy = "void()") {
+    // Reset the VFInfo and the Module to be able to invoke `invokeParser`
+    // multiple times in the same test.
+    reset(SFunTy);
 
     // Fake the arguments to the CallInst.
-    const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, FTy);
+    const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy);
     if (OptInfo) {
       Info = *OptInfo;
       ScalarFuncParametersNum =
-          Info.Shape.getScalarShape(FTy).Parameters.size();
+          Info.Shape.getScalarShape(ScalarFTy).Parameters.size();
       return true;
     }
     return false;
@@ -138,7 +135,7 @@ TEST_F(VFABIParserTest, OnlyValidNames) {
 }
 
 TEST_F(VFABIParserTest, ParamListParsing) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo(vector_foo)",
+  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo",
                            "void(i32, i32, i32, ptr, i32)"));
   EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VecFuncParameters.size(), (unsigned)5);
@@ -151,7 +148,7 @@ TEST_F(VFABIParserTest, ParamListParsing) {
             VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
   EXPECT_EQ(VecFuncParameters[4], VFParameter({4, VFParamKind::OMP_Linear, 1}));
   EXPECT_EQ(ScalarName, "foo");
-  EXPECT_EQ(VectorName, "vector_foo");
+  EXPECT_EQ(VectorName, "_ZGVnN2vl16Ls32R3l_foo");
 }
 
 TEST_F(VFABIParserTest, ScalarNameAndVectorName_01) {
@@ -172,9 +169,17 @@ TEST_F(VFABIParserTest, ScalarNameAndVectorName_03) {
   EXPECT_EQ(VectorName, "fooBarAbcVec");
 }
 
+TEST_F(VFABIParserTest, ScalarNameOnly) {
+  EXPECT_TRUE(invokeParser("_ZGVnM2v___foo_bar_abc"));
+  EXPECT_EQ(ScalarName, "__foo_bar_abc");
+  // no vector name specified (as it's optional), so it should have the entire
+  // mangled name.
+  EXPECT_EQ(VectorName, "_ZGVnM2v___foo_bar_abc");
+}
+
 TEST_F(VFABIParserTest, Parse) {
   EXPECT_TRUE(
-      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_foo(vector_foo)",
+      invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_foo",
                    "void(i32, i32, i32, i32, ptr, i32, i32, i32, ptr)"));
   EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VF, ElementCount::getFixed(2));
@@ -198,7 +203,7 @@ TEST_F(VFABIParserTest, Parse) {
   EXPECT_EQ(VecFuncParameters[8],
             VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
   EXPECT_EQ(ScalarName, "foo");
-  EXPECT_EQ(VectorName, "vector_foo");
+  EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_foo");
 }
 
 TEST_F(VFABIParserTest, ParseVectorName) {
@@ -305,29 +310,6 @@ TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
   EXPECT_EQ(VectorName, "vector_foo");
 }
 
-TEST_F(VFABIParserTest, ISA) {
-  EXPECT_TRUE(invokeParser("_ZGVqN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::Unknown);
-
-  EXPECT_TRUE(invokeParser("_ZGVnN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
-
-  EXPECT_TRUE(invokeParser("_ZGVsN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::SVE);
-
-  EXPECT_TRUE(invokeParser("_ZGVbN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::SSE);
-
-  EXPECT_TRUE(invokeParser("_ZGVcN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::AVX);
-
-  EXPECT_TRUE(invokeParser("_ZGVdN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::AVX2);
-
-  EXPECT_TRUE(invokeParser("_ZGVeN2v_foo"));
-  EXPECT_EQ(ISA, VFISAKind::AVX512);
-}
-
 TEST_F(VFABIParserTest, LLVM_ISA) {
   EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_foo"));
   EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_foo(vector_foo)", "void(i32)"));
@@ -607,8 +589,6 @@ TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
 
 TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
   const char *MangledName = "_ZGVsMxv_sin(custom_vg)";
-  // The parser succeeds only when the correct function definition of
-  // `custom_vg` is added to the module.
   EXPECT_FALSE(invokeParser(MangledName));
   EXPECT_TRUE(invokeParser(MangledName, "void(i32)"));
   EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";

>From 32058b2ae50fdd86164bfe370968c8ea16095c46 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Thu, 30 Nov 2023 18:58:16 +0000
Subject: [PATCH 4/6] Clang-format issue.

---
 llvm/unittests/Analysis/VectorFunctionABITest.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index 3adf6e97a7b7ddc..64d0399c69a8a08 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -27,9 +27,9 @@ class VFABIParserTest : public ::testing::Test {
                                 << Err.getMessage() << "\n";
     Type *Ty = parseType(SFunTy, Err, *(M.get()));
     ScalarFTy = dyn_cast<FunctionType>(Ty);
-    EXPECT_NE(ScalarFTy, nullptr) << "Invalid function type string: " << SFunTy
-                            << "\n"
-                            << Err.getMessage() << "\n";
+    EXPECT_NE(ScalarFTy, nullptr)
+        << "Invalid function type string: " << SFunTy << "\n"
+        << Err.getMessage() << "\n";
     // Reset the VFInfo
     Info = VFInfo();
     ScalarFuncParametersNum = 0;
@@ -135,8 +135,8 @@ TEST_F(VFABIParserTest, OnlyValidNames) {
 }
 
 TEST_F(VFABIParserTest, ParamListParsing) {
-  EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo",
-                           "void(i32, i32, i32, ptr, i32)"));
+  EXPECT_TRUE(
+      invokeParser("_ZGVnN2vl16Ls32R3l_foo", "void(i32, i32, i32, ptr, i32)"));
   EXPECT_TRUE(matchScalarParamNum()) << "Different number of Scalar parameters";
   EXPECT_EQ(VecFuncParameters.size(), (unsigned)5);
   EXPECT_EQ(VecFuncParameters[0], VFParameter({0, VFParamKind::Vector}));

>From 591e599fb445f3efaed34ee6cc989b58a86cef67 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Fri, 1 Dec 2023 10:08:27 +0000
Subject: [PATCH 5/6] Made use for Scalar FunctionTypes more clear.

Removed ScalarFuncParametersNum, and now using the ScalarFTy directly,
that is parsed from the input ScalarFTyStr.
---
 .../Analysis/VectorFunctionABITest.cpp        | 43 ++++++++-----------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index 64d0399c69a8a08..3cd7ba981e6e63c 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -32,7 +32,6 @@ class VFABIParserTest : public ::testing::Test {
         << Err.getMessage() << "\n";
     // Reset the VFInfo
     Info = VFInfo();
-    ScalarFuncParametersNum = 0;
   }
 
   // Data needed to load the optional IR passed to invokeParser
@@ -47,37 +46,29 @@ class VFABIParserTest : public ::testing::Test {
   ElementCount &VF = Info.Shape.VF;
   VFISAKind &ISA = Info.ISA;
   SmallVector<VFParameter, 8> &VecFuncParameters = Info.Shape.Parameters;
-  size_t ScalarFuncParametersNum = 0;
   std::string &ScalarName = Info.ScalarName;
   std::string &VectorName = Info.VectorName;
-  // Invoke the parser. We need to make sure that a function exist in
-  // the module because the parser fails if such function don't
-  // exists. Every time this method is invoked the state of the test
-  // is reset.
-  //
-  // \p MangledName -> the string the parser has to demangle.
-  //
-  // \p VectorName -> optional vector name that the method needs to
-  // use to create the function in the module if it differs from the
-  // standard mangled name.
-  //
-  // \p STy -> FunctionType string to be used for the signature of
-  // the vector function.  The correct signature is needed by the
-  // parser only for scalable functions. For the sake of testing, the
-  // generic fixed-length case can use as signature `void()`.
-  //
+
+  /// Invoke the parser. We need to make sure that a function exist in the
+  /// module because the parser fails if such function don't exists. Every time
+  /// this method is invoked the state of the test is reset.
+  ///
+  /// \p MangledName string the parser has to demangle.
+  ///
+  /// \p ScalarFTyStr FunctionType string to be used to get the signature of
+  /// the Scalar function. Used by `tryDemangleForVFABI` to check for the number
+  // of arguments on Scalable vectors, and by `matchScalarParamNum` to perform
+  /// some additional checking in the tests in this file.
   bool invokeParser(const StringRef MangledName,
-                    const StringRef SFunTy = "void()") {
+                    const StringRef ScalarFTyStr = "void()") {
     // Reset the VFInfo and the Module to be able to invoke `invokeParser`
     // multiple times in the same test.
-    reset(SFunTy);
+    reset(ScalarFTyStr);
 
     // Fake the arguments to the CallInst.
     const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy);
     if (OptInfo) {
       Info = *OptInfo;
-      ScalarFuncParametersNum =
-          Info.Shape.getScalarShape(ScalarFTy).Parameters.size();
       return true;
     }
     return false;
@@ -95,10 +86,12 @@ class VFABIParserTest : public ::testing::Test {
                                     VFParamKind::GlobalPredicate;
   }
 
-  // Checks that the number of vectorized parameters matches the scalar ones.
-  // Takes into account that vectorized calls may also have a Mask.
+  // Checks that the number of vectorized parameters matches the
+  // scalar ones. This requires a correct scalar FunctionType string to be fed
+  // to the 'invokeParser'. It takes into account that vectorized calls may also
+  // have a Mask.
   bool matchScalarParamNum() {
-    return (VecFuncParameters.size() - isMasked()) == ScalarFuncParametersNum;
+    return (VecFuncParameters.size() - isMasked()) == ScalarFTy->getNumParams();
   }
 };
 } // unnamed namespace

>From c2447447ebb08684db38ec7e95adb03c63a46973 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Fri, 1 Dec 2023 13:20:41 +0000
Subject: [PATCH 6/6] Fix for demangle-fuzzer tool and minor refactoring

demangle-fuzzer had an extra parenthesis introduced by previous commit
in this PR and it was not formatted properly.

In ABI tests, renamed `reset` parameter to match `invokeParser`, and
did a few more minor styling changes.
---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp             | 2 +-
 llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp | 3 ++-
 llvm/unittests/Analysis/VectorFunctionABITest.cpp           | 6 +++---
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 1fa4b8e28ee9163..d8a3f7ce3ac97f3 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -7581,7 +7581,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
     assert((IsFinalized || CommonMask.empty()) &&
            "Shuffle construction must be finalized.");
   }
-  };
+};
 
 InstructionCost
 BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
diff --git a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
index f81bf6d10b63e01..d5c19d18ca7971e 100644
--- a/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
+++ b/llvm/tools/vfabi-demangle-fuzzer/vfabi-demangler-fuzzer.cpp
@@ -38,7 +38,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
       Args.push_back(Constant::getNullValue(ParamTy));
     }
     std::unique_ptr<CallInst> CI(CallInst::Create(F, Args));
-    const auto Info = VFABI::tryDemangleForVFABI(MangledName, CI->getFunctionType()));
+    const auto Info =
+        VFABI::tryDemangleForVFABI(MangledName, CI->getFunctionType());
 
     // Do not optimize away the return value. Inspired by
     // https://github.com/google/benchmark/blob/main/include/benchmark/benchmark.h#L307-L345
diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index 3cd7ba981e6e63c..480615228c67d97 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -21,14 +21,14 @@ class VFABIParserTest : public ::testing::Test {
   // Parser output.
   VFInfo Info;
   // Reset the data needed for the test.
-  void reset(const StringRef SFunTy) {
+  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";
-    Type *Ty = parseType(SFunTy, Err, *(M.get()));
+    Type *Ty = parseType(ScalarFTyStr, Err, *(M.get()));
     ScalarFTy = dyn_cast<FunctionType>(Ty);
     EXPECT_NE(ScalarFTy, nullptr)
-        << "Invalid function type string: " << SFunTy << "\n"
+        << "Invalid function type string: " << ScalarFTyStr << "\n"
         << Err.getMessage() << "\n";
     // Reset the VFInfo
     Info = VFInfo();



More information about the llvm-commits mailing list