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

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sat Feb 28 12:14:09 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-emitc

Author: Mehdi Amini (joker-eph)

<details>
<summary>Changes</summary>

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

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


2 Files Affected:

- (modified) mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp (+7) 
- (modified) mlir/test/Conversion/SCFToEmitC/scf-to-emitc-failed.mlir (+24) 


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

``````````

</details>


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


More information about the Mlir-commits mailing list