[Mlir-commits] [mlir] [mlir][MemRef] Add guard, only pass for int or float (PR #206692)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jun 30 02:52:23 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-memref

Author: Daniel Christian Mandolang (danielcm585)

<details>
<summary>Changes</summary>

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`)


---
Full diff: https://github.com/llvm/llvm-project/pull/206692.diff


2 Files Affected:

- (modified) mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp (+13) 
- (added) mlir/test/Transforms/emulate-narrow-int-vector.mlir (+10) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/206692


More information about the Mlir-commits mailing list