[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