[llvm] b1bc05d - [DataLayout] Add a specifier for element-aligned vectors (#180617)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 11 08:56:55 PDT 2026
Author: Justin Bogner
Date: 2026-03-11T08:56:50-07:00
New Revision: b1bc05d5b9c21013aec32167a0381431290dbdaf
URL: https://github.com/llvm/llvm-project/commit/b1bc05d5b9c21013aec32167a0381431290dbdaf
DIFF: https://github.com/llvm/llvm-project/commit/b1bc05d5b9c21013aec32167a0381431290dbdaf.diff
LOG: [DataLayout] Add a specifier for element-aligned vectors (#180617)
This adds the "ve" specifier to Data Layout, which says that vectors are
element-aligned by default for a target.
Note that we also remove the default vector specs for 64 and 128 bit
vectors - these match the natural alignment of those vectors, so they
didn't actually have any functional effect.
Added:
Modified:
llvm/docs/LangRef.rst
llvm/include/llvm/IR/DataLayout.h
llvm/lib/IR/DataLayout.cpp
llvm/unittests/IR/DataLayoutTest.cpp
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 2d22bfd22c624..8bf66c56f82fc 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3408,6 +3408,9 @@ as follows:
``v<size>:<abi>[:<pref>]``
This specifies the alignment for a vector type of a given bit
``<size>``. The value of ``<size>`` must be in the range [1,2^24).
+``ve``
+ Specifies that vectors are element-aligned by default, rather than having
+ natural alignment.
``f<size>:<abi>[:<pref>]``
This specifies the alignment for a floating-point type of a given bit
``<size>``. Only values of ``<size>`` that are supported by the target
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index a4f4980520f6b..583963ab12e26 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -108,6 +108,7 @@ class DataLayout {
private:
bool BigEndian = false;
+ bool VectorsAreElementAligned = false;
unsigned AllocaAddrSpace = 0;
unsigned ProgramAddrSpace = 0;
@@ -214,6 +215,9 @@ class DataLayout {
bool isLittleEndian() const { return !BigEndian; }
bool isBigEndian() const { return BigEndian; }
+ /// Whether vectors are element aligned, rather than naturally aligned.
+ bool vectorsAreElementAligned() const { return VectorsAreElementAligned; }
+
/// Returns the string representation of the DataLayout.
///
/// This representation is in the same format accepted by the string
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 05aa6c29c0e50..22b489110d064 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -188,15 +188,10 @@ constexpr DataLayout::PrimitiveSpec DefaultFloatSpecs[] = {
{64, Align::Constant<8>(), Align::Constant<8>()}, // f64:64:64
{128, Align::Constant<16>(), Align::Constant<16>()}, // f128:128:128
};
-constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
- {64, Align::Constant<8>(), Align::Constant<8>()}, // v64:64:64
- {128, Align::Constant<16>(), Align::Constant<16>()}, // v128:128:128
-};
DataLayout::DataLayout()
: IntSpecs(ArrayRef(DefaultIntSpecs)),
- FloatSpecs(ArrayRef(DefaultFloatSpecs)),
- VectorSpecs(ArrayRef(DefaultVectorSpecs)) {
+ FloatSpecs(ArrayRef(DefaultFloatSpecs)) {
// Default pointer type specifications.
setPointerSpec(0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false,
false, "");
@@ -212,6 +207,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
LayoutMap = nullptr;
StringRepresentation = Other.StringRepresentation;
BigEndian = Other.BigEndian;
+ VectorsAreElementAligned = Other.VectorsAreElementAligned;
AllocaAddrSpace = Other.AllocaAddrSpace;
ProgramAddrSpace = Other.ProgramAddrSpace;
DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace;
@@ -232,6 +228,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
bool DataLayout::operator==(const DataLayout &Other) const {
// NOTE: StringRepresentation might
diff er, it is not canonicalized.
return BigEndian == Other.BigEndian &&
+ VectorsAreElementAligned == Other.VectorsAreElementAligned &&
AllocaAddrSpace == Other.AllocaAddrSpace &&
ProgramAddrSpace == Other.ProgramAddrSpace &&
DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
@@ -537,6 +534,11 @@ Error DataLayout::parseSpecification(
return Error::success();
}
+ if (Spec == "ve") {
+ VectorsAreElementAligned = true;
+ return Error::success();
+ }
+
// The rest of the specifiers are single-character.
assert(!Spec.empty() && "Empty specification is handled by the caller");
char Specifier = Spec.front();
@@ -903,6 +905,9 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
if (I != VectorSpecs.end() && I->BitWidth == BitWidth)
return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+ if (vectorsAreElementAligned())
+ return getAlignment(cast<VectorType>(Ty)->getElementType(), abi_or_pref);
+
// By default, use natural alignment for vector types. This is consistent
// with what clang and llvm-gcc do.
//
diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp
index 5bef6fcd20126..40da68c24923a 100644
--- a/llvm/unittests/IR/DataLayoutTest.cpp
+++ b/llvm/unittests/IR/DataLayoutTest.cpp
@@ -815,17 +815,58 @@ TEST(DataLayoutTest, GlobalsAddressSpace) {
}
TEST(DataLayoutTest, VectorAlign) {
- Expected<DataLayout> DL = DataLayout::parse("v64:64");
- EXPECT_THAT_EXPECTED(DL, Succeeded());
-
LLVMContext Context;
Type *const FloatTy = Type::getFloatTy(Context);
- Type *const V8F32Ty = FixedVectorType::get(FloatTy, 8);
+ Type *const V4F32 = FixedVectorType::get(FloatTy, 4);
+ Type *const V8F32 = FixedVectorType::get(FloatTy, 8);
+ Type *const HalfTy = Type::getHalfTy(Context);
+ Type *const V4F16 = FixedVectorType::get(HalfTy, 4);
+
+ {
+ Expected<DataLayout> DL = DataLayout::parse("v64:16:64-v128:32:128");
+ EXPECT_THAT_EXPECTED(DL, Succeeded());
+ EXPECT_FALSE(DL->vectorsAreElementAligned());
+
+ EXPECT_EQ(Align(2), DL->getABITypeAlign(V4F16));
+ EXPECT_EQ(Align(8), DL->getPrefTypeAlign(V4F16));
+
+ EXPECT_EQ(Align(4), DL->getABITypeAlign(V4F32));
+ EXPECT_EQ(Align(16), DL->getPrefTypeAlign(V4F32));
+
+ // The alignment for a vector type larger than any specified vector type
+ // uses the natural alignment as a fallback.
+ EXPECT_EQ(Align(4 * 8), DL->getABITypeAlign(V8F32));
+ EXPECT_EQ(Align(4 * 8), DL->getPrefTypeAlign(V8F32));
+ }
+
+ {
+ Expected<DataLayout> DL = DataLayout::parse("ve");
+ EXPECT_THAT_EXPECTED(DL, Succeeded());
+ EXPECT_TRUE(DL->vectorsAreElementAligned());
- // The alignment for a vector type larger than any specified vector type uses
- // the natural alignment as a fallback.
- EXPECT_EQ(Align(4 * 8), DL->getABITypeAlign(V8F32Ty));
- EXPECT_EQ(Align(4 * 8), DL->getPrefTypeAlign(V8F32Ty));
+ EXPECT_EQ(DL->getABITypeAlign(FloatTy), DL->getABITypeAlign(V4F32));
+ EXPECT_EQ(DL->getABITypeAlign(FloatTy), DL->getABITypeAlign(V8F32));
+ EXPECT_EQ(DL->getABITypeAlign(HalfTy), DL->getABITypeAlign(V4F16));
+
+ EXPECT_EQ(DL->getPrefTypeAlign(FloatTy), DL->getPrefTypeAlign(V4F32));
+ EXPECT_EQ(DL->getPrefTypeAlign(FloatTy), DL->getPrefTypeAlign(V8F32));
+ EXPECT_EQ(DL->getPrefTypeAlign(HalfTy), DL->getPrefTypeAlign(V4F16));
+ }
+
+ {
+ Expected<DataLayout> DL = DataLayout::parse("ve-v64:64-v128:128-v256:256");
+ EXPECT_THAT_EXPECTED(DL, Succeeded());
+ EXPECT_TRUE(DL->vectorsAreElementAligned());
+
+ // Specific vector alignments override "ve"
+ EXPECT_EQ(Align(16), DL->getABITypeAlign(V4F32));
+ EXPECT_EQ(Align(32), DL->getABITypeAlign(V8F32));
+ EXPECT_EQ(Align(8), DL->getABITypeAlign(V4F16));
+
+ EXPECT_EQ(Align(16), DL->getPrefTypeAlign(V4F32));
+ EXPECT_EQ(Align(32), DL->getPrefTypeAlign(V8F32));
+ EXPECT_EQ(Align(8), DL->getPrefTypeAlign(V4F16));
+ }
}
TEST(DataLayoutTest, Equality) {
More information about the llvm-commits
mailing list