[llvm] [VFABI] Add support for vector functions that return struct types (PR #119000)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 12:58:04 PST 2024


https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/119000

>From 16afa09ae322b88ad452a08fff984463eb306a2a Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 6 Dec 2024 14:26:53 +0000
Subject: [PATCH 01/14] [VFABI] Add support for vector functions that return
 struct types

This patch updates the `VFABIDemangler` to support vector functions that
return struct types. For example, a vector variant of `sincos` that
returns a vector of sine values and a vector of cosine values within a
struct.

This patch also adds some helpers in `llvm/IR/CallWideningUtils.h` for
widening call return types. Some of these are used in the
`VFABIDemangler`, and others will be used in subsequent patches, so this
patch simply adds tests for them.
---
 llvm/include/llvm/Analysis/VectorUtils.h    |  14 +-
 llvm/include/llvm/IR/CallWideningUtils.h    |  44 ++++++
 llvm/include/llvm/IR/VectorUtils.h          |  32 +++++
 llvm/lib/IR/CMakeLists.txt                  |   1 +
 llvm/lib/IR/CallWideningUtils.cpp           |  73 ++++++++++
 llvm/lib/IR/VFABIDemangler.cpp              |  18 ++-
 llvm/unittests/IR/CMakeLists.txt            |   1 +
 llvm/unittests/IR/CallWideningUtilsTest.cpp | 149 ++++++++++++++++++++
 llvm/unittests/IR/VFABIDemanglerTest.cpp    |  67 +++++++++
 9 files changed, 379 insertions(+), 20 deletions(-)
 create mode 100644 llvm/include/llvm/IR/CallWideningUtils.h
 create mode 100644 llvm/include/llvm/IR/VectorUtils.h
 create mode 100644 llvm/lib/IR/CallWideningUtils.cpp
 create mode 100644 llvm/unittests/IR/CallWideningUtilsTest.cpp

diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index c1016dd7bdddbd..5433231a1018e9 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -18,6 +18,7 @@
 #include "llvm/Analysis/LoopAccessAnalysis.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/VFABIDemangler.h"
+#include "llvm/IR/VectorUtils.h"
 #include "llvm/Support/CheckedArithmetic.h"
 
 namespace llvm {
@@ -127,19 +128,6 @@ namespace Intrinsic {
 typedef unsigned ID;
 }
 
-/// A helper function for converting Scalar types to vector types. If
-/// the incoming type is void, we return void. If the EC represents a
-/// scalar, we return the scalar type.
-inline Type *ToVectorTy(Type *Scalar, ElementCount EC) {
-  if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar())
-    return Scalar;
-  return VectorType::get(Scalar, EC);
-}
-
-inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
-  return ToVectorTy(Scalar, ElementCount::getFixed(VF));
-}
-
 /// Identify if the intrinsic is trivially vectorizable.
 /// This method returns true if the intrinsic's argument types are all scalars
 /// for the scalar form of the intrinsic and all vectors (or scalars handled by
diff --git a/llvm/include/llvm/IR/CallWideningUtils.h b/llvm/include/llvm/IR/CallWideningUtils.h
new file mode 100644
index 00000000000000..de51c8f6c6ba1f
--- /dev/null
+++ b/llvm/include/llvm/IR/CallWideningUtils.h
@@ -0,0 +1,44 @@
+//===---- CallWideningUtils.h - Utils for widening scalar to vector calls --==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CALLWIDENINGUTILS_H
+#define LLVM_IR_CALLWIDENINGUTILS_H
+
+#include "llvm/IR/DerivedTypes.h"
+
+namespace llvm {
+
+/// A helper for converting to wider (vector) types. For scalar types, this is
+/// equivalent to calling `ToVectorTy`. For struct types, this returns a new
+/// struct where each element type has been widened to a vector type. Note: Only
+/// unpacked literal struct types are supported.
+Type *ToWideTy(Type *Ty, ElementCount EC);
+
+/// A helper for converting wide types to narrow (non-vector) types. For vector
+/// types, this is equivalent to calling .getScalarType(). For struct types,
+/// this returns a new struct where each element type has been converted to a
+/// scalar type. Note: Only unpacked literal struct types are supported.
+Type *ToNarrowTy(Type *Ty);
+
+/// Returns the types contained in `Ty`. For struct types, it returns the
+/// elements, all other types are returned directly.
+SmallVector<Type *, 2> getContainedTypes(Type *Ty);
+
+/// Returns true if `Ty` is a vector type or a struct of vector types where all
+/// vector types share the same VF.
+bool isWideTy(Type *Ty);
+
+/// Returns the vectorization factor for a widened type.
+inline ElementCount getWideTypeVF(Type *Ty) {
+  assert(isWideTy(Ty) && "expected widened type");
+  return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
+}
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
new file mode 100644
index 00000000000000..a2e34a02e08a67
--- /dev/null
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -0,0 +1,32 @@
+//===----------- VectorUtils.h -  Vector type utility functions -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VECTORUTILS_H
+#define LLVM_IR_VECTORUTILS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DerivedTypes.h"
+
+namespace llvm {
+
+/// A helper function for converting Scalar types to vector types. If
+/// the incoming type is void, we return void. If the EC represents a
+/// scalar, we return the scalar type.
+inline Type *ToVectorTy(Type *Scalar, ElementCount EC) {
+  if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar())
+    return Scalar;
+  return VectorType::get(Scalar, EC);
+}
+
+inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
+  return ToVectorTy(Scalar, ElementCount::getFixed(VF));
+}
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 544f4ea9223d0e..874ee8c4795a96 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMCore
   AutoUpgrade.cpp
   BasicBlock.cpp
   BuiltinGCs.cpp
+  CallWideningUtils.cpp
   Comdat.cpp
   ConstantFold.cpp
   ConstantFPRange.cpp
diff --git a/llvm/lib/IR/CallWideningUtils.cpp b/llvm/lib/IR/CallWideningUtils.cpp
new file mode 100644
index 00000000000000..ec0bc6e3baa463
--- /dev/null
+++ b/llvm/lib/IR/CallWideningUtils.cpp
@@ -0,0 +1,73 @@
+//===----------- VectorUtils.cpp - Vector type utility functions ----------===//
+//
+// 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/IR/CallWideningUtils.h"
+#include "llvm/ADT/SmallVectorExtras.h"
+#include "llvm/IR/VectorUtils.h"
+
+using namespace llvm;
+
+/// A helper for converting to wider (vector) types. For scalar types, this is
+/// equivalent to calling `ToVectorTy`. For struct types, this returns a new
+/// struct where each element type has been widened to a vector type. Note: Only
+/// unpacked literal struct types are supported.
+Type *llvm::ToWideTy(Type *Ty, ElementCount EC) {
+  if (EC.isScalar())
+    return Ty;
+  auto *StructTy = dyn_cast<StructType>(Ty);
+  if (!StructTy)
+    return ToVectorTy(Ty, EC);
+  assert(StructTy->isLiteral() && !StructTy->isPacked() &&
+         "expected unpacked struct literal");
+  return StructType::get(
+      Ty->getContext(),
+      map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
+        return VectorType::get(ElTy, EC);
+      }));
+}
+
+/// A helper for converting wide types to narrow (non-vector) types. For vector
+/// types, this is equivalent to calling .getScalarType(). For struct types,
+/// this returns a new struct where each element type has been converted to a
+/// scalar type. Note: Only unpacked literal struct types are supported.
+Type *llvm::ToNarrowTy(Type *Ty) {
+  auto *StructTy = dyn_cast<StructType>(Ty);
+  if (!StructTy)
+    return Ty->getScalarType();
+  assert(StructTy->isLiteral() && !StructTy->isPacked() &&
+         "expected unpacked struct literal");
+  return StructType::get(
+      Ty->getContext(),
+      map_to_vector(StructTy->elements(), [](Type *ElTy) -> Type * {
+        return ElTy->getScalarType();
+      }));
+}
+
+/// Returns the types contained in `Ty`. For struct types, it returns the
+/// elements, all other types are returned directly.
+SmallVector<Type *, 2> llvm::getContainedTypes(Type *Ty) {
+  auto *StructTy = dyn_cast<StructType>(Ty);
+  if (StructTy)
+    return to_vector<2>(StructTy->elements());
+  return {Ty};
+}
+
+/// Returns true if `Ty` is a vector type or a struct of vector types where all
+/// vector types share the same VF.
+bool llvm::isWideTy(Type *Ty) {
+  auto *StructTy = dyn_cast<StructType>(Ty);
+  if (StructTy && (!StructTy->isLiteral() || StructTy->isPacked()))
+    return false;
+  auto ContainedTys = getContainedTypes(Ty);
+  if (ContainedTys.empty() || !ContainedTys.front()->isVectorTy())
+    return false;
+  ElementCount VF = cast<VectorType>(ContainedTys.front())->getElementCount();
+  return all_of(ContainedTys, [&](Type *Ty) {
+    return Ty->isVectorTy() && cast<VectorType>(Ty)->getElementCount() == VF;
+  });
+}
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index 897583084bf38c..19c922c8bf035b 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -10,6 +10,7 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/CallWideningUtils.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -346,12 +347,15 @@ getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA,
   // Also check the return type if not void.
   Type *RetTy = Signature->getReturnType();
   if (!RetTy->isVoidTy()) {
-    std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA, RetTy);
-    // If we have an unknown scalar element type we can't find a reasonable VF.
-    if (!ReturnEC)
-      return std::nullopt;
-    if (ElementCount::isKnownLT(*ReturnEC, MinEC))
-      MinEC = *ReturnEC;
+    for (Type *RetTy : getContainedTypes(RetTy)) {
+      std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA, RetTy);
+      // If we have an unknown scalar element type we can't find a reasonable
+      // VF.
+      if (!ReturnEC)
+        return std::nullopt;
+      if (ElementCount::isKnownLT(*ReturnEC, MinEC))
+        MinEC = *ReturnEC;
+    }
   }
 
   // The SVE Vector function call ABI bases the VF on the widest element types
@@ -566,7 +570,7 @@ FunctionType *VFABI::createFunctionType(const VFInfo &Info,
 
   auto *RetTy = ScalarFTy->getReturnType();
   if (!RetTy->isVoidTy())
-    RetTy = VectorType::get(RetTy, VF);
+    RetTy = ToWideTy(RetTy, VF);
   return FunctionType::get(RetTy, VecTypes, false);
 }
 
diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt
index ed93ee547d2231..c4cc1bd78403a8 100644
--- a/llvm/unittests/IR/CMakeLists.txt
+++ b/llvm/unittests/IR/CMakeLists.txt
@@ -15,6 +15,7 @@ add_llvm_unittest(IRTests
   AttributesTest.cpp
   BasicBlockTest.cpp
   BasicBlockDbgInfoTest.cpp
+  CallWideningUtilsTest.cpp
   CFGBuilder.cpp
   ConstantFPRangeTest.cpp
   ConstantRangeTest.cpp
diff --git a/llvm/unittests/IR/CallWideningUtilsTest.cpp b/llvm/unittests/IR/CallWideningUtilsTest.cpp
new file mode 100644
index 00000000000000..939806212eee6a
--- /dev/null
+++ b/llvm/unittests/IR/CallWideningUtilsTest.cpp
@@ -0,0 +1,149 @@
+//===------- CallWideningUtilsTest.cpp - Call widening utils tests --------===//
+//
+// 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/IR/CallWideningUtils.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class CallWideningUtilsTest : public ::testing::Test {};
+
+TEST(CallWideningUtilsTest, TestToWideTy) {
+  LLVMContext C;
+
+  Type *ITy = Type::getInt32Ty(C);
+  Type *FTy = Type::getFloatTy(C);
+  Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
+  Type *MixedStructTy = StructType::get(FTy, ITy);
+  Type *VoidTy = Type::getVoidTy(C);
+
+  for (ElementCount VF :
+       {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
+    Type *IntVec = ToWideTy(ITy, VF);
+    EXPECT_TRUE(isa<VectorType>(IntVec));
+    EXPECT_EQ(IntVec, VectorType::get(ITy, VF));
+
+    Type *FloatVec = ToWideTy(FTy, VF);
+    EXPECT_TRUE(isa<VectorType>(FloatVec));
+    EXPECT_EQ(FloatVec, VectorType::get(FTy, VF));
+
+    Type *WideHomogeneousStructTy = ToWideTy(HomogeneousStructTy, VF);
+    EXPECT_TRUE(isa<StructType>(WideHomogeneousStructTy));
+    EXPECT_TRUE(
+        cast<StructType>(WideHomogeneousStructTy)->containsHomogeneousTypes());
+    EXPECT_TRUE(cast<StructType>(WideHomogeneousStructTy)->getNumElements() ==
+                3);
+    EXPECT_TRUE(cast<StructType>(WideHomogeneousStructTy)->getElementType(0) ==
+                VectorType::get(FTy, VF));
+
+    Type *WideMixedStructTy = ToWideTy(MixedStructTy, VF);
+    EXPECT_TRUE(isa<StructType>(WideMixedStructTy));
+    EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getNumElements() == 2);
+    EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(0) ==
+                VectorType::get(FTy, VF));
+    EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(1) ==
+                VectorType::get(ITy, VF));
+
+    EXPECT_EQ(ToWideTy(VoidTy, VF), VoidTy);
+  }
+
+  ElementCount ScalarVF = ElementCount::getFixed(1);
+  for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
+    EXPECT_EQ(ToWideTy(Ty, ScalarVF), Ty);
+  }
+}
+
+TEST(CallWideningUtilsTest, TestToNarrowTy) {
+  LLVMContext C;
+
+  Type *ITy = Type::getInt32Ty(C);
+  Type *FTy = Type::getFloatTy(C);
+  Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
+  Type *MixedStructTy = StructType::get(FTy, ITy);
+  Type *VoidTy = Type::getVoidTy(C);
+
+  for (ElementCount VF : {ElementCount::getFixed(1), ElementCount::getFixed(4),
+                          ElementCount::getScalable(2)}) {
+    for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
+      // ToNarrowTy should be the inverse of ToWideTy.
+      EXPECT_EQ(ToNarrowTy(ToWideTy(Ty, VF)), Ty);
+    };
+  }
+}
+
+TEST(CallWideningUtilsTest, TestGetContainedTypes) {
+  LLVMContext C;
+
+  Type *ITy = Type::getInt32Ty(C);
+  Type *FTy = Type::getFloatTy(C);
+  Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
+  Type *MixedStructTy = StructType::get(FTy, ITy);
+  Type *VoidTy = Type::getVoidTy(C);
+
+  EXPECT_EQ(getContainedTypes(ITy), SmallVector<Type *>({ITy}));
+  EXPECT_EQ(getContainedTypes(FTy), SmallVector<Type *>({FTy}));
+  EXPECT_EQ(getContainedTypes(VoidTy), SmallVector<Type *>({VoidTy}));
+  EXPECT_EQ(getContainedTypes(HomogeneousStructTy),
+            SmallVector<Type *>({FTy, FTy, FTy}));
+  EXPECT_EQ(getContainedTypes(MixedStructTy), SmallVector<Type *>({FTy, ITy}));
+}
+
+TEST(CallWideningUtilsTest, TestIsWideTy) {
+  LLVMContext C;
+
+  Type *ITy = Type::getInt32Ty(C);
+  Type *FTy = Type::getFloatTy(C);
+  Type *NarrowStruct = StructType::get(FTy, ITy);
+  Type *VoidTy = Type::getVoidTy(C);
+
+  EXPECT_FALSE(isWideTy(ITy));
+  EXPECT_FALSE(isWideTy(NarrowStruct));
+  EXPECT_FALSE(isWideTy(VoidTy));
+
+  ElementCount VF = ElementCount::getFixed(4);
+  EXPECT_TRUE(isWideTy(ToWideTy(ITy, VF)));
+  EXPECT_TRUE(isWideTy(ToWideTy(NarrowStruct, VF)));
+
+  Type *MixedVFStruct =
+      StructType::get(VectorType::get(ITy, ElementCount::getFixed(2)),
+                      VectorType::get(ITy, ElementCount::getFixed(4)));
+  EXPECT_FALSE(isWideTy(MixedVFStruct));
+
+  // Currently only literals types are considered wide.
+  Type *NamedWideStruct = StructType::create("Named", VectorType::get(ITy, VF),
+                                             VectorType::get(ITy, VF));
+  EXPECT_FALSE(isWideTy(NamedWideStruct));
+
+  // Currently only unpacked types are considered wide.
+  Type *PackedWideStruct = StructType::get(
+      C, ArrayRef<Type *>{VectorType::get(ITy, VF), VectorType::get(ITy, VF)},
+      /*isPacked=*/true);
+  EXPECT_FALSE(isWideTy(PackedWideStruct));
+}
+
+TEST(CallWideningUtilsTest, TestGetWideTypeVF) {
+  LLVMContext C;
+
+  Type *ITy = Type::getInt32Ty(C);
+  Type *FTy = Type::getFloatTy(C);
+  Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
+  Type *MixedStructTy = StructType::get(FTy, ITy);
+
+  for (ElementCount VF :
+       {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
+    for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy}) {
+      EXPECT_EQ(getWideTypeVF(ToWideTy(Ty, VF)), VF);
+    };
+  }
+}
+
+} // namespace
diff --git a/llvm/unittests/IR/VFABIDemanglerTest.cpp b/llvm/unittests/IR/VFABIDemanglerTest.cpp
index 07bff16df49335..896cd48ad11d6d 100644
--- a/llvm/unittests/IR/VFABIDemanglerTest.cpp
+++ b/llvm/unittests/IR/VFABIDemanglerTest.cpp
@@ -753,6 +753,73 @@ TEST_F(VFABIParserTest, ParseVoidReturnTypeSVE) {
   EXPECT_EQ(VectorName, "vector_foo");
 }
 
+TEST_F(VFABIParserTest, ParseWideStructReturnTypeSVE) {
+  EXPECT_TRUE(
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "{double, double}(float)"));
+  EXPECT_EQ(ISA, VFISAKind::SVE);
+  EXPECT_TRUE(isMasked());
+  FunctionType *FTy = FunctionType::get(
+      StructType::get(
+          VectorType::get(Type::getDoubleTy(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getDoubleTy(Ctx),
+                          ElementCount::getScalable(2))),
+      {
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getInt1Ty(Ctx), ElementCount::getScalable(2)),
+      },
+      false);
+  EXPECT_EQ(getFunctionType(), FTy);
+  EXPECT_EQ(Parameters.size(), 2U);
+  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(VF, ElementCount::getScalable(2));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
+}
+
+TEST_F(VFABIParserTest, ParseWideStructMixedReturnTypeSVE) {
+  EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "{float, i64}(float)"));
+  EXPECT_EQ(ISA, VFISAKind::SVE);
+  EXPECT_TRUE(isMasked());
+  FunctionType *FTy = FunctionType::get(
+      StructType::get(
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getInt64Ty(Ctx), ElementCount::getScalable(2))),
+      {
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getInt1Ty(Ctx), ElementCount::getScalable(2)),
+      },
+      false);
+  EXPECT_EQ(getFunctionType(), FTy);
+  EXPECT_EQ(Parameters.size(), 2U);
+  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
+  EXPECT_EQ(VF, ElementCount::getScalable(2));
+  EXPECT_EQ(ScalarName, "foo");
+  EXPECT_EQ(VectorName, "vector_foo");
+}
+
+TEST_F(VFABIParserTest, ParseWideStructReturnTypeNEON) {
+  EXPECT_TRUE(
+      invokeParser("_ZGVnN2v_foo(vector_foo)", "{float, float}(float)"));
+  EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
+  EXPECT_FALSE(isMasked());
+  FunctionType *FTy = FunctionType::get(
+      StructType::get(
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2)),
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2))),
+      {
+          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2)),
+      },
+      false);
+  EXPECT_EQ(getFunctionType(), FTy);
+  EXPECT_EQ(Parameters.size(), 1U);
+  EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
+  EXPECT_EQ(VF, ElementCount::getFixed(2));
+  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)", "void(i128)"));

>From 349b678f7553f0b25e9dd85cde7230da2db2e75c Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 12 Dec 2024 17:18:37 +0000
Subject: [PATCH 02/14] Fixups

---
 llvm/include/llvm/IR/CallWideningUtils.h      | 44 -----------
 llvm/include/llvm/IR/StructWideningUtils.h    | 32 ++++++++
 llvm/include/llvm/IR/VectorUtils.h            | 46 +++++++++++-
 llvm/lib/IR/CMakeLists.txt                    |  2 +-
 llvm/lib/IR/CallWideningUtils.cpp             | 73 -------------------
 llvm/lib/IR/StructWideningUtils.cpp           | 57 +++++++++++++++
 llvm/lib/IR/VFABIDemangler.cpp                |  2 +-
 llvm/unittests/IR/CMakeLists.txt              |  2 +-
 ...eningUtilsTest.cpp => VectorUtilsTest.cpp} | 26 +++----
 9 files changed, 149 insertions(+), 135 deletions(-)
 delete mode 100644 llvm/include/llvm/IR/CallWideningUtils.h
 create mode 100644 llvm/include/llvm/IR/StructWideningUtils.h
 delete mode 100644 llvm/lib/IR/CallWideningUtils.cpp
 create mode 100644 llvm/lib/IR/StructWideningUtils.cpp
 rename llvm/unittests/IR/{CallWideningUtilsTest.cpp => VectorUtilsTest.cpp} (86%)

diff --git a/llvm/include/llvm/IR/CallWideningUtils.h b/llvm/include/llvm/IR/CallWideningUtils.h
deleted file mode 100644
index de51c8f6c6ba1f..00000000000000
--- a/llvm/include/llvm/IR/CallWideningUtils.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===---- CallWideningUtils.h - Utils for widening scalar to vector calls --==//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_CALLWIDENINGUTILS_H
-#define LLVM_IR_CALLWIDENINGUTILS_H
-
-#include "llvm/IR/DerivedTypes.h"
-
-namespace llvm {
-
-/// A helper for converting to wider (vector) types. For scalar types, this is
-/// equivalent to calling `ToVectorTy`. For struct types, this returns a new
-/// struct where each element type has been widened to a vector type. Note: Only
-/// unpacked literal struct types are supported.
-Type *ToWideTy(Type *Ty, ElementCount EC);
-
-/// A helper for converting wide types to narrow (non-vector) types. For vector
-/// types, this is equivalent to calling .getScalarType(). For struct types,
-/// this returns a new struct where each element type has been converted to a
-/// scalar type. Note: Only unpacked literal struct types are supported.
-Type *ToNarrowTy(Type *Ty);
-
-/// Returns the types contained in `Ty`. For struct types, it returns the
-/// elements, all other types are returned directly.
-SmallVector<Type *, 2> getContainedTypes(Type *Ty);
-
-/// Returns true if `Ty` is a vector type or a struct of vector types where all
-/// vector types share the same VF.
-bool isWideTy(Type *Ty);
-
-/// Returns the vectorization factor for a widened type.
-inline ElementCount getWideTypeVF(Type *Ty) {
-  assert(isWideTy(Ty) && "expected widened type");
-  return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
-}
-
-} // namespace llvm
-
-#endif
diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
new file mode 100644
index 00000000000000..b1b922f2b5d8be
--- /dev/null
+++ b/llvm/include/llvm/IR/StructWideningUtils.h
@@ -0,0 +1,32 @@
+//===---- StructWideningUtils.h - Utils for widening scalar to vector calls
+//--==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_STRUCTWIDENINGUTILS_H
+#define LLVM_IR_STRUCTWIDENINGUTILS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DerivedTypes.h"
+
+namespace llvm {
+
+/// A helper for converting structs of scalar types to structs of vector types.
+/// Note: Only unpacked literal struct types are supported.
+Type *ToWideStructTy(StructType *StructTy, ElementCount EC);
+
+/// A helper for converting structs of vector types to structs of scalar types.
+/// Note: Only unpacked literal struct types are supported.
+Type *ToNarrowStructTy(StructType *StructTy);
+
+/// Returns true if `StructTy` is an unpacked literal struct where all elements
+/// are vectors of matching element count. This does not include empty structs.
+bool isWideStructTy(StructType *StructTy);
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
index a2e34a02e08a67..89c8dc2911c50d 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -1,4 +1,4 @@
-//===----------- VectorUtils.h -  Vector type utility functions -*- C++ -*-===//
+//===----------- VectorUtils.h - Vector type utility functions -*- C++ -*-====//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,8 +9,8 @@
 #ifndef LLVM_IR_VECTORUTILS_H
 #define LLVM_IR_VECTORUTILS_H
 
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/StructWideningUtils.h"
 
 namespace llvm {
 
@@ -27,6 +27,48 @@ inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
   return ToVectorTy(Scalar, ElementCount::getFixed(VF));
 }
 
+/// A helper for converting to wider (vector) types. For scalar types, this is
+/// equivalent to calling `ToVectorTy`. For struct types, this returns a new
+/// struct where each element type has been widened to a vector type. Note: Only
+/// unpacked literal struct types are supported.
+inline Type *ToWideTy(Type *Ty, ElementCount EC) {
+  if (StructType *StructTy = dyn_cast<StructType>(Ty))
+    return ToWideStructTy(StructTy, EC);
+  return ToVectorTy(Ty, EC);
+}
+
+/// A helper for converting wide types to narrow (non-vector) types. For vector
+/// types, this is equivalent to calling .getScalarType(). For struct types,
+/// this returns a new struct where each element type has been converted to a
+/// scalar type. Note: Only unpacked literal struct types are supported.
+inline Type *ToNarrowTy(Type *Ty) {
+  if (StructType *StructTy = dyn_cast<StructType>(Ty))
+    return ToNarrowStructTy(StructTy);
+  return Ty->getScalarType();
+}
+
+/// Returns true if `Ty` is a vector type or a struct of vector types where all
+/// vector types share the same VF.
+inline bool isWideTy(Type *Ty) {
+  if (StructType *StructTy = dyn_cast<StructType>(Ty))
+    return isWideStructTy(StructTy);
+  return Ty->isVectorTy();
+}
+
+/// Returns the types contained in `Ty`. For struct types, it returns the
+/// elements, all other types are returned directly.
+inline ArrayRef<Type *> getContainedTypes(Type *const &Ty) {
+  if (auto *StructTy = dyn_cast<StructType>(Ty))
+    return StructTy->elements();
+  return ArrayRef<Type *>{&Ty, 1};
+}
+
+/// Returns the vectorization factor for a widened type.
+inline ElementCount getWideTypeVF(Type *Ty) {
+  assert(isWideTy(Ty) && "expected widened type");
+  return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
+}
+
 } // namespace llvm
 
 #endif
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 874ee8c4795a96..42aceadde59227 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -6,7 +6,6 @@ add_llvm_component_library(LLVMCore
   AutoUpgrade.cpp
   BasicBlock.cpp
   BuiltinGCs.cpp
-  CallWideningUtils.cpp
   Comdat.cpp
   ConstantFold.cpp
   ConstantFPRange.cpp
@@ -65,6 +64,7 @@ add_llvm_component_library(LLVMCore
   PseudoProbe.cpp
   ReplaceConstant.cpp
   Statepoint.cpp
+  StructWideningUtils.cpp
   StructuralHash.cpp
   Type.cpp
   TypedPointerType.cpp
diff --git a/llvm/lib/IR/CallWideningUtils.cpp b/llvm/lib/IR/CallWideningUtils.cpp
deleted file mode 100644
index ec0bc6e3baa463..00000000000000
--- a/llvm/lib/IR/CallWideningUtils.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//===----------- VectorUtils.cpp - Vector type utility functions ----------===//
-//
-// 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/IR/CallWideningUtils.h"
-#include "llvm/ADT/SmallVectorExtras.h"
-#include "llvm/IR/VectorUtils.h"
-
-using namespace llvm;
-
-/// A helper for converting to wider (vector) types. For scalar types, this is
-/// equivalent to calling `ToVectorTy`. For struct types, this returns a new
-/// struct where each element type has been widened to a vector type. Note: Only
-/// unpacked literal struct types are supported.
-Type *llvm::ToWideTy(Type *Ty, ElementCount EC) {
-  if (EC.isScalar())
-    return Ty;
-  auto *StructTy = dyn_cast<StructType>(Ty);
-  if (!StructTy)
-    return ToVectorTy(Ty, EC);
-  assert(StructTy->isLiteral() && !StructTy->isPacked() &&
-         "expected unpacked struct literal");
-  return StructType::get(
-      Ty->getContext(),
-      map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
-        return VectorType::get(ElTy, EC);
-      }));
-}
-
-/// A helper for converting wide types to narrow (non-vector) types. For vector
-/// types, this is equivalent to calling .getScalarType(). For struct types,
-/// this returns a new struct where each element type has been converted to a
-/// scalar type. Note: Only unpacked literal struct types are supported.
-Type *llvm::ToNarrowTy(Type *Ty) {
-  auto *StructTy = dyn_cast<StructType>(Ty);
-  if (!StructTy)
-    return Ty->getScalarType();
-  assert(StructTy->isLiteral() && !StructTy->isPacked() &&
-         "expected unpacked struct literal");
-  return StructType::get(
-      Ty->getContext(),
-      map_to_vector(StructTy->elements(), [](Type *ElTy) -> Type * {
-        return ElTy->getScalarType();
-      }));
-}
-
-/// Returns the types contained in `Ty`. For struct types, it returns the
-/// elements, all other types are returned directly.
-SmallVector<Type *, 2> llvm::getContainedTypes(Type *Ty) {
-  auto *StructTy = dyn_cast<StructType>(Ty);
-  if (StructTy)
-    return to_vector<2>(StructTy->elements());
-  return {Ty};
-}
-
-/// Returns true if `Ty` is a vector type or a struct of vector types where all
-/// vector types share the same VF.
-bool llvm::isWideTy(Type *Ty) {
-  auto *StructTy = dyn_cast<StructType>(Ty);
-  if (StructTy && (!StructTy->isLiteral() || StructTy->isPacked()))
-    return false;
-  auto ContainedTys = getContainedTypes(Ty);
-  if (ContainedTys.empty() || !ContainedTys.front()->isVectorTy())
-    return false;
-  ElementCount VF = cast<VectorType>(ContainedTys.front())->getElementCount();
-  return all_of(ContainedTys, [&](Type *Ty) {
-    return Ty->isVectorTy() && cast<VectorType>(Ty)->getElementCount() == VF;
-  });
-}
diff --git a/llvm/lib/IR/StructWideningUtils.cpp b/llvm/lib/IR/StructWideningUtils.cpp
new file mode 100644
index 00000000000000..5c325c7cbdafc6
--- /dev/null
+++ b/llvm/lib/IR/StructWideningUtils.cpp
@@ -0,0 +1,57 @@
+//===-- CallWideningUtils.cpp - Utils for widening scalar to vector calls --==//
+//
+// 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/IR/StructWideningUtils.h"
+#include "llvm/ADT/SmallVectorExtras.h"
+#include "llvm/IR/VectorUtils.h"
+
+using namespace llvm;
+
+static bool isUnpackedStructLiteral(StructType *StructTy) {
+  return StructTy->isLiteral() && !StructTy->isPacked();
+}
+
+/// A helper for converting structs of scalar types to structs of vector types.
+/// Note: Only unpacked literal struct types are supported.
+Type *llvm::ToWideStructTy(StructType *StructTy, ElementCount EC) {
+  if (EC.isScalar())
+    return StructTy;
+  assert(isUnpackedStructLiteral(StructTy) &&
+         "expected unpacked struct literal");
+  return StructType::get(
+      StructTy->getContext(),
+      map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
+        return VectorType::get(ElTy, EC);
+      }));
+}
+
+/// A helper for converting structs of vector types to structs of scalar types.
+/// Note: Only unpacked literal struct types are supported.
+Type *llvm::ToNarrowStructTy(StructType *StructTy) {
+  assert(isUnpackedStructLiteral(StructTy) &&
+         "expected unpacked struct literal");
+  return StructType::get(
+      StructTy->getContext(),
+      map_to_vector(StructTy->elements(), [](Type *ElTy) -> Type * {
+        return ElTy->getScalarType();
+      }));
+}
+
+/// Returns true if `StructTy` is an unpacked literal struct where all elements
+/// are vectors of matching element count. This does not include empty structs.
+bool llvm::isWideStructTy(StructType *StructTy) {
+  if (!isUnpackedStructLiteral(StructTy))
+    return false;
+  auto ElemTys = StructTy->elements();
+  if (ElemTys.empty() || !ElemTys.front()->isVectorTy())
+    return false;
+  ElementCount VF = cast<VectorType>(ElemTys.front())->getElementCount();
+  return all_of(ElemTys, [&](Type *Ty) {
+    return Ty->isVectorTy() && cast<VectorType>(Ty)->getElementCount() == VF;
+  });
+}
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index 19c922c8bf035b..b7559e2f4108a7 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -10,8 +10,8 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/IR/CallWideningUtils.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/VectorUtils.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <limits>
diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt
index c4cc1bd78403a8..efbe710987a489 100644
--- a/llvm/unittests/IR/CMakeLists.txt
+++ b/llvm/unittests/IR/CMakeLists.txt
@@ -15,7 +15,6 @@ add_llvm_unittest(IRTests
   AttributesTest.cpp
   BasicBlockTest.cpp
   BasicBlockDbgInfoTest.cpp
-  CallWideningUtilsTest.cpp
   CFGBuilder.cpp
   ConstantFPRangeTest.cpp
   ConstantRangeTest.cpp
@@ -53,6 +52,7 @@ add_llvm_unittest(IRTests
   ValueTest.cpp
   VectorBuilderTest.cpp
   VectorTypesTest.cpp
+  VectorUtilsTest.cpp
   VerifierTest.cpp
   VFABIDemanglerTest.cpp
   VPIntrinsicTest.cpp
diff --git a/llvm/unittests/IR/CallWideningUtilsTest.cpp b/llvm/unittests/IR/VectorUtilsTest.cpp
similarity index 86%
rename from llvm/unittests/IR/CallWideningUtilsTest.cpp
rename to llvm/unittests/IR/VectorUtilsTest.cpp
index 939806212eee6a..b70cd2f511df48 100644
--- a/llvm/unittests/IR/CallWideningUtilsTest.cpp
+++ b/llvm/unittests/IR/VectorUtilsTest.cpp
@@ -1,4 +1,4 @@
-//===------- CallWideningUtilsTest.cpp - Call widening utils tests --------===//
+//===------- VectorUtilsTest.cpp - Vector utils 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,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/CallWideningUtils.h"
+#include "llvm/IR/VectorUtils.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
 #include "gtest/gtest.h"
@@ -15,9 +15,9 @@ using namespace llvm;
 
 namespace {
 
-class CallWideningUtilsTest : public ::testing::Test {};
+class VectorUtilsTest : public ::testing::Test {};
 
-TEST(CallWideningUtilsTest, TestToWideTy) {
+TEST(VectorUtilsTest, TestToWideTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -62,7 +62,7 @@ TEST(CallWideningUtilsTest, TestToWideTy) {
   }
 }
 
-TEST(CallWideningUtilsTest, TestToNarrowTy) {
+TEST(VectorUtilsTest, TestToNarrowTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -80,7 +80,7 @@ TEST(CallWideningUtilsTest, TestToNarrowTy) {
   }
 }
 
-TEST(CallWideningUtilsTest, TestGetContainedTypes) {
+TEST(VectorUtilsTest, TestGetContainedTypes) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -89,15 +89,15 @@ TEST(CallWideningUtilsTest, TestGetContainedTypes) {
   Type *MixedStructTy = StructType::get(FTy, ITy);
   Type *VoidTy = Type::getVoidTy(C);
 
-  EXPECT_EQ(getContainedTypes(ITy), SmallVector<Type *>({ITy}));
-  EXPECT_EQ(getContainedTypes(FTy), SmallVector<Type *>({FTy}));
-  EXPECT_EQ(getContainedTypes(VoidTy), SmallVector<Type *>({VoidTy}));
+  EXPECT_EQ(getContainedTypes(ITy), ArrayRef<Type *>({ITy}));
+  EXPECT_EQ(getContainedTypes(FTy), ArrayRef<Type *>({FTy}));
+  EXPECT_EQ(getContainedTypes(VoidTy), ArrayRef<Type *>({VoidTy}));
   EXPECT_EQ(getContainedTypes(HomogeneousStructTy),
-            SmallVector<Type *>({FTy, FTy, FTy}));
-  EXPECT_EQ(getContainedTypes(MixedStructTy), SmallVector<Type *>({FTy, ITy}));
+            ArrayRef<Type *>({FTy, FTy, FTy}));
+  EXPECT_EQ(getContainedTypes(MixedStructTy), ArrayRef<Type *>({FTy, ITy}));
 }
 
-TEST(CallWideningUtilsTest, TestIsWideTy) {
+TEST(VectorUtilsTest, TestIsWideTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -130,7 +130,7 @@ TEST(CallWideningUtilsTest, TestIsWideTy) {
   EXPECT_FALSE(isWideTy(PackedWideStruct));
 }
 
-TEST(CallWideningUtilsTest, TestGetWideTypeVF) {
+TEST(VectorUtilsTest, TestGetWideTypeVF) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);

>From 8199c2366ae344d6dcec56c962106b7d4539b72a Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 12 Dec 2024 17:20:54 +0000
Subject: [PATCH 03/14] Rm include

---
 llvm/include/llvm/IR/StructWideningUtils.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
index b1b922f2b5d8be..a5b1238244bfd8 100644
--- a/llvm/include/llvm/IR/StructWideningUtils.h
+++ b/llvm/include/llvm/IR/StructWideningUtils.h
@@ -10,7 +10,6 @@
 #ifndef LLVM_IR_STRUCTWIDENINGUTILS_H
 #define LLVM_IR_STRUCTWIDENINGUTILS_H
 
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/DerivedTypes.h"
 
 namespace llvm {

>From 7b2339741deb3765615b01ebf64ebe3d2e1ec475 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 12 Dec 2024 17:24:49 +0000
Subject: [PATCH 04/14] Update comment

---
 llvm/include/llvm/IR/StructWideningUtils.h | 3 +--
 llvm/lib/IR/StructWideningUtils.cpp        | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
index a5b1238244bfd8..3044f3b4658d01 100644
--- a/llvm/include/llvm/IR/StructWideningUtils.h
+++ b/llvm/include/llvm/IR/StructWideningUtils.h
@@ -1,5 +1,4 @@
-//===---- StructWideningUtils.h - Utils for widening scalar to vector calls
-//--==//
+//===--- StructWideningUtils.h - Utils for widening/narrowing struct types ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/lib/IR/StructWideningUtils.cpp b/llvm/lib/IR/StructWideningUtils.cpp
index 5c325c7cbdafc6..b97b1e0a3da0ed 100644
--- a/llvm/lib/IR/StructWideningUtils.cpp
+++ b/llvm/lib/IR/StructWideningUtils.cpp
@@ -1,4 +1,4 @@
-//===-- CallWideningUtils.cpp - Utils for widening scalar to vector calls --==//
+//===- StructWideningUtils.cpp - Utils for widening/narrowing struct types ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 0bb3c80a1355c1da0b0051b5547dc8501fad08b9 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 13 Dec 2024 12:31:01 +0000
Subject: [PATCH 05/14] Fixups

---
 llvm/include/llvm/IR/StructWideningUtils.h |  8 +++-
 llvm/include/llvm/IR/VectorUtils.h         |  8 ++--
 llvm/lib/IR/StructWideningUtils.cpp        | 10 ++--
 llvm/lib/IR/VFABIDemangler.cpp             |  5 ++
 llvm/unittests/IR/VFABIDemanglerTest.cpp   | 56 ++++++++++++++--------
 5 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
index 3044f3b4658d01..3067ab88435ae0 100644
--- a/llvm/include/llvm/IR/StructWideningUtils.h
+++ b/llvm/include/llvm/IR/StructWideningUtils.h
@@ -13,13 +13,17 @@
 
 namespace llvm {
 
+inline bool isUnpackedStructLiteral(StructType *StructTy) {
+  return StructTy->isLiteral() && !StructTy->isPacked();
+}
+
 /// A helper for converting structs of scalar types to structs of vector types.
 /// Note: Only unpacked literal struct types are supported.
-Type *ToWideStructTy(StructType *StructTy, ElementCount EC);
+Type *toWideStructTy(StructType *StructTy, ElementCount EC);
 
 /// A helper for converting structs of vector types to structs of scalar types.
 /// Note: Only unpacked literal struct types are supported.
-Type *ToNarrowStructTy(StructType *StructTy);
+Type *toNarrowStructTy(StructType *StructTy);
 
 /// Returns true if `StructTy` is an unpacked literal struct where all elements
 /// are vectors of matching element count. This does not include empty structs.
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
index 89c8dc2911c50d..4ddf721e3a829c 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -33,7 +33,7 @@ inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
 /// unpacked literal struct types are supported.
 inline Type *ToWideTy(Type *Ty, ElementCount EC) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
-    return ToWideStructTy(StructTy, EC);
+    return toWideStructTy(StructTy, EC);
   return ToVectorTy(Ty, EC);
 }
 
@@ -43,7 +43,7 @@ inline Type *ToWideTy(Type *Ty, ElementCount EC) {
 /// scalar type. Note: Only unpacked literal struct types are supported.
 inline Type *ToNarrowTy(Type *Ty) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
-    return ToNarrowStructTy(StructTy);
+    return toNarrowStructTy(StructTy);
   return Ty->getScalarType();
 }
 
@@ -60,10 +60,10 @@ inline bool isWideTy(Type *Ty) {
 inline ArrayRef<Type *> getContainedTypes(Type *const &Ty) {
   if (auto *StructTy = dyn_cast<StructType>(Ty))
     return StructTy->elements();
-  return ArrayRef<Type *>{&Ty, 1};
+  return ArrayRef<Type *>(&Ty, 1);
 }
 
-/// Returns the vectorization factor for a widened type.
+/// Returns the number of vector elements for a widened type.
 inline ElementCount getWideTypeVF(Type *Ty) {
   assert(isWideTy(Ty) && "expected widened type");
   return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
diff --git a/llvm/lib/IR/StructWideningUtils.cpp b/llvm/lib/IR/StructWideningUtils.cpp
index b97b1e0a3da0ed..72f442a9bf04c7 100644
--- a/llvm/lib/IR/StructWideningUtils.cpp
+++ b/llvm/lib/IR/StructWideningUtils.cpp
@@ -12,17 +12,15 @@
 
 using namespace llvm;
 
-static bool isUnpackedStructLiteral(StructType *StructTy) {
-  return StructTy->isLiteral() && !StructTy->isPacked();
-}
-
 /// A helper for converting structs of scalar types to structs of vector types.
 /// Note: Only unpacked literal struct types are supported.
-Type *llvm::ToWideStructTy(StructType *StructTy, ElementCount EC) {
+Type *llvm::toWideStructTy(StructType *StructTy, ElementCount EC) {
   if (EC.isScalar())
     return StructTy;
   assert(isUnpackedStructLiteral(StructTy) &&
          "expected unpacked struct literal");
+  assert(all_of(StructTy->elements(), VectorType::isValidElementType) &&
+         "expected all element types to be valid vector element types");
   return StructType::get(
       StructTy->getContext(),
       map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
@@ -32,7 +30,7 @@ Type *llvm::ToWideStructTy(StructType *StructTy, ElementCount EC) {
 
 /// A helper for converting structs of vector types to structs of scalar types.
 /// Note: Only unpacked literal struct types are supported.
-Type *llvm::ToNarrowStructTy(StructType *StructTy) {
+Type *llvm::toNarrowStructTy(StructType *StructTy) {
   assert(isUnpackedStructLiteral(StructTy) &&
          "expected unpacked struct literal");
   return StructType::get(
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index b7559e2f4108a7..e7e080038e74c2 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -347,6 +347,11 @@ getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA,
   // Also check the return type if not void.
   Type *RetTy = Signature->getReturnType();
   if (!RetTy->isVoidTy()) {
+    // If the return type is a struct, only allow unpacked struct literals.
+    StructType *StructTy = dyn_cast<StructType>(RetTy);
+    if (StructTy && !isUnpackedStructLiteral(StructTy))
+      return std::nullopt;
+
     for (Type *RetTy : getContainedTypes(RetTy)) {
       std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA, RetTy);
       // If we have an unknown scalar element type we can't find a reasonable
diff --git a/llvm/unittests/IR/VFABIDemanglerTest.cpp b/llvm/unittests/IR/VFABIDemanglerTest.cpp
index 896cd48ad11d6d..0e62082e07c7d9 100644
--- a/llvm/unittests/IR/VFABIDemanglerTest.cpp
+++ b/llvm/unittests/IR/VFABIDemanglerTest.cpp
@@ -40,7 +40,9 @@ class VFABIParserTest : public ::testing::Test {
   VFInfo Info;
   /// Reset the data needed for the test.
   void reset(const StringRef ScalarFTyStr) {
-    M = parseAssemblyString("declare void @dummy()", Err, Ctx);
+    M = parseAssemblyString("%dummy_named_struct = type { double, double }\n"
+                            "declare void @dummy()",
+                            Err, Ctx);
     EXPECT_NE(M.get(), nullptr)
         << "Loading an invalid module.\n " << Err.getMessage() << "\n";
     Type *Ty = parseType(ScalarFTyStr, Err, *(M));
@@ -758,21 +760,20 @@ TEST_F(VFABIParserTest, ParseWideStructReturnTypeSVE) {
       invokeParser("_ZGVsMxv_foo(vector_foo)", "{double, double}(float)"));
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_TRUE(isMasked());
+  ElementCount NXV2 = ElementCount::getScalable(2);
   FunctionType *FTy = FunctionType::get(
-      StructType::get(
-          VectorType::get(Type::getDoubleTy(Ctx), ElementCount::getScalable(2)),
-          VectorType::get(Type::getDoubleTy(Ctx),
-                          ElementCount::getScalable(2))),
+      StructType::get(VectorType::get(Type::getDoubleTy(Ctx), NXV2),
+                      VectorType::get(Type::getDoubleTy(Ctx), NXV2)),
       {
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
-          VectorType::get(Type::getInt1Ty(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getFloatTy(Ctx), NXV2),
+          VectorType::get(Type::getInt1Ty(Ctx), NXV2),
       },
       false);
   EXPECT_EQ(getFunctionType(), FTy);
   EXPECT_EQ(Parameters.size(), 2U);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(VF, ElementCount::getScalable(2));
+  EXPECT_EQ(VF, NXV2);
   EXPECT_EQ(ScalarName, "foo");
   EXPECT_EQ(VectorName, "vector_foo");
 }
@@ -781,45 +782,60 @@ TEST_F(VFABIParserTest, ParseWideStructMixedReturnTypeSVE) {
   EXPECT_TRUE(invokeParser("_ZGVsMxv_foo(vector_foo)", "{float, i64}(float)"));
   EXPECT_EQ(ISA, VFISAKind::SVE);
   EXPECT_TRUE(isMasked());
+  ElementCount NXV2 = ElementCount::getScalable(2);
   FunctionType *FTy = FunctionType::get(
-      StructType::get(
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
-          VectorType::get(Type::getInt64Ty(Ctx), ElementCount::getScalable(2))),
+      StructType::get(VectorType::get(Type::getFloatTy(Ctx), NXV2),
+                      VectorType::get(Type::getInt64Ty(Ctx), NXV2)),
       {
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getScalable(2)),
-          VectorType::get(Type::getInt1Ty(Ctx), ElementCount::getScalable(2)),
+          VectorType::get(Type::getFloatTy(Ctx), NXV2),
+          VectorType::get(Type::getInt1Ty(Ctx), NXV2),
       },
       false);
   EXPECT_EQ(getFunctionType(), FTy);
   EXPECT_EQ(Parameters.size(), 2U);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
-  EXPECT_EQ(VF, ElementCount::getScalable(2));
+  EXPECT_EQ(VF, NXV2);
   EXPECT_EQ(ScalarName, "foo");
   EXPECT_EQ(VectorName, "vector_foo");
 }
 
 TEST_F(VFABIParserTest, ParseWideStructReturnTypeNEON) {
   EXPECT_TRUE(
-      invokeParser("_ZGVnN2v_foo(vector_foo)", "{float, float}(float)"));
+      invokeParser("_ZGVnN4v_foo(vector_foo)", "{float, float}(float)"));
   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
   EXPECT_FALSE(isMasked());
+  ElementCount V4 = ElementCount::getFixed(4);
   FunctionType *FTy = FunctionType::get(
-      StructType::get(
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2)),
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2))),
+      StructType::get(VectorType::get(Type::getFloatTy(Ctx), V4),
+                      VectorType::get(Type::getFloatTy(Ctx), V4)),
       {
-          VectorType::get(Type::getFloatTy(Ctx), ElementCount::getFixed(2)),
+          VectorType::get(Type::getFloatTy(Ctx), V4),
       },
       false);
   EXPECT_EQ(getFunctionType(), FTy);
   EXPECT_EQ(Parameters.size(), 1U);
   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
-  EXPECT_EQ(VF, ElementCount::getFixed(2));
+  EXPECT_EQ(VF, V4);
   EXPECT_EQ(ScalarName, "foo");
   EXPECT_EQ(VectorName, "vector_foo");
 }
 
+TEST_F(VFABIParserTest, ParseUnsupportedStructReturnTypesSVE) {
+  // Struct with array element type.
+  EXPECT_FALSE(
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "{double, [4 x f32]}(float)"));
+  // Nested struct type.
+  EXPECT_FALSE(
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "{{float, float}}(float)"));
+  // Packed struct type.
+  EXPECT_FALSE(
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "<{double, float}>(float)"));
+  // Named struct type.
+  EXPECT_FALSE(
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "%dummy_named_struct(float)"));
+}
+
 // Make sure we reject unsupported parameter types.
 TEST_F(VFABIParserTest, ParseUnsupportedElementTypeSVE) {
   EXPECT_FALSE(invokeParser("_ZGVsMxv_foo(vector_foo)", "void(i128)"));

>From 54c624490e9aff94fd3f386fe131ebfc83fb4ea0 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 13 Dec 2024 14:47:11 +0000
Subject: [PATCH 06/14] Fix typo

---
 llvm/unittests/IR/VFABIDemanglerTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/unittests/IR/VFABIDemanglerTest.cpp b/llvm/unittests/IR/VFABIDemanglerTest.cpp
index 0e62082e07c7d9..e30e0f865f7199 100644
--- a/llvm/unittests/IR/VFABIDemanglerTest.cpp
+++ b/llvm/unittests/IR/VFABIDemanglerTest.cpp
@@ -824,7 +824,7 @@ TEST_F(VFABIParserTest, ParseWideStructReturnTypeNEON) {
 TEST_F(VFABIParserTest, ParseUnsupportedStructReturnTypesSVE) {
   // Struct with array element type.
   EXPECT_FALSE(
-      invokeParser("_ZGVsMxv_foo(vector_foo)", "{double, [4 x f32]}(float)"));
+      invokeParser("_ZGVsMxv_foo(vector_foo)", "{double, [4 x float]}(float)"));
   // Nested struct type.
   EXPECT_FALSE(
       invokeParser("_ZGVsMxv_foo(vector_foo)", "{{float, float}}(float)"));

>From 91085c669b2072cd0b05d38062ece968ac8d5fa9 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 13 Dec 2024 16:58:46 +0000
Subject: [PATCH 07/14] Fixups

---
 llvm/include/llvm/IR/StructWideningUtils.h |  8 ++---
 llvm/include/llvm/IR/VectorUtils.h         | 28 +++++++--------
 llvm/lib/IR/StructWideningUtils.cpp        |  8 ++---
 llvm/lib/IR/VFABIDemangler.cpp             |  2 +-
 llvm/unittests/IR/VectorUtilsTest.cpp      | 42 +++++++++++-----------
 5 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
index 3067ab88435ae0..8c3cb9f5192cdf 100644
--- a/llvm/include/llvm/IR/StructWideningUtils.h
+++ b/llvm/include/llvm/IR/StructWideningUtils.h
@@ -1,4 +1,4 @@
-//===--- StructWideningUtils.h - Utils for widening/narrowing struct types ===//
+//===--- StructWideningUtils.h - Utils for vectorizing struct types -------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -19,15 +19,15 @@ inline bool isUnpackedStructLiteral(StructType *StructTy) {
 
 /// A helper for converting structs of scalar types to structs of vector types.
 /// Note: Only unpacked literal struct types are supported.
-Type *toWideStructTy(StructType *StructTy, ElementCount EC);
+Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC);
 
 /// A helper for converting structs of vector types to structs of scalar types.
 /// Note: Only unpacked literal struct types are supported.
-Type *toNarrowStructTy(StructType *StructTy);
+Type *toScalarizedStructTy(StructType *StructTy);
 
 /// Returns true if `StructTy` is an unpacked literal struct where all elements
 /// are vectors of matching element count. This does not include empty structs.
-bool isWideStructTy(StructType *StructTy);
+bool isVectorizedStructTy(StructType *StructTy);
 
 } // namespace llvm
 
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
index 4ddf721e3a829c..49409f7ea26ce1 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -27,31 +27,31 @@ inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
   return ToVectorTy(Scalar, ElementCount::getFixed(VF));
 }
 
-/// A helper for converting to wider (vector) types. For scalar types, this is
+/// A helper for converting to vectorized types. For scalar types, this is
 /// equivalent to calling `ToVectorTy`. For struct types, this returns a new
 /// struct where each element type has been widened to a vector type. Note: Only
 /// unpacked literal struct types are supported.
-inline Type *ToWideTy(Type *Ty, ElementCount EC) {
+inline Type *toVectorizedTy(Type *Ty, ElementCount EC) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
-    return toWideStructTy(StructTy, EC);
+    return toVectorizedStructTy(StructTy, EC);
   return ToVectorTy(Ty, EC);
 }
 
-/// A helper for converting wide types to narrow (non-vector) types. For vector
-/// types, this is equivalent to calling .getScalarType(). For struct types,
-/// this returns a new struct where each element type has been converted to a
-/// scalar type. Note: Only unpacked literal struct types are supported.
-inline Type *ToNarrowTy(Type *Ty) {
+/// A helper for converting vectorized types to scalarized (non-vector) types.
+/// For vector types, this is equivalent to calling .getScalarType(). For struct
+/// types, this returns a new struct where each element type has been converted
+/// to a scalar type. Note: Only unpacked literal struct types are supported.
+inline Type *toScalarizedTy(Type *Ty) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
-    return toNarrowStructTy(StructTy);
+    return toScalarizedStructTy(StructTy);
   return Ty->getScalarType();
 }
 
 /// Returns true if `Ty` is a vector type or a struct of vector types where all
 /// vector types share the same VF.
-inline bool isWideTy(Type *Ty) {
+inline bool isVectorizedTy(Type *Ty) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
-    return isWideStructTy(StructTy);
+    return isVectorizedStructTy(StructTy);
   return Ty->isVectorTy();
 }
 
@@ -63,9 +63,9 @@ inline ArrayRef<Type *> getContainedTypes(Type *const &Ty) {
   return ArrayRef<Type *>(&Ty, 1);
 }
 
-/// Returns the number of vector elements for a widened type.
-inline ElementCount getWideTypeVF(Type *Ty) {
-  assert(isWideTy(Ty) && "expected widened type");
+/// Returns the number of vector elements for a vectorized type.
+inline ElementCount getVectorizedTypeVF(Type *Ty) {
+  assert(isVectorizedTy(Ty) && "expected widened type");
   return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
 }
 
diff --git a/llvm/lib/IR/StructWideningUtils.cpp b/llvm/lib/IR/StructWideningUtils.cpp
index 72f442a9bf04c7..372db086fe7612 100644
--- a/llvm/lib/IR/StructWideningUtils.cpp
+++ b/llvm/lib/IR/StructWideningUtils.cpp
@@ -1,4 +1,4 @@
-//===- StructWideningUtils.cpp - Utils for widening/narrowing struct types ===//
+//===- StructWideningUtils.cpp - Utils for vectorizing struct types------- ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -14,7 +14,7 @@ using namespace llvm;
 
 /// A helper for converting structs of scalar types to structs of vector types.
 /// Note: Only unpacked literal struct types are supported.
-Type *llvm::toWideStructTy(StructType *StructTy, ElementCount EC) {
+Type *llvm::toVectorizedStructTy(StructType *StructTy, ElementCount EC) {
   if (EC.isScalar())
     return StructTy;
   assert(isUnpackedStructLiteral(StructTy) &&
@@ -30,7 +30,7 @@ Type *llvm::toWideStructTy(StructType *StructTy, ElementCount EC) {
 
 /// A helper for converting structs of vector types to structs of scalar types.
 /// Note: Only unpacked literal struct types are supported.
-Type *llvm::toNarrowStructTy(StructType *StructTy) {
+Type *llvm::toScalarizedStructTy(StructType *StructTy) {
   assert(isUnpackedStructLiteral(StructTy) &&
          "expected unpacked struct literal");
   return StructType::get(
@@ -42,7 +42,7 @@ Type *llvm::toNarrowStructTy(StructType *StructTy) {
 
 /// Returns true if `StructTy` is an unpacked literal struct where all elements
 /// are vectors of matching element count. This does not include empty structs.
-bool llvm::isWideStructTy(StructType *StructTy) {
+bool llvm::isVectorizedStructTy(StructType *StructTy) {
   if (!isUnpackedStructLiteral(StructTy))
     return false;
   auto ElemTys = StructTy->elements();
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index e7e080038e74c2..a61eae6d478c3a 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -575,7 +575,7 @@ FunctionType *VFABI::createFunctionType(const VFInfo &Info,
 
   auto *RetTy = ScalarFTy->getReturnType();
   if (!RetTy->isVoidTy())
-    RetTy = ToWideTy(RetTy, VF);
+    RetTy = toVectorizedTy(RetTy, VF);
   return FunctionType::get(RetTy, VecTypes, false);
 }
 
diff --git a/llvm/unittests/IR/VectorUtilsTest.cpp b/llvm/unittests/IR/VectorUtilsTest.cpp
index b70cd2f511df48..aac3bf1817f92c 100644
--- a/llvm/unittests/IR/VectorUtilsTest.cpp
+++ b/llvm/unittests/IR/VectorUtilsTest.cpp
@@ -17,7 +17,7 @@ namespace {
 
 class VectorUtilsTest : public ::testing::Test {};
 
-TEST(VectorUtilsTest, TestToWideTy) {
+TEST(VectorUtilsTest, TestToVectorizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -28,15 +28,15 @@ TEST(VectorUtilsTest, TestToWideTy) {
 
   for (ElementCount VF :
        {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
-    Type *IntVec = ToWideTy(ITy, VF);
+    Type *IntVec = toVectorizedTy(ITy, VF);
     EXPECT_TRUE(isa<VectorType>(IntVec));
     EXPECT_EQ(IntVec, VectorType::get(ITy, VF));
 
-    Type *FloatVec = ToWideTy(FTy, VF);
+    Type *FloatVec = toVectorizedTy(FTy, VF);
     EXPECT_TRUE(isa<VectorType>(FloatVec));
     EXPECT_EQ(FloatVec, VectorType::get(FTy, VF));
 
-    Type *WideHomogeneousStructTy = ToWideTy(HomogeneousStructTy, VF);
+    Type *WideHomogeneousStructTy = toVectorizedTy(HomogeneousStructTy, VF);
     EXPECT_TRUE(isa<StructType>(WideHomogeneousStructTy));
     EXPECT_TRUE(
         cast<StructType>(WideHomogeneousStructTy)->containsHomogeneousTypes());
@@ -45,7 +45,7 @@ TEST(VectorUtilsTest, TestToWideTy) {
     EXPECT_TRUE(cast<StructType>(WideHomogeneousStructTy)->getElementType(0) ==
                 VectorType::get(FTy, VF));
 
-    Type *WideMixedStructTy = ToWideTy(MixedStructTy, VF);
+    Type *WideMixedStructTy = toVectorizedTy(MixedStructTy, VF);
     EXPECT_TRUE(isa<StructType>(WideMixedStructTy));
     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getNumElements() == 2);
     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(0) ==
@@ -53,16 +53,16 @@ TEST(VectorUtilsTest, TestToWideTy) {
     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(1) ==
                 VectorType::get(ITy, VF));
 
-    EXPECT_EQ(ToWideTy(VoidTy, VF), VoidTy);
+    EXPECT_EQ(toVectorizedTy(VoidTy, VF), VoidTy);
   }
 
   ElementCount ScalarVF = ElementCount::getFixed(1);
   for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
-    EXPECT_EQ(ToWideTy(Ty, ScalarVF), Ty);
+    EXPECT_EQ(toVectorizedTy(Ty, ScalarVF), Ty);
   }
 }
 
-TEST(VectorUtilsTest, TestToNarrowTy) {
+TEST(VectorUtilsTest, TestToScalarizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -74,8 +74,8 @@ TEST(VectorUtilsTest, TestToNarrowTy) {
   for (ElementCount VF : {ElementCount::getFixed(1), ElementCount::getFixed(4),
                           ElementCount::getScalable(2)}) {
     for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
-      // ToNarrowTy should be the inverse of ToWideTy.
-      EXPECT_EQ(ToNarrowTy(ToWideTy(Ty, VF)), Ty);
+      // toScalarizedTy should be the inverse of toVectorizedTy.
+      EXPECT_EQ(toScalarizedTy(toVectorizedTy(Ty, VF)), Ty);
     };
   }
 }
@@ -97,7 +97,7 @@ TEST(VectorUtilsTest, TestGetContainedTypes) {
   EXPECT_EQ(getContainedTypes(MixedStructTy), ArrayRef<Type *>({FTy, ITy}));
 }
 
-TEST(VectorUtilsTest, TestIsWideTy) {
+TEST(VectorUtilsTest, TestIsVectorizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -105,32 +105,32 @@ TEST(VectorUtilsTest, TestIsWideTy) {
   Type *NarrowStruct = StructType::get(FTy, ITy);
   Type *VoidTy = Type::getVoidTy(C);
 
-  EXPECT_FALSE(isWideTy(ITy));
-  EXPECT_FALSE(isWideTy(NarrowStruct));
-  EXPECT_FALSE(isWideTy(VoidTy));
+  EXPECT_FALSE(isVectorizedTy(ITy));
+  EXPECT_FALSE(isVectorizedTy(NarrowStruct));
+  EXPECT_FALSE(isVectorizedTy(VoidTy));
 
   ElementCount VF = ElementCount::getFixed(4);
-  EXPECT_TRUE(isWideTy(ToWideTy(ITy, VF)));
-  EXPECT_TRUE(isWideTy(ToWideTy(NarrowStruct, VF)));
+  EXPECT_TRUE(isVectorizedTy(toVectorizedTy(ITy, VF)));
+  EXPECT_TRUE(isVectorizedTy(toVectorizedTy(NarrowStruct, VF)));
 
   Type *MixedVFStruct =
       StructType::get(VectorType::get(ITy, ElementCount::getFixed(2)),
                       VectorType::get(ITy, ElementCount::getFixed(4)));
-  EXPECT_FALSE(isWideTy(MixedVFStruct));
+  EXPECT_FALSE(isVectorizedTy(MixedVFStruct));
 
   // Currently only literals types are considered wide.
   Type *NamedWideStruct = StructType::create("Named", VectorType::get(ITy, VF),
                                              VectorType::get(ITy, VF));
-  EXPECT_FALSE(isWideTy(NamedWideStruct));
+  EXPECT_FALSE(isVectorizedTy(NamedWideStruct));
 
   // Currently only unpacked types are considered wide.
   Type *PackedWideStruct = StructType::get(
       C, ArrayRef<Type *>{VectorType::get(ITy, VF), VectorType::get(ITy, VF)},
       /*isPacked=*/true);
-  EXPECT_FALSE(isWideTy(PackedWideStruct));
+  EXPECT_FALSE(isVectorizedTy(PackedWideStruct));
 }
 
-TEST(VectorUtilsTest, TestGetWideTypeVF) {
+TEST(VectorUtilsTest, TestGetVectorizedTypeVF) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -141,7 +141,7 @@ TEST(VectorUtilsTest, TestGetWideTypeVF) {
   for (ElementCount VF :
        {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
     for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy}) {
-      EXPECT_EQ(getWideTypeVF(ToWideTy(Ty, VF)), VF);
+      EXPECT_EQ(getVectorizedTypeVF(toVectorizedTy(Ty, VF)), VF);
     };
   }
 }

>From 899f19a6f33febcbad98251d38970d3ee5bb6b3d Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 10:29:46 +0000
Subject: [PATCH 08/14] Move helpers

---
 llvm/include/llvm/IR/StructWideningUtils.h    | 34 -------------------
 llvm/include/llvm/IR/VectorUtils.h            | 17 +++++++++-
 llvm/lib/IR/CMakeLists.txt                    |  2 +-
 ...tructWideningUtils.cpp => VectorUtils.cpp} |  5 ++-
 4 files changed, 19 insertions(+), 39 deletions(-)
 delete mode 100644 llvm/include/llvm/IR/StructWideningUtils.h
 rename llvm/lib/IR/{StructWideningUtils.cpp => VectorUtils.cpp} (94%)

diff --git a/llvm/include/llvm/IR/StructWideningUtils.h b/llvm/include/llvm/IR/StructWideningUtils.h
deleted file mode 100644
index 8c3cb9f5192cdf..00000000000000
--- a/llvm/include/llvm/IR/StructWideningUtils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===--- StructWideningUtils.h - Utils for vectorizing struct types -------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_STRUCTWIDENINGUTILS_H
-#define LLVM_IR_STRUCTWIDENINGUTILS_H
-
-#include "llvm/IR/DerivedTypes.h"
-
-namespace llvm {
-
-inline bool isUnpackedStructLiteral(StructType *StructTy) {
-  return StructTy->isLiteral() && !StructTy->isPacked();
-}
-
-/// A helper for converting structs of scalar types to structs of vector types.
-/// Note: Only unpacked literal struct types are supported.
-Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC);
-
-/// A helper for converting structs of vector types to structs of scalar types.
-/// Note: Only unpacked literal struct types are supported.
-Type *toScalarizedStructTy(StructType *StructTy);
-
-/// Returns true if `StructTy` is an unpacked literal struct where all elements
-/// are vectors of matching element count. This does not include empty structs.
-bool isVectorizedStructTy(StructType *StructTy);
-
-} // namespace llvm
-
-#endif
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
index 49409f7ea26ce1..3396bba64cc536 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -10,7 +10,6 @@
 #define LLVM_IR_VECTORUTILS_H
 
 #include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/StructWideningUtils.h"
 
 namespace llvm {
 
@@ -27,6 +26,18 @@ inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
   return ToVectorTy(Scalar, ElementCount::getFixed(VF));
 }
 
+/// A helper for converting structs of scalar types to structs of vector types.
+/// Note: Only unpacked literal struct types are supported.
+Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC);
+
+/// A helper for converting structs of vector types to structs of scalar types.
+/// Note: Only unpacked literal struct types are supported.
+Type *toScalarizedStructTy(StructType *StructTy);
+
+/// Returns true if `StructTy` is an unpacked literal struct where all elements
+/// are vectors of matching element count. This does not include empty structs.
+bool isVectorizedStructTy(StructType *StructTy);
+
 /// A helper for converting to vectorized types. For scalar types, this is
 /// equivalent to calling `ToVectorTy`. For struct types, this returns a new
 /// struct where each element type has been widened to a vector type. Note: Only
@@ -69,6 +80,10 @@ inline ElementCount getVectorizedTypeVF(Type *Ty) {
   return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
 }
 
+inline bool isUnpackedStructLiteral(StructType *StructTy) {
+  return StructTy->isLiteral() && !StructTy->isPacked();
+}
+
 } // namespace llvm
 
 #endif
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 42aceadde59227..7eaf35e10ebc67 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -64,7 +64,6 @@ add_llvm_component_library(LLVMCore
   PseudoProbe.cpp
   ReplaceConstant.cpp
   Statepoint.cpp
-  StructWideningUtils.cpp
   StructuralHash.cpp
   Type.cpp
   TypedPointerType.cpp
@@ -74,6 +73,7 @@ add_llvm_component_library(LLVMCore
   Value.cpp
   ValueSymbolTable.cpp
   VectorBuilder.cpp
+  VectorUtils.cpp
   Verifier.cpp
   VFABIDemangler.cpp
   RuntimeLibcalls.cpp
diff --git a/llvm/lib/IR/StructWideningUtils.cpp b/llvm/lib/IR/VectorUtils.cpp
similarity index 94%
rename from llvm/lib/IR/StructWideningUtils.cpp
rename to llvm/lib/IR/VectorUtils.cpp
index 372db086fe7612..7a7ef2796a2a07 100644
--- a/llvm/lib/IR/StructWideningUtils.cpp
+++ b/llvm/lib/IR/VectorUtils.cpp
@@ -1,4 +1,4 @@
-//===- StructWideningUtils.cpp - Utils for vectorizing struct types------- ===//
+//===- VectorUtils.cpp - Vector type utility functions --------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,9 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/StructWideningUtils.h"
-#include "llvm/ADT/SmallVectorExtras.h"
 #include "llvm/IR/VectorUtils.h"
+#include "llvm/ADT/SmallVectorExtras.h"
 
 using namespace llvm;
 

>From ee19f4e20ac123c8442959974dbf5e9923a5d569 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 14:10:39 +0000
Subject: [PATCH 09/14] Fixups

---
 llvm/include/llvm/IR/VectorUtils.h | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorUtils.h
index 3396bba64cc536..47ff1bbc98ebc5 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorUtils.h
@@ -27,7 +27,9 @@ inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
 }
 
 /// A helper for converting structs of scalar types to structs of vector types.
-/// Note: Only unpacked literal struct types are supported.
+/// Note:
+///   - If \p EC is scalar, \p StructTy is returned unchanged
+///   - Only unpacked literal struct types are supported
 Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC);
 
 /// A helper for converting structs of vector types to structs of scalar types.
@@ -40,8 +42,11 @@ bool isVectorizedStructTy(StructType *StructTy);
 
 /// A helper for converting to vectorized types. For scalar types, this is
 /// equivalent to calling `ToVectorTy`. For struct types, this returns a new
-/// struct where each element type has been widened to a vector type. Note: Only
-/// unpacked literal struct types are supported.
+/// struct where each element type has been widened to a vector type.
+/// Note:
+///   - If the he incoming type is void, we return void
+///   - If \p EC is scalar, \p Ty is returned unchanged
+///   - Only unpacked literal struct types are supported
 inline Type *toVectorizedTy(Type *Ty, ElementCount EC) {
   if (StructType *StructTy = dyn_cast<StructType>(Ty))
     return toVectorizedStructTy(StructTy, EC);

>From b0ff8df1e1987c10302d22b7e87b2a19347e77f6 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 19:05:01 +0000
Subject: [PATCH 10/14] RM

---
 llvm/include/llvm/Analysis/VectorUtils.h                      | 2 +-
 llvm/include/llvm/IR/{VectorUtils.h => VectorTypeUtils.h}     | 2 +-
 llvm/lib/IR/CMakeLists.txt                                    | 2 +-
 llvm/lib/IR/VFABIDemangler.cpp                                | 2 +-
 llvm/lib/IR/{VectorUtils.cpp => VectorTypeUtils.cpp}          | 4 ++--
 llvm/unittests/IR/CMakeLists.txt                              | 2 +-
 .../IR/{VectorUtilsTest.cpp => VectorTypeUtilsTest.cpp}       | 4 ++--
 7 files changed, 9 insertions(+), 9 deletions(-)
 rename llvm/include/llvm/IR/{VectorUtils.h => VectorTypeUtils.h} (98%)
 rename llvm/lib/IR/{VectorUtils.cpp => VectorTypeUtils.cpp} (94%)
 rename llvm/unittests/IR/{VectorUtilsTest.cpp => VectorTypeUtilsTest.cpp} (98%)

diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index 5433231a1018e9..7f8a0c9c0af7be 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -18,7 +18,7 @@
 #include "llvm/Analysis/LoopAccessAnalysis.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/VFABIDemangler.h"
-#include "llvm/IR/VectorUtils.h"
+#include "llvm/IR/VectorTypeUtils.h"
 #include "llvm/Support/CheckedArithmetic.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/IR/VectorUtils.h b/llvm/include/llvm/IR/VectorTypeUtils.h
similarity index 98%
rename from llvm/include/llvm/IR/VectorUtils.h
rename to llvm/include/llvm/IR/VectorTypeUtils.h
index 47ff1bbc98ebc5..ed838c05ba03a9 100644
--- a/llvm/include/llvm/IR/VectorUtils.h
+++ b/llvm/include/llvm/IR/VectorTypeUtils.h
@@ -1,4 +1,4 @@
-//===----------- VectorUtils.h - Vector type utility functions -*- C++ -*-====//
+//===------- VectorTypeUtils.h - Vector type utility functions -*- C++ -*-====//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 7eaf35e10ebc67..5f6254b2313180 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -73,7 +73,7 @@ add_llvm_component_library(LLVMCore
   Value.cpp
   ValueSymbolTable.cpp
   VectorBuilder.cpp
-  VectorUtils.cpp
+  VectorTypeUtils.cpp
   Verifier.cpp
   VFABIDemangler.cpp
   RuntimeLibcalls.cpp
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index a61eae6d478c3a..62f96b10cea4ac 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -11,7 +11,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/IR/Module.h"
-#include "llvm/IR/VectorUtils.h"
+#include "llvm/IR/VectorTypeUtils.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <limits>
diff --git a/llvm/lib/IR/VectorUtils.cpp b/llvm/lib/IR/VectorTypeUtils.cpp
similarity index 94%
rename from llvm/lib/IR/VectorUtils.cpp
rename to llvm/lib/IR/VectorTypeUtils.cpp
index 7a7ef2796a2a07..e6e265414a2b8e 100644
--- a/llvm/lib/IR/VectorUtils.cpp
+++ b/llvm/lib/IR/VectorTypeUtils.cpp
@@ -1,4 +1,4 @@
-//===- VectorUtils.cpp - Vector type utility functions --------------------===//
+//===------- VectorTypeUtils.cpp - Vector type utility functions ----------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/VectorUtils.h"
+#include "llvm/IR/VectorTypeUtils.h"
 #include "llvm/ADT/SmallVectorExtras.h"
 
 using namespace llvm;
diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt
index efbe710987a489..b3dfe3d72fd385 100644
--- a/llvm/unittests/IR/CMakeLists.txt
+++ b/llvm/unittests/IR/CMakeLists.txt
@@ -51,8 +51,8 @@ add_llvm_unittest(IRTests
   ValueMapTest.cpp
   ValueTest.cpp
   VectorBuilderTest.cpp
+  VectorTypeUtilsTest.cpp
   VectorTypesTest.cpp
-  VectorUtilsTest.cpp
   VerifierTest.cpp
   VFABIDemanglerTest.cpp
   VPIntrinsicTest.cpp
diff --git a/llvm/unittests/IR/VectorUtilsTest.cpp b/llvm/unittests/IR/VectorTypeUtilsTest.cpp
similarity index 98%
rename from llvm/unittests/IR/VectorUtilsTest.cpp
rename to llvm/unittests/IR/VectorTypeUtilsTest.cpp
index aac3bf1817f92c..00ae6bbdcd3ace 100644
--- a/llvm/unittests/IR/VectorUtilsTest.cpp
+++ b/llvm/unittests/IR/VectorTypeUtilsTest.cpp
@@ -1,4 +1,4 @@
-//===------- VectorUtilsTest.cpp - Vector utils tests ---------------------===//
+//===------- VectorTypeUtilsTest.cpp - Vector utils 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,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/VectorUtils.h"
+#include "llvm/IR/VectorTypeUtils.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
 #include "gtest/gtest.h"

>From 5c155cefc1fa7ff691a3eb1536238da4e6d93e18 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 19:07:08 +0000
Subject: [PATCH 11/14] RM

---
 llvm/include/llvm/IR/VectorTypeUtils.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/IR/VectorTypeUtils.h b/llvm/include/llvm/IR/VectorTypeUtils.h
index ed838c05ba03a9..756eed63fae49e 100644
--- a/llvm/include/llvm/IR/VectorTypeUtils.h
+++ b/llvm/include/llvm/IR/VectorTypeUtils.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_IR_VECTORUTILS_H
-#define LLVM_IR_VECTORUTILS_H
+#ifndef LLVM_IR_VECTORTYPEUTILS_H
+#define LLVM_IR_VECTORTYPEUTILS_H
 
 #include "llvm/IR/DerivedTypes.h"
 

>From dd90ff4460172021fba065eda20dfc1d3fe3bd8f Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 19:15:11 +0000
Subject: [PATCH 12/14] RM

---
 llvm/unittests/IR/VectorTypeUtilsTest.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/unittests/IR/VectorTypeUtilsTest.cpp b/llvm/unittests/IR/VectorTypeUtilsTest.cpp
index 00ae6bbdcd3ace..c77f183e921de4 100644
--- a/llvm/unittests/IR/VectorTypeUtilsTest.cpp
+++ b/llvm/unittests/IR/VectorTypeUtilsTest.cpp
@@ -15,9 +15,9 @@ using namespace llvm;
 
 namespace {
 
-class VectorUtilsTest : public ::testing::Test {};
+class VectorTypeUtilsTest : public ::testing::Test {};
 
-TEST(VectorUtilsTest, TestToVectorizedTy) {
+TEST(VectorTypeUtilsTest, TestToVectorizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -62,7 +62,7 @@ TEST(VectorUtilsTest, TestToVectorizedTy) {
   }
 }
 
-TEST(VectorUtilsTest, TestToScalarizedTy) {
+TEST(VectorTypeUtilsTest, TestToScalarizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -80,7 +80,7 @@ TEST(VectorUtilsTest, TestToScalarizedTy) {
   }
 }
 
-TEST(VectorUtilsTest, TestGetContainedTypes) {
+TEST(VectorTypeUtilsTest, TestGetContainedTypes) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -97,7 +97,7 @@ TEST(VectorUtilsTest, TestGetContainedTypes) {
   EXPECT_EQ(getContainedTypes(MixedStructTy), ArrayRef<Type *>({FTy, ITy}));
 }
 
-TEST(VectorUtilsTest, TestIsVectorizedTy) {
+TEST(VectorTypeUtilsTest, TestIsVectorizedTy) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);
@@ -130,7 +130,7 @@ TEST(VectorUtilsTest, TestIsVectorizedTy) {
   EXPECT_FALSE(isVectorizedTy(PackedWideStruct));
 }
 
-TEST(VectorUtilsTest, TestGetVectorizedTypeVF) {
+TEST(VectorTypeUtilsTest, TestGetVectorizedTypeVF) {
   LLVMContext C;
 
   Type *ITy = Type::getInt32Ty(C);

>From cbf5ff970c687cd72f8858628f317b68ea9fbeab Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 20:48:17 +0000
Subject: [PATCH 13/14] fix typo

---
 llvm/include/llvm/IR/VectorTypeUtils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/VectorTypeUtils.h b/llvm/include/llvm/IR/VectorTypeUtils.h
index 756eed63fae49e..4a48663911ed4f 100644
--- a/llvm/include/llvm/IR/VectorTypeUtils.h
+++ b/llvm/include/llvm/IR/VectorTypeUtils.h
@@ -44,7 +44,7 @@ bool isVectorizedStructTy(StructType *StructTy);
 /// equivalent to calling `ToVectorTy`. For struct types, this returns a new
 /// struct where each element type has been widened to a vector type.
 /// Note:
-///   - If the he incoming type is void, we return void
+///   - If the incoming type is void, we return void
 ///   - If \p EC is scalar, \p Ty is returned unchanged
 ///   - Only unpacked literal struct types are supported
 inline Type *toVectorizedTy(Type *Ty, ElementCount EC) {

>From 39c5bc4434ebf22416544c8bd47c948a95bcece4 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Tue, 17 Dec 2024 20:57:12 +0000
Subject: [PATCH 14/14] widened type -> vectorized type

---
 llvm/include/llvm/IR/VectorTypeUtils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/VectorTypeUtils.h b/llvm/include/llvm/IR/VectorTypeUtils.h
index 4a48663911ed4f..f30bf9ee9240b0 100644
--- a/llvm/include/llvm/IR/VectorTypeUtils.h
+++ b/llvm/include/llvm/IR/VectorTypeUtils.h
@@ -81,7 +81,7 @@ inline ArrayRef<Type *> getContainedTypes(Type *const &Ty) {
 
 /// Returns the number of vector elements for a vectorized type.
 inline ElementCount getVectorizedTypeVF(Type *Ty) {
-  assert(isVectorizedTy(Ty) && "expected widened type");
+  assert(isVectorizedTy(Ty) && "expected vectorized type");
   return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
 }
 



More information about the llvm-commits mailing list