[Mlir-commits] [mlir] [MLIR][LLVM] Query target extension type data layouts (PR #236540)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 28 12:14:28 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Akimasa Watanuki (Men-cotton)
<details>
<summary>Changes</summary>
Expose the layout representation of LLVM target extension types and delegate size and alignment queries to that representation. Follow LLVM target type layout rules for pointer representations, explicit SPIR-V layouts, padding, and scalable vectors so clients do not need target-name-specific alignment fallbacks.
Assisted-by: Codex / GPT-6
---
Full diff: https://github.com/llvm/llvm-project/pull/236540.diff
4 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td (+6-1)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp (+69)
- (modified) mlir/unittests/Dialect/LLVMIR/CMakeLists.txt (+1)
- (modified) mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp (+86)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
index e31323651ceda1..fb798789ab195e 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
@@ -330,7 +330,9 @@ def LLVMPointerType : LLVMType<"LLVMPointer", "ptr", [
// LLVMTargetExtType
//===----------------------------------------------------------------------===//
-def LLVMTargetExtType : LLVMType<"LLVMTargetExt", "target"> {
+def LLVMTargetExtType : LLVMType<"LLVMTargetExt", "target", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface,
+ ["getPreferredAlignment"]>]> {
let summary = "LLVM target-specific extension type";
let description = [{
LLVM dialect target extension type, which are generally unintrospectable
@@ -359,6 +361,9 @@ def LLVMTargetExtType : LLVMType<"LLVMTargetExt", "target"> {
bool hasProperty(Property Prop) const;
bool supportsMemOps() const;
+
+ /// Return the type used for layout, or void for an unsized extension type.
+ Type getLayoutType() const;
}];
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index 2d99c0e4a4931d..0d7a9c31d86502 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/TypeSize.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
#include <optional>
using namespace mlir;
@@ -754,6 +755,74 @@ bool LLVM::LLVMTargetExtType::supportsMemOps() const {
return false;
}
+Type LLVM::LLVMTargetExtType::getLayoutType() const {
+ // Keep this mapping consistent with getTargetTypeInfo in
+ // llvm/lib/IR/Type.cpp.
+ MLIRContext *context = getContext();
+ StringRef name = getExtTypeName();
+ if (name == "spirv.Type") {
+ assert(getIntParams().size() == 3 &&
+ "wrong number of parameters for spirv.Type");
+ unsigned size = getIntParams()[1];
+ unsigned alignment = getIntParams()[2];
+ if (size && alignment)
+ return LLVMArrayType::get(IntegerType::get(context, alignment),
+ size * 8 / alignment);
+ return IntegerType::get(context, 32);
+ }
+ if (name == "spirv.IntegralConstant" || name == "spirv.Literal" ||
+ name == "amdgpu.stridemark")
+ return LLVMVoidType::get(context);
+ if (name == "spirv.Padding" || name == "dx.Padding") {
+ assert(getIntParams().size() == 1 && "expected padding size");
+ return LLVMArrayType::get(IntegerType::get(context, 8), getIntParams()[0]);
+ }
+ if (name.starts_with(kSpirvPrefix) || name.starts_with("dx.") ||
+ name == "wasm.funcref" || name == "wasm.externref")
+ return LLVMPointerType::get(context);
+ if (name == kArmSVCount)
+ return VectorType::get({16}, IntegerType::get(context, 1), {true});
+ if (name == "riscv.vector.tuple") {
+ assert(getTypeParams().size() == 1 && getIntParams().size() == 1 &&
+ "expected tuple vector type and field count");
+ unsigned numElements =
+ std::max(getVectorNumElements(getTypeParams()[0]).getKnownMinValue(),
+ llvm::RISCV::RVVBytesPerBlock) *
+ getIntParams()[0];
+ return VectorType::get({numElements}, IntegerType::get(context, 8), {true});
+ }
+ if (name == kAMDGCNNamedBarrier)
+ return IntegerType::get(context, 8);
+ if (name == "llvm.test.vectorelement")
+ return IntegerType::get(context, 32);
+ return LLVMVoidType::get(context);
+}
+
+llvm::TypeSize LLVM::LLVMTargetExtType::getTypeSizeInBits(
+ const DataLayout &dataLayout, DataLayoutEntryListRef params) const {
+ Type layoutType = getLayoutType();
+ // LLVM vector bit sizes do not round the element count up to a power of two,
+ // unlike the default data layout for builtin MLIR vectors.
+ if (auto vectorType = dyn_cast<VectorType>(layoutType))
+ return llvm::TypeSize::get(
+ vectorType.getNumElements() *
+ dataLayout.getTypeSizeInBits(vectorType.getElementType())
+ .getFixedValue(),
+ vectorType.isScalable());
+ return dataLayout.getTypeSizeInBits(layoutType);
+}
+
+uint64_t
+LLVM::LLVMTargetExtType::getABIAlignment(const DataLayout &dataLayout,
+ DataLayoutEntryListRef params) const {
+ return dataLayout.getTypeABIAlignment(getLayoutType());
+}
+
+uint64_t LLVM::LLVMTargetExtType::getPreferredAlignment(
+ const DataLayout &dataLayout, DataLayoutEntryListRef params) const {
+ return dataLayout.getTypePreferredAlignment(getLayoutType());
+}
+
//===----------------------------------------------------------------------===//
// LLVMPPCFP128Type
//===----------------------------------------------------------------------===//
diff --git a/mlir/unittests/Dialect/LLVMIR/CMakeLists.txt b/mlir/unittests/Dialect/LLVMIR/CMakeLists.txt
index 0dffa51bdcf167..784a857872658c 100644
--- a/mlir/unittests/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/unittests/Dialect/LLVMIR/CMakeLists.txt
@@ -5,6 +5,7 @@ add_mlir_unittest(MLIRLLVMIRTests
)
mlir_target_link_libraries(MLIRLLVMIRTests
PRIVATE
+ MLIRDLTIDialect
MLIRFuncDialect
MLIRLLVMDialect
MLIRROCDLDialect
diff --git a/mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp b/mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp
index 72d8867d232aad..aa8176693f9a3e 100644
--- a/mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp
+++ b/mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp
@@ -7,7 +7,13 @@
//===----------------------------------------------------------------------===//
#include "LLVMTestBase.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
using namespace mlir;
using namespace mlir::LLVM;
@@ -60,3 +66,83 @@ TEST_F(LLVMIRTest, StructElementOffsets) {
EXPECT_EQ(packedAlloc.getElementOffset(dataLayout, 1), 16u);
EXPECT_EQ(dataLayout.getTypeSize(packedAlloc), 17u);
}
+
+TEST_F(LLVMIRTest, TargetExtensionLayoutMatchesLLVM) {
+ DataLayout layout;
+ llvm::LLVMContext llvmContext;
+ llvm::DataLayout llvmLayout("");
+ auto check = [&](StringRef name, ArrayRef<Type> typeParams,
+ ArrayRef<llvm::Type *> llvmTypeParams,
+ ArrayRef<unsigned> intParams) {
+ SCOPED_TRACE(name.str());
+ auto type = LLVMTargetExtType::get(&context, name, typeParams, intParams);
+ auto *llvmType =
+ llvm::TargetExtType::get(llvmContext, name, llvmTypeParams, intParams);
+ llvm::TypeSize size = layout.getTypeSizeInBits(type);
+ llvm::TypeSize llvmSize = llvmLayout.getTypeSizeInBits(llvmType);
+ EXPECT_EQ(size.getKnownMinValue(), llvmSize.getKnownMinValue());
+ EXPECT_EQ(size.isScalable(), llvmSize.isScalable());
+ EXPECT_EQ(layout.getTypeABIAlignment(type),
+ llvmLayout.getABITypeAlign(llvmType).value());
+ EXPECT_EQ(layout.getTypePreferredAlignment(type),
+ llvmLayout.getPrefTypeAlign(llvmType).value());
+ };
+
+ check("spirv.Image", {Float32Type::get(&context)},
+ {llvm::Type::getFloatTy(llvmContext)}, {1, 0, 0, 0, 0, 0, 0});
+ check("spirv.SignedImage", {}, {}, {});
+ check("spirv.Sampler", {}, {}, {});
+ check("spirv.Pipe", {}, {}, {0});
+ check("spirv.Event", {}, {}, {});
+ check("dx.RawBuffer", {IntegerType::get(&context, 32)},
+ {llvm::Type::getInt32Ty(llvmContext)}, {0, 0});
+ check("wasm.funcref", {}, {}, {});
+ check("wasm.externref", {}, {}, {});
+ check("spirv.Type", {}, {}, {0, 8, 32});
+ check("spirv.Type", {}, {}, {0, 0, 0});
+ check("spirv.Padding", {}, {}, {3});
+ check("dx.Padding", {}, {}, {3});
+ check("amdgcn.named.barrier", {}, {}, {0});
+ check("llvm.test.vectorelement", {}, {}, {});
+ check("aarch64.svcount", {}, {}, {});
+ check("riscv.vector.tuple",
+ {VectorType::get({4}, IntegerType::get(&context, 64), {true})},
+ {llvm::ScalableVectorType::get(llvm::Type::getInt64Ty(llvmContext), 4)},
+ {3});
+}
+
+TEST_F(LLVMIRTest, UnsizedTargetExtensionLayout) {
+ for (StringRef name : {"spirv.IntegralConstant", "spirv.Literal",
+ "amdgpu.stridemark", "unknown"}) {
+ SCOPED_TRACE(name.str());
+ auto type = LLVMTargetExtType::get(&context, name, {}, {});
+ EXPECT_TRUE(isa<LLVMVoidType>(type.getLayoutType()));
+ }
+}
+
+TEST_F(LLVMIRTest, TargetExtensionLayoutInAggregates) {
+ DataLayout layout;
+ auto sampler = LLVMTargetExtType::get(&context, "spirv.Sampler", {}, {});
+ auto array = LLVMArrayType::get(sampler, 3);
+ EXPECT_EQ(layout.getTypeSize(array).getFixedValue(), 24u);
+ EXPECT_EQ(layout.getTypeABIAlignment(array), 8u);
+ auto record = LLVMStructType::getLiteral(
+ &context, {IntegerType::get(&context, 8), sampler});
+ EXPECT_EQ(record.getElementOffset(layout, 1), 8u);
+ EXPECT_EQ(layout.getTypeSize(record).getFixedValue(), 16u);
+}
+
+TEST_F(LLVMIRTest, TargetExtensionCustomPointerLayout) {
+ context.getOrLoadDialect<DLTIDialect>();
+ Builder builder(&context);
+ OwningOpRef<ModuleOp> module = ModuleOp::create(builder.getUnknownLoc());
+ auto pointerEntry = DataLayoutEntryAttr::get(
+ LLVMPointerType::get(&context), builder.getI64VectorAttr({32, 32, 64}));
+ (*module)->setAttr(DLTIDialect::kDataLayoutAttrName,
+ DataLayoutSpecAttr::get(&context, {pointerEntry}));
+ DataLayout layout(module.get());
+ auto sampler = LLVMTargetExtType::get(&context, "spirv.Sampler", {}, {});
+ EXPECT_EQ(layout.getTypeSizeInBits(sampler).getFixedValue(), 32u);
+ EXPECT_EQ(layout.getTypeABIAlignment(sampler), 4u);
+ EXPECT_EQ(layout.getTypePreferredAlignment(sampler), 8u);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/236540
More information about the Mlir-commits
mailing list