[Mlir-commits] [mlir] [mlir][ABI] Fix scalable vector mapping in ABITypeMapper (PR #206617)
Fedor Nikolaev
llvmlistbot at llvm.org
Tue Jun 30 05:34:03 PDT 2026
https://github.com/felichita updated https://github.com/llvm/llvm-project/pull/206617
>From 63c23741f0c5cc9ac418dc5a484dbbae9b0f3337 Mon Sep 17 00:00:00 2001
From: Fedor Nikolaev <fridrixnm at gmail.com>
Date: Tue, 30 Jun 2026 01:40:44 +0200
Subject: [PATCH] [mlir][ABI] Fix scalable vector mapping in ABITypeMapper
mapVectorType always used ElementCount::getFixed, even for scalable
vectors. Use the correct scalable flag based on the VectorType.
ElementCount can only express a single scalable dimension, so vectors
with more than one scalable dim (e.g. vector<[2]x[4]xf32>) cannot be
represented correctly; return nullptr in that case instead of
silently computing a wrong size.
---
mlir/lib/ABI/ABITypeMapper.cpp | 10 +++++++-
mlir/unittests/ABI/ABITypeMapperTest.cpp | 30 ++++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/ABI/ABITypeMapper.cpp b/mlir/lib/ABI/ABITypeMapper.cpp
index 83dc6990ec5bb..109b70c93952f 100644
--- a/mlir/lib/ABI/ABITypeMapper.cpp
+++ b/mlir/lib/ABI/ABITypeMapper.cpp
@@ -70,12 +70,20 @@ const llvm::abi::Type *ABITypeMapper::mapVectorType(mlir::VectorType type) {
if (!elementTy)
return nullptr;
+ // ABI lowering cannot represent vectors with more than one scalable
+ // dimension (e.g. vector<[2]x[4]xf32>) since ElementCount only has a
+ // single scalable bit and would silently produce vscale*N instead of
+ // the correct vscale^2*N.
+ if (llvm::count(type.getScalableDims(), true) > 1)
+ return nullptr;
+
auto shape = type.getShape();
uint64_t totalElements = 1;
for (int64_t dim : shape)
totalElements *= dim;
- llvm::ElementCount ec = llvm::ElementCount::getFixed(totalElements);
+ bool isScalable = llvm::is_contained(type.getScalableDims(), true);
+ llvm::ElementCount ec = llvm::ElementCount::get(totalElements, isScalable);
uint64_t abiAlign = dl.getTypeABIAlignment(type);
return builder.getVectorType(elementTy, ec, llvm::Align(abiAlign));
}
diff --git a/mlir/unittests/ABI/ABITypeMapperTest.cpp b/mlir/unittests/ABI/ABITypeMapperTest.cpp
index 4a7989298a149..573ab9df9896f 100644
--- a/mlir/unittests/ABI/ABITypeMapperTest.cpp
+++ b/mlir/unittests/ABI/ABITypeMapperTest.cpp
@@ -170,4 +170,34 @@ TEST_F(ABITypeMapperTest, MapUnsignedI32) {
EXPECT_FALSE(intTy->isSigned());
}
+TEST_F(ABITypeMapperTest, MapScalableVectorOf4xF32) {
+ DataLayout dl(module);
+ ABITypeMapper mapper(dl);
+
+ auto f32 = Float32Type::get(&ctx);
+ auto vec = VectorType::get({4}, f32, /* scalableDims=*/true);
+ const llvm::abi::Type *result = mapper.map(vec);
+
+ ASSERT_NE(result, nullptr);
+ EXPECT_TRUE(result->isVector());
+
+ auto *vecTy = llvm::cast<llvm::abi::VectorType>(result);
+ EXPECT_TRUE(vecTy->getNumElements().isScalable());
+ EXPECT_EQ(vecTy->getNumElements().getKnownMinValue(), 4u);
+ EXPECT_TRUE(vecTy->getElementType()->isFloat());
+}
+
+TEST_F(ABITypeMapperTest, MapMultiScalableVectorReturnsNull) {
+ DataLayout dl(module);
+ ABITypeMapper mapper(dl);
+
+ auto f32 = Float32Type::get(&ctx);
+ auto vec = VectorType::get({2, 4}, f32, /*scalableDims=*/{true, true});
+ const llvm::abi::Type *result = mapper.map(vec);
+
+ // (vscale*2)*(vscale*4) = vscale^2*8,
+ // ElementCount -> must return nullptr
+ EXPECT_EQ(result, nullptr);
+}
+
} // namespace
More information about the Mlir-commits
mailing list