[Mlir-commits] [mlir] [mlir][SCFToEmitC] Fix crash when scf.while carries a memref loop variable (PR #183944)

Mehdi Amini llvmlistbot at llvm.org
Sat Feb 28 12:13:37 PST 2026


https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/183944

When a scf.while op has a loop-carried value whose type converts to emitc::ArrayType (e.g. memref<1xf64>), the WhileLowering pattern unconditionally called emitc::LValueType::get(arrayType), which triggered an assertion because LValueType cannot wrap an array type.

Fix by returning a match failure in createVariablesForResults and createVariablesForLoopCarriedValues when the converted type is an emitc::ArrayType. This converts the crash into a proper legalization failure.

Fixes #182649

>From 7a3fba4ce3a994d69103fd9e4a80eb0ce71e0ce4 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Sat, 28 Feb 2026 09:19:07 -0800
Subject: [PATCH] [mlir][SCFToEmitC] Fix crash when scf.while carries a memref
 loop variable

When a scf.while op has a loop-carried value whose type converts to
emitc::ArrayType (e.g. memref<1xf64>), the WhileLowering pattern
unconditionally called emitc::LValueType::get(arrayType), which
triggered an assertion because LValueType cannot wrap an array type.

Fix by returning a match failure in createVariablesForResults and
createVariablesForLoopCarriedValues when the converted type is an
emitc::ArrayType. This converts the crash into a proper legalization
failure.

Fixes #182649
---
 mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp |  7 ++++++
 .../SCFToEmitC/scf-to-emitc-failed.mlir       | 24 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
index 71e3f88a63f34..07feba7e565d9 100644
--- a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
+++ b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
@@ -89,6 +89,9 @@ createVariablesForResults(T op, const TypeConverter *typeConverter,
     Type resultType = typeConverter->convertType(result.getType());
     if (!resultType)
       return rewriter.notifyMatchFailure(op, "result type conversion failed");
+    if (isa<emitc::ArrayType>(resultType))
+      return rewriter.notifyMatchFailure(
+          op, "cannot create variable for result of array type");
     Type varType = emitc::LValueType::get(resultType);
     emitc::OpaqueAttr noInit = emitc::OpaqueAttr::get(context, "");
     emitc::VariableOp var =
@@ -393,6 +396,10 @@ struct WhileLowering : public OpConversionPattern<WhileOp> {
       Type convertedType = getTypeConverter()->convertType(init.getType());
       if (!convertedType)
         return rewriter.notifyMatchFailure(whileOp, "type conversion failed");
+      if (isa<emitc::ArrayType>(convertedType))
+        return rewriter.notifyMatchFailure(
+            whileOp,
+            "cannot create variable for loop-carried value of array type");
 
       auto var = emitc::VariableOp::create(
           rewriter, loc, emitc::LValueType::get(convertedType), noInit);
diff --git a/mlir/test/Conversion/SCFToEmitC/scf-to-emitc-failed.mlir b/mlir/test/Conversion/SCFToEmitC/scf-to-emitc-failed.mlir
index 02c27deaa7a13..7f226c51323d8 100644
--- a/mlir/test/Conversion/SCFToEmitC/scf-to-emitc-failed.mlir
+++ b/mlir/test/Conversion/SCFToEmitC/scf-to-emitc-failed.mlir
@@ -8,3 +8,27 @@ func.func @unsupported_type_vector(%arg0 : index, %arg1 : index, %arg2 : index)
   }
   return %r : vector<3xindex>
 }
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/182649
+// scf.while with a memref loop-carried value (which converts to emitc.array)
+// must fail gracefully rather than crashing with an assertion.
+
+func.func @while_with_memref_carried(%n: index) {
+  %c0 = arith.constant 0 : index
+  %zero_f64 = arith.constant 0.0 : f64
+  %buf = memref.alloca() : memref<1xf64>
+  memref.store %zero_f64, %buf[%c0] : memref<1xf64>
+  // expected-error at +1 {{failed to legalize operation 'scf.while'}}
+  scf.while (%i = %c0, %acc = %buf) : (index, memref<1xf64>) -> (index, memref<1xf64>) {
+    %cond = arith.cmpi slt, %i, %n : index
+    scf.condition(%cond) %i, %acc : index, memref<1xf64>
+  } do {
+    ^bb0(%i: index, %acc: memref<1xf64>):
+    %c1 = arith.constant 1 : index
+    %next_i = arith.addi %i, %c1 : index
+    scf.yield %next_i, %acc : index, memref<1xf64>
+  }
+  return
+}



More information about the Mlir-commits mailing list