[Mlir-commits] [mlir] [XeGPU] Handle scf.while result types from scf.condition (PR #202931)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jun 10 04:08:18 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-gpu
Author: woruyu (woruyu)
<details>
<summary>Changes</summary>
### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/202797. XeGPU blocking updates SCF structural op result types after converting vectors through tensor types with layout encodings. The existing code used scf.yield operands as the source for parent op result types, which is not valid for scf.while.
For scf.while, parent results correspond to the operands of scf.condition in the before region. The after-region scf.yield operands are loop-carried values for the next iteration and may have a different count, including zero. Skip scf.while in the scf.yield walk and update its result types from scf.condition instead.
This avoids crashing on while ops with results but no yield operands.
---
Full diff: https://github.com/llvm/llvm-project/pull/202931.diff
2 Files Affected:
- (modified) mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp (+19)
- (modified) mlir/test/Dialect/XeGPU/xegpu-blocking.mlir (+16)
``````````diff
diff --git a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
index 0fb0ac6e3416d..0fdd16287eec8 100644
--- a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
+++ b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
@@ -526,9 +526,28 @@ void xegpu::doSCFStructuralTypeConversionWithTensorType(
return WalkResult::advance();
});
+ // For scf.while, the parent op results correspond to scf.condition
+ // operands, not to the after-region scf.yield operands.
+ op->walk([](scf::ConditionOp conditionOp) {
+ auto whileOp = dyn_cast<scf::WhileOp>(conditionOp->getParentOp());
+ if (!whileOp)
+ return;
+
+ ValueRange args = conditionOp.getArgs();
+ for (OpResult r : whileOp->getOpResults()) {
+ unsigned idx = r.getResultNumber();
+ Type resultTy = r.getType();
+ Type conditionTy = args[idx].getType();
+ if (isa<RankedTensorType>(resultTy) && conditionTy != resultTy)
+ r.setType(conditionTy);
+ }
+ });
+
// using yieldOp as anchor to update the result type of its ParentOp
op->walk([](scf::YieldOp yieldOp) {
Operation *parentOp = yieldOp->getParentOp();
+ if (isa<scf::WhileOp>(parentOp))
+ return;
for (OpResult r : parentOp->getOpResults()) {
unsigned idx = r.getResultNumber();
Type resultTy = r.getType();
diff --git a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
index c0ea112edc818..18c0751c036e1 100644
--- a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
+++ b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
@@ -1,5 +1,21 @@
// RUN: mlir-opt --xegpu-blocking -split-input-file %s | FileCheck %s
+// CHECK-LABEL: func.func @while_results_without_iter_args
+func.func @while_results_without_iter_args() -> i32 {
+ %c0_i32 = arith.constant 0 : i32
+ %c0_i64 = arith.constant 0 : i64
+ %true = arith.constant true
+ %0:2 = scf.while : () -> (i32, i64) {
+ scf.condition(%true) %c0_i32, %c0_i64 : i32, i64
+ } do {
+ ^bb0(%arg0: i32, %arg1: i64):
+ scf.yield
+ }
+ return %0#0 : i32
+}
+
+// -----
+
#a = #xegpu.layout<inst_data = [8, 16], lane_layout = [1, 16], lane_data = [8, 1]>
#b = #xegpu.layout<inst_data = [16, 16], lane_layout = [1, 16], lane_data = [16, 1]>
#c = #xegpu.layout<inst_data = [8, 16], lane_layout = [1, 16], lane_data = [8, 1]>
``````````
</details>
https://github.com/llvm/llvm-project/pull/202931
More information about the Mlir-commits
mailing list