[Mlir-commits] [mlir] [mlir][MemRef] Add guard, only pass for int or float (PR #206692)
Daniel Christian Mandolang
llvmlistbot at llvm.org
Tue Jun 30 02:51:41 PDT 2026
https://github.com/danielcm585 created https://github.com/llvm/llvm-project/pull/206692
Several conversion patterns in `EmulateNarrowType.cpp` call `getIntOrFloatBitWidth()` on memref element types without first checking that the type is actually an integer or float. When a memref has a non-scalar element type such as `memref<vector<[2]x2xi1>>`, the element type extracted via `getElementType()` is a vector type, which causes an assertion failure:
```
mlir::Type::getIntOrFloatBitWidth() const:
Assertion 'isIntOrFloat() && "only integers and floats have a bitwidth"' failed```
The type converter registered in populateMemRefNarrowTypeEmulationConversions already guards against this case — it checks !elementType.isIntOrFloat() and returns the type unchanged. However, the conversion patterns themselves lacked the corresponding guard, so they would proceed to call getIntOrFloatBitWidth() on the unconverted (non-scalar) element type and crash.
This patch adds `isIntOrFloat()` checks before `getIntOrFloatBitWidth()` calls in four patterns:
- `convertCastingOp` (used by `ReinterpretCastOp`)
- `ConvertMemRefAllocation` (used by `AllocaOp`/`AllocOp`)
- `ConvertMemRefLoad` (used by `LoadOp`)
- `ConvertMemRefSubview` (used by `SubViewOp`)
>From 6649ec90bce4c836dc99cc338937d8fab45f4848 Mon Sep 17 00:00:00 2001
From: danielcm585 <danielchristianmandolang at gmail.com>
Date: Tue, 30 Jun 2026 17:47:47 +0800
Subject: [PATCH] [mlir] Add guard, only pass for int or float
---
.../Dialect/MemRef/Transforms/EmulateNarrowType.cpp | 13 +++++++++++++
mlir/test/Transforms/emulate-narrow-int-vector.mlir | 10 ++++++++++
2 files changed, 23 insertions(+)
create mode 100644 mlir/test/Transforms/emulate-narrow-int-vector.mlir
diff --git a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp
index a11e14faa5475..d31572e71fc9a 100644
--- a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp
+++ b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp
@@ -50,6 +50,9 @@ convertCastingOp(ConversionPatternRewriter &rewriter,
Type convertedElementType = newTy.getElementType();
Type oldElementType = op.getType().getElementType();
+ if (!oldElementType.isIntOrFloat() || !convertedElementType.isIntOrFloat())
+ return rewriter.notifyMatchFailure(
+ op, "only integer or float element types are supported");
int srcBits = oldElementType.getIntOrFloatBitWidth();
int dstBits = convertedElementType.getIntOrFloatBitWidth();
if (dstBits % srcBits != 0) {
@@ -234,6 +237,10 @@ struct ConvertMemRefAllocation final : OpConversionPattern<OpTy> {
OpFoldResult zero = rewriter.getIndexAttr(0);
// Get linearized type.
+ if (!currentType.getElementType().isIntOrFloat() ||
+ !newResultType.getElementType().isIntOrFloat())
+ return rewriter.notifyMatchFailure(
+ op, "only integer or float element types are supported");
int srcBits = currentType.getElementType().getIntOrFloatBitWidth();
int dstBits = newResultType.getElementType().getIntOrFloatBitWidth();
SmallVector<OpFoldResult> sizes = op.getMixedSizes();
@@ -331,6 +338,9 @@ struct ConvertMemRefLoad final : OpConversionPattern<memref::LoadOp> {
auto convertedType = cast<MemRefType>(adaptor.getMemref().getType());
auto convertedElementType = convertedType.getElementType();
auto oldElementType = op.getMemRefType().getElementType();
+ if (!oldElementType.isIntOrFloat() || !convertedElementType.isIntOrFloat())
+ return rewriter.notifyMatchFailure(
+ op, "only integer or float element types are supported");
int srcBits = oldElementType.getIntOrFloatBitWidth();
int dstBits = convertedElementType.getIntOrFloatBitWidth();
if (dstBits % srcBits != 0) {
@@ -601,6 +611,9 @@ struct ConvertMemRefSubview final : OpConversionPattern<memref::SubViewOp> {
Location loc = subViewOp.getLoc();
Type convertedElementType = newTy.getElementType();
Type oldElementType = subViewOp.getType().getElementType();
+ if (!oldElementType.isIntOrFloat() || !convertedElementType.isIntOrFloat())
+ return rewriter.notifyMatchFailure(
+ subViewOp, "only integer or float element types are supported");
int srcBits = oldElementType.getIntOrFloatBitWidth();
int dstBits = convertedElementType.getIntOrFloatBitWidth();
if (dstBits % srcBits != 0)
diff --git a/mlir/test/Transforms/emulate-narrow-int-vector.mlir b/mlir/test/Transforms/emulate-narrow-int-vector.mlir
new file mode 100644
index 0000000000000..e2e987422d8e7
--- /dev/null
+++ b/mlir/test/Transforms/emulate-narrow-int-vector.mlir
@@ -0,0 +1,10 @@
+// RUN: mlir-opt --test-emulate-narrow-int --verify-diagnostics %s
+
+module {
+ func.func @test() {
+ %alloca = memref.alloca() : memref<vector<[2]x2xi1>>
+ // expected-error @+1 {{failed to legalize operation 'memref.load'}}
+ %val = memref.load %alloca[] : memref<vector<[2]x2xi1>>
+ return
+ }
+}
\ No newline at end of file
More information about the Mlir-commits
mailing list