[Mlir-commits] [mlir] [mlir][scf] fix loop specialization crash when an scf.for result is used (PR #236046)

Prashanth T llvmlistbot at llvm.org
Sat Oct 31 18:44:06 PDT 2026


================
@@ -103,9 +103,19 @@ static void specializeForLoopForUnrolling(ForOp op) {
   Value cond = arith::CmpIOp::create(b, op.getLoc(), arith::CmpIPredicate::eq,
                                      bound, constant);
   map.map(bound, constant);
-  auto ifOp = scf::IfOp::create(b, op.getLoc(), cond, /*withElseRegion=*/true);
-  ifOp.getThenBodyBuilder().clone(*op.getOperation(), map);
-  ifOp.getElseBodyBuilder().clone(*op.getOperation());
+  auto ifOp = scf::IfOp::create(b, op.getLoc(), op->getResultTypes(), cond,
+                                /*withElseRegion=*/true);
+
+  OpBuilder thenB = ifOp.getThenBodyBuilder();
+  Operation *thenLoop = thenB.clone(*op.getOperation(), map);
+  OpBuilder elseB = ifOp.getElseBodyBuilder();
+  Operation *elseLoop = elseB.clone(*op.getOperation());
+
+  if (op->getNumResults() > 0) {
+    scf::YieldOp::create(thenB, op.getLoc(), thenLoop->getResults());
----------------
StarOne01 wrote:

`IfOp::create` doesn't create a `scf.yield` op when we give it the result types (https://github.com/llvm/llvm-project/commit/1125c5c0b2cf13aa112a7531eb89fd1b771aa13b), we clone the `scf.for` op with a condition, the `scf.yield` inside the loop is from the program and the new `yield` outside the loop is for result assignment.

when we don't have a result, the builder auto inserts one, without the guard we are looking at two `scf.yield` which the verifier rejects since one isn't the last operation.

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


More information about the Mlir-commits mailing list