[Mlir-commits] [mlir] f9423ed - [mlir] Fix alignment for predicate (i1) vectors (#175975)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Feb 2 01:16:30 PST 2026
Author: Andrzej Warzyński
Date: 2026-02-02T09:16:26Z
New Revision: f9423ed07c7a6839aa58bf010f0278f959948c99
URL: https://github.com/llvm/llvm-project/commit/f9423ed07c7a6839aa58bf010f0278f959948c99
DIFF: https://github.com/llvm/llvm-project/commit/f9423ed07c7a6839aa58bf010f0278f959948c99.diff
LOG: [mlir] Fix alignment for predicate (i1) vectors (#175975)
Legal scalable predicate vectors (legal in the LLVM sense), e.g.
`vector<[16]xi1>` (or `<vscale x 16 x i1>`, using LLVM syntax) ought to
have alignment **2** rather than **16**, see e.g. [1].
MLIR currently computes the vector “size in bits” as:
```cpp
vecType.getNumElements()
* dataLayout.getTypeSize(vecType.getElementType()) * 8
```
but `getTypeSize()` returns a size in *bytes* (rounded up from bits), so
for `i1` it returns 1. Multiplying by 8 converts that storage byte back to 8
bits per element, which overestimates predicate vector sizes.
Instead, use:
```cpp
vecType.getNumElements()
* dataLayout.getTypeSizeInBits(vecType.getElementType())
```
For `vector<[16]xi1>` this changes:
* [before]: `alignment = 16 * (1 byte * 8) (i.e. `128 bits`),
to:
* [after]: `alignment = 16 * 1 bit` (i.e. `16 bits`).
This is a very small update that, based on the available tests, only
affects types like `vector<[16]xi1>`. It aligns MLIR with LLVM, making
sure that the corresponding alignment is 2 rather that 16. For context,
LLVM computes the alignment in this case via `getTypeStoreSize`, which
for `16 x i1` returns 2 bytes. Perhaps MLIR should follow similar path
in the future.
[1] https://developer.arm.com/documentation/ddi0602/2025-12/SVE-Instructions/LDR--predicate---Load-predicate-register-?lang=en
Added:
Modified:
mlir/lib/Interfaces/DataLayoutInterfaces.cpp
mlir/test/Interfaces/DataLayoutInterfaces/query.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Interfaces/DataLayoutInterfaces.cpp b/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
index 2b73001bb55eb..4aec320ddeff5 100644
--- a/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
+++ b/mlir/lib/Interfaces/DataLayoutInterfaces.cpp
@@ -71,14 +71,12 @@ mlir::detail::getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout,
IntegerType::get(type.getContext(), getIndexBitwidth(params)));
// Sizes of vector types are rounded up to those of types with closest
- // power-of-two number of elements in the innermost dimension. We also assume
- // there is no bit-packing at the moment element sizes are taken in bytes and
- // multiplied with 8 bits.
+ // power-of-two number of elements in the innermost dimension.
// TODO: make this extensible.
if (auto vecType = dyn_cast<VectorType>(type)) {
uint64_t baseSize = vecType.getNumElements() / vecType.getShape().back() *
llvm::PowerOf2Ceil(vecType.getShape().back()) *
- dataLayout.getTypeSize(vecType.getElementType()) * 8;
+ dataLayout.getTypeSizeInBits(vecType.getElementType());
return llvm::TypeSize::get(baseSize, vecType.isScalable());
}
diff --git a/mlir/test/Interfaces/DataLayoutInterfaces/query.mlir b/mlir/test/Interfaces/DataLayoutInterfaces/query.mlir
index 5df32555000ad..97ef8b2a8ae1c 100644
--- a/mlir/test/Interfaces/DataLayoutInterfaces/query.mlir
+++ b/mlir/test/Interfaces/DataLayoutInterfaces/query.mlir
@@ -44,6 +44,12 @@ func.func @no_layout_builtin() {
// CHECK: preferred = 16
// CHECK: size = {minimal_size = 16 : index, scalable}
"test.data_layout_query"() : () -> vector<[4]xi32>
+ // CHECK: alignment = 2
+ // CHECK: bitsize = {minimal_size = 16 : index, scalable}
+ // CHECK: index = 0
+ // CHECK: preferred = 2
+ // CHECK: size = {minimal_size = 2 : index, scalable}
+ "test.data_layout_query"() : () -> vector<[16]xi1>
return
}
More information about the Mlir-commits
mailing list