[Mlir-commits] [mlir] [mlir][vector][memref] Add `alignment` attribute to memory access ops (PR #144344)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Jun 16 16:53:35 PDT 2025
https://github.com/tyb0807 updated https://github.com/llvm/llvm-project/pull/144344
>From 49edb9f57a60a245bc91a1677b6cdca5ed505d3e Mon Sep 17 00:00:00 2001
From: tyb0807 <sontuan.vu119 at gmail.com>
Date: Mon, 16 Jun 2025 14:45:40 +0200
Subject: [PATCH] [mlir][memref][vectpr] Add alignment attribute to memory
access ops
---
.../mlir/Dialect/MemRef/IR/MemRefOps.td | 66 ++++++++++++-
.../mlir/Dialect/Vector/IR/VectorOps.td | 69 +++++++++++++-
.../Dialect/MemRef/load-store-alignment.mlir | 27 ++++++
.../Dialect/Vector/load-store-alignment.mlir | 27 ++++++
mlir/unittests/Dialect/CMakeLists.txt | 1 +
mlir/unittests/Dialect/MemRef/CMakeLists.txt | 1 +
.../Dialect/MemRef/LoadStoreAlignment.cpp | 86 +++++++++++++++++
mlir/unittests/Dialect/Vector/CMakeLists.txt | 7 ++
.../Dialect/Vector/LoadStoreAlignment.cpp | 93 +++++++++++++++++++
9 files changed, 371 insertions(+), 6 deletions(-)
create mode 100644 mlir/test/Dialect/MemRef/load-store-alignment.mlir
create mode 100644 mlir/test/Dialect/Vector/load-store-alignment.mlir
create mode 100644 mlir/unittests/Dialect/MemRef/LoadStoreAlignment.cpp
create mode 100644 mlir/unittests/Dialect/Vector/CMakeLists.txt
create mode 100644 mlir/unittests/Dialect/Vector/LoadStoreAlignment.cpp
diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
index 77e3074661abf..60eb469c4398e 100644
--- a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
+++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
@@ -1217,6 +1217,11 @@ def LoadOp : MemRef_Op<"load",
be reused in the cache. For details, refer to the
[https://llvm.org/docs/LangRef.html#load-instruction](LLVM load instruction).
+ An optional `alignment` attribute allows to specify the byte alignment of the
+ load operation. It must be a positive power of 2. The operation must access
+ memory at an address aligned to this boundary. Violations may lead to
+ architecture-specific faults or performance penalties.
+ A value of 0 indicates no specific alignment requirement.
Example:
```mlir
@@ -1227,7 +1232,38 @@ def LoadOp : MemRef_Op<"load",
let arguments = (ins Arg<AnyMemRef, "the reference to load from",
[MemRead]>:$memref,
Variadic<Index>:$indices,
- DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal);
+ DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal,
+ ConfinedAttr<OptionalAttr<I64Attr>,
+ [IntMinValue<0>]>:$alignment);
+
+ let builders = [
+ OpBuilder<(ins "Value":$memref,
+ "ValueRange":$indices,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, memref, indices, false,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>,
+ OpBuilder<(ins "Type":$resultType,
+ "Value":$memref,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, resultType, memref, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>,
+ OpBuilder<(ins "TypeRange":$resultTypes,
+ "Value":$memref,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, resultTypes, memref, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>
+ ];
+
let results = (outs AnyType:$result);
let extraClassDeclaration = [{
@@ -1913,6 +1949,11 @@ def MemRef_StoreOp : MemRef_Op<"store",
be reused in the cache. For details, refer to the
[https://llvm.org/docs/LangRef.html#store-instruction](LLVM store instruction).
+ An optional `alignment` attribute allows to specify the byte alignment of the
+ store operation. It must be a positive power of 2. The operation must access
+ memory at an address aligned to this boundary. Violations may lead to
+ architecture-specific faults or performance penalties.
+ A value of 0 indicates no specific alignment requirement.
Example:
```mlir
@@ -1924,13 +1965,32 @@ def MemRef_StoreOp : MemRef_Op<"store",
Arg<AnyMemRef, "the reference to store to",
[MemWrite]>:$memref,
Variadic<Index>:$indices,
- DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal);
+ DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal,
+ ConfinedAttr<OptionalAttr<I64Attr>,
+ [IntMinValue<0>]>:$alignment);
let builders = [
+ OpBuilder<(ins "Value":$valueToStore,
+ "Value":$memref,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, valueToStore, memref, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>,
+ OpBuilder<(ins "Value":$valueToStore,
+ "Value":$memref,
+ "ValueRange":$indices,
+ "uint64_t":$alignment), [{
+ return build($_builder, $_state, valueToStore, memref, indices, false,
+ $_builder.getI64IntegerAttr(alignment));
+ }]>,
OpBuilder<(ins "Value":$valueToStore, "Value":$memref), [{
$_state.addOperands(valueToStore);
$_state.addOperands(memref);
- }]>];
+ }]>
+ ];
let extraClassDeclaration = [{
Value getValueToStore() { return getOperand(0); }
diff --git a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
index 8353314ed958b..66c65892f636c 100644
--- a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
@@ -1734,12 +1734,49 @@ def Vector_LoadOp : Vector_Op<"load"> {
```mlir
%result = vector.load %memref[%c0] : memref<7xf32>, vector<8xf32>
```
+
+ An optional `alignment` attribute allows to specify the byte alignment of the
+ load operation. It must be a positive power of 2. The operation must access
+ memory at an address aligned to this boundary. Violations may lead to
+ architecture-specific faults or performance penalties.
+ A value of 0 indicates no specific alignment requirement.
}];
let arguments = (ins Arg<AnyMemRef, "the reference to load from",
[MemRead]>:$base,
Variadic<Index>:$indices,
- DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal);
+ DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal,
+ ConfinedAttr<OptionalAttr<I64Attr>,
+ [IntMinValue<0>]>:$alignment);
+
+ let builders = [
+ OpBuilder<(ins "VectorType":$resultType,
+ "Value":$base,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, resultType, base, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>,
+ OpBuilder<(ins "VectorType":$resultType,
+ "Value":$base,
+ "ValueRange":$indices,
+ "uint64_t":$alignment), [{
+ return build($_builder, $_state, resultType, base, indices, false,
+ $_builder.getI64IntegerAttr(alignment));
+ }]>,
+ OpBuilder<(ins "TypeRange":$resultTypes,
+ "Value":$base,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, resultTypes, base, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>
+ ];
+
let results = (outs AnyVectorOfAnyRank:$result);
let extraClassDeclaration = [{
@@ -1818,6 +1855,12 @@ def Vector_StoreOp : Vector_Op<"store"> {
```mlir
vector.store %valueToStore, %memref[%c0] : memref<7xf32>, vector<8xf32>
```
+
+ An optional `alignment` attribute allows to specify the byte alignment of the
+ store operation. It must be a positive power of 2. The operation must access
+ memory at an address aligned to this boundary. Violations may lead to
+ architecture-specific faults or performance penalties.
+ A value of 0 indicates no specific alignment requirement.
}];
let arguments = (ins
@@ -1825,8 +1868,28 @@ def Vector_StoreOp : Vector_Op<"store"> {
Arg<AnyMemRef, "the reference to store to",
[MemWrite]>:$base,
Variadic<Index>:$indices,
- DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal
- );
+ DefaultValuedOptionalAttr<BoolAttr, "false">:$nontemporal,
+ ConfinedAttr<OptionalAttr<I64Attr>,
+ [IntMinValue<0>]>:$alignment);
+
+ let builders = [
+ OpBuilder<(ins "Value":$valueToStore,
+ "Value":$base,
+ "ValueRange":$indices,
+ CArg<"bool", "false">:$nontemporal,
+ CArg<"uint64_t", "0">:$alignment), [{
+ return build($_builder, $_state, valueToStore, base, indices, nontemporal,
+ alignment != 0 ? $_builder.getI64IntegerAttr(alignment) :
+ nullptr);
+ }]>,
+ OpBuilder<(ins "Value":$valueToStore,
+ "Value":$base,
+ "ValueRange":$indices,
+ "uint64_t":$alignment), [{
+ return build($_builder, $_state, valueToStore, base, indices, false,
+ $_builder.getI64IntegerAttr(alignment));
+ }]>
+ ];
let extraClassDeclaration = [{
MemRefType getMemRefType() {
diff --git a/mlir/test/Dialect/MemRef/load-store-alignment.mlir b/mlir/test/Dialect/MemRef/load-store-alignment.mlir
new file mode 100644
index 0000000000000..57947e894c4dd
--- /dev/null
+++ b/mlir/test/Dialect/MemRef/load-store-alignment.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
+
+// CHECK-LABEL: func @test_load_store_alignment
+// CHECK: memref.load {{.*}} {alignment = 16 : i64}
+// CHECK: memref.store {{.*}} {alignment = 16 : i64}
+func.func @test_load_store_alignment(%memref: memref<4xi32>) {
+ %c0 = arith.constant 0 : index
+ %val = memref.load %memref[%c0] { alignment = 16 } : memref<4xi32>
+ memref.store %val, %memref[%c0] { alignment = 16 } : memref<4xi32>
+ return
+}
+
+// -----
+
+func.func @test_invalid_load_alignment(%memref: memref<4xi32>) {
+ // expected-error @+1 {{custom op 'memref.load' 'memref.load' op attribute 'alignment' failed to satisfy constraint: 64-bit signless integer attribute whose minimum value is 0}}
+ %val = memref.load %memref[%c0] { alignment = -1 } : memref<4xi32>
+ return
+}
+
+// -----
+
+func.func @test_invalid_store_alignment(%memref: memref<4xi32>, %val: memref<4xi32>) {
+ // expected-error @+1 {{custom op 'memref.store' 'memref.store' op attribute 'alignment' failed to satisfy constraint: 64-bit signless integer attribute whose minimum value is 0}}
+ memref.store %val, %memref[%c0] { alignment = -1 } : memref<4xi32>
+ return
+}
diff --git a/mlir/test/Dialect/Vector/load-store-alignment.mlir b/mlir/test/Dialect/Vector/load-store-alignment.mlir
new file mode 100644
index 0000000000000..dbc9be8c56eaf
--- /dev/null
+++ b/mlir/test/Dialect/Vector/load-store-alignment.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
+
+// CHECK-LABEL: func @test_load_store_alignment
+// CHECK: vector.load {{.*}} {alignment = 16 : i64}
+// CHECK: vector.store {{.*}} {alignment = 16 : i64}
+func.func @test_load_store_alignment(%memref: memref<4xi32>) {
+ %c0 = arith.constant 0 : index
+ %val = vector.load %memref[%c0] { alignment = 16 } : memref<4xi32>, vector<4xi32>
+ vector.store %val, %memref[%c0] { alignment = 16 } : memref<4xi32>, vector<4xi32>
+ return
+}
+
+// -----
+
+func.func @test_invalid_load_alignment(%memref: memref<4xi32>) {
+ // expected-error @+1 {{custom op 'vector.load' 'vector.load' op attribute 'alignment' failed to satisfy constraint: 64-bit signless integer attribute whose minimum value is 0}}
+ %val = vector.load %memref[%c0] { alignment = -1 } : memref<4xi32>, vector<4xi32>
+ return
+}
+
+// -----
+
+func.func @test_invalid_store_alignment(%memref: memref<4xi32>, %val: vector<4xi32>) {
+ // expected-error @+1 {{custom op 'vector.store' 'vector.store' op attribute 'alignment' failed to satisfy constraint: 64-bit signless integer attribute whose minimum value is 0}}
+ vector.store %val, %memref[%c0] { alignment = -1 } : memref<4xi32>, vector<4xi32>
+ return
+}
diff --git a/mlir/unittests/Dialect/CMakeLists.txt b/mlir/unittests/Dialect/CMakeLists.txt
index aea247547473d..34c9fb7317443 100644
--- a/mlir/unittests/Dialect/CMakeLists.txt
+++ b/mlir/unittests/Dialect/CMakeLists.txt
@@ -18,3 +18,4 @@ add_subdirectory(SPIRV)
add_subdirectory(SMT)
add_subdirectory(Transform)
add_subdirectory(Utils)
+add_subdirectory(Vector)
diff --git a/mlir/unittests/Dialect/MemRef/CMakeLists.txt b/mlir/unittests/Dialect/MemRef/CMakeLists.txt
index dede3ba0a885c..87d33854fadcd 100644
--- a/mlir/unittests/Dialect/MemRef/CMakeLists.txt
+++ b/mlir/unittests/Dialect/MemRef/CMakeLists.txt
@@ -1,5 +1,6 @@
add_mlir_unittest(MLIRMemRefTests
InferShapeTest.cpp
+ LoadStoreAlignment.cpp
)
mlir_target_link_libraries(MLIRMemRefTests
PRIVATE
diff --git a/mlir/unittests/Dialect/MemRef/LoadStoreAlignment.cpp b/mlir/unittests/Dialect/MemRef/LoadStoreAlignment.cpp
new file mode 100644
index 0000000000000..139144a08a26f
--- /dev/null
+++ b/mlir/unittests/Dialect/MemRef/LoadStoreAlignment.cpp
@@ -0,0 +1,86 @@
+//===- LoadStoreAlignment.cpp - unit tests for load/store alignment -------===//
+//
+// 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 "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Verifier.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::memref;
+
+TEST(LoadStoreAlignmentTest, ValidAlignment) {
+ MLIRContext ctx;
+ OpBuilder b(&ctx);
+ ctx.loadDialect<memref::MemRefDialect>();
+
+ // Create a dummy memref
+ Type elementType = b.getI32Type();
+ auto memrefType = MemRefType::get({4}, elementType);
+ Value memref = b.create<memref::AllocaOp>(b.getUnknownLoc(), memrefType);
+
+ // Create load with valid alignment
+ Value zero = b.create<arith::ConstantIndexOp>(b.getUnknownLoc(), 0);
+ auto loadOp = b.create<LoadOp>(b.getUnknownLoc(), memref, ValueRange{zero},
+ static_cast<uint64_t>(16));
+
+ // Verify the attribute exists
+ auto alignmentAttr = loadOp->getAttrOfType<IntegerAttr>("alignment");
+ EXPECT_TRUE(alignmentAttr != nullptr);
+ EXPECT_EQ(alignmentAttr.getInt(), 16);
+
+ // Create store with valid alignment
+ auto storeOp = b.create<StoreOp>(b.getUnknownLoc(), loadOp, memref,
+ ValueRange{zero}, static_cast<uint64_t>(16));
+
+ // Verify the attribute exists
+ alignmentAttr = storeOp->getAttrOfType<IntegerAttr>("alignment");
+ EXPECT_TRUE(alignmentAttr != nullptr);
+ EXPECT_EQ(alignmentAttr.getInt(), 16);
+}
+
+TEST(LoadStoreAlignmentTest, InvalidAlignmentFailsVerification) {
+ MLIRContext ctx;
+ OpBuilder b(&ctx);
+ ctx.loadDialect<memref::MemRefDialect>();
+
+ Type elementType = b.getI32Type();
+ auto memrefType = MemRefType::get({4}, elementType);
+ Value memref = b.create<memref::AllocaOp>(b.getUnknownLoc(), memrefType);
+
+ Value zero = b.create<arith::ConstantIndexOp>(b.getUnknownLoc(), 0);
+
+ auto loadOp =
+ b.create<LoadOp>(b.getUnknownLoc(), memref, ValueRange{zero}, -1);
+
+ // Capture diagnostics
+ std::string errorMessage;
+ ScopedDiagnosticHandler handler(
+ &ctx, [&](Diagnostic &diag) { errorMessage = diag.str(); });
+
+ // Trigger verification
+ auto result = mlir::verify(loadOp);
+
+ // Check results
+ EXPECT_TRUE(failed(result));
+ EXPECT_EQ(
+ errorMessage,
+ "'memref.load' op attribute 'alignment' failed to satisfy constraint: "
+ "64-bit signless integer attribute whose minimum value is 0");
+
+ auto storeOp = b.create<StoreOp>(b.getUnknownLoc(), loadOp, memref,
+ ValueRange{zero}, false, -1);
+ result = mlir::verify(storeOp);
+
+ // Check results
+ EXPECT_TRUE(failed(result));
+ EXPECT_EQ(
+ errorMessage,
+ "'memref.store' op attribute 'alignment' failed to satisfy constraint: "
+ "64-bit signless integer attribute whose minimum value is 0");
+}
diff --git a/mlir/unittests/Dialect/Vector/CMakeLists.txt b/mlir/unittests/Dialect/Vector/CMakeLists.txt
new file mode 100644
index 0000000000000..b23d9c2df3870
--- /dev/null
+++ b/mlir/unittests/Dialect/Vector/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_mlir_unittest(MLIRVectorTests
+ LoadStoreAlignment.cpp
+)
+mlir_target_link_libraries(MLIRVectorTests
+ PRIVATE
+ MLIRVectorDialect
+ )
diff --git a/mlir/unittests/Dialect/Vector/LoadStoreAlignment.cpp b/mlir/unittests/Dialect/Vector/LoadStoreAlignment.cpp
new file mode 100644
index 0000000000000..ae8568f55be82
--- /dev/null
+++ b/mlir/unittests/Dialect/Vector/LoadStoreAlignment.cpp
@@ -0,0 +1,93 @@
+//===- LoadStoreAlignment.cpp - unit tests for load/store alignment -------===//
+//
+// 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 "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Vector/IR/VectorOps.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Verifier.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::vector;
+
+TEST(LoadStoreAlignmentTest, ValidAlignment) {
+ MLIRContext ctx;
+ OpBuilder b(&ctx);
+ ctx.loadDialect<memref::MemRefDialect>();
+ ctx.loadDialect<vector::VectorDialect>();
+
+ // Create a dummy memref
+ Type elementType = b.getI32Type();
+ auto memrefType = MemRefType::get({4}, elementType);
+ Value memref = b.create<memref::AllocaOp>(b.getUnknownLoc(), memrefType);
+
+ VectorType elemVecTy = VectorType::get({2}, elementType);
+
+ // Create load with valid alignment
+ Value zero = b.create<arith::ConstantIndexOp>(b.getUnknownLoc(), 0);
+ auto loadOp = b.create<LoadOp>(b.getUnknownLoc(), elemVecTy, memref,
+ ValueRange{zero}, static_cast<uint64_t>(16));
+
+ // Verify the attribute exists
+ auto alignmentAttr = loadOp->getAttrOfType<IntegerAttr>("alignment");
+ EXPECT_TRUE(alignmentAttr != nullptr);
+ EXPECT_EQ(alignmentAttr.getInt(), 16);
+
+ // Create store with valid alignment
+ auto storeOp = b.create<StoreOp>(b.getUnknownLoc(), loadOp, memref,
+ ValueRange{zero}, static_cast<uint64_t>(16));
+
+ // Verify the attribute exists
+ alignmentAttr = storeOp->getAttrOfType<IntegerAttr>("alignment");
+ EXPECT_TRUE(alignmentAttr != nullptr);
+ EXPECT_EQ(alignmentAttr.getInt(), 16);
+}
+
+TEST(LoadStoreAlignmentTest, InvalidAlignmentFailsVerification) {
+ MLIRContext ctx;
+ OpBuilder b(&ctx);
+ ctx.loadDialect<memref::MemRefDialect>();
+ ctx.loadDialect<vector::VectorDialect>();
+
+ Type elementType = b.getI32Type();
+ auto memrefType = MemRefType::get({4}, elementType);
+ Value memref = b.create<memref::AllocaOp>(b.getUnknownLoc(), memrefType);
+
+ VectorType elemVecTy = VectorType::get({2}, elementType);
+
+ Value zero = b.create<arith::ConstantIndexOp>(b.getUnknownLoc(), 0);
+
+ auto loadOp = b.create<LoadOp>(b.getUnknownLoc(), elemVecTy, memref,
+ ValueRange{zero}, false, -1);
+
+ // Capture diagnostics
+ std::string errorMessage;
+ ScopedDiagnosticHandler handler(
+ &ctx, [&](Diagnostic &diag) { errorMessage = diag.str(); });
+
+ // Trigger verification
+ auto result = mlir::verify(loadOp);
+
+ // Check results
+ EXPECT_TRUE(failed(result));
+ EXPECT_EQ(
+ errorMessage,
+ "'vector.load' op attribute 'alignment' failed to satisfy constraint: "
+ "64-bit signless integer attribute whose minimum value is 0");
+
+ auto storeOp = b.create<StoreOp>(b.getUnknownLoc(), loadOp, memref,
+ ValueRange{zero}, false, -1);
+ result = mlir::verify(storeOp);
+
+ // Check results
+ EXPECT_TRUE(failed(result));
+ EXPECT_EQ(
+ errorMessage,
+ "'vector.store' op attribute 'alignment' failed to satisfy constraint: "
+ "64-bit signless integer attribute whose minimum value is 0");
+}
More information about the Mlir-commits
mailing list