[Mlir-commits] [mlir] b5ef9e2 - [MLIR][XeGPU] Avoid crashing on `gpu.func` missing `gpu.return` (#186330)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Mar 18 08:25:19 PDT 2026


Author: Akimasa Watanuki
Date: 2026-03-19T00:25:13+09:00
New Revision: b5ef9e29c5fe12590e1f966c4af35f98185a175f

URL: https://github.com/llvm/llvm-project/commit/b5ef9e29c5fe12590e1f966c4af35f98185a175f
DIFF: https://github.com/llvm/llvm-project/commit/b5ef9e29c5fe12590e1f966c4af35f98185a175f.diff

LOG: [MLIR][XeGPU] Avoid crashing on `gpu.func` missing `gpu.return` (#186330)

Skip malformed `gpu.func` operations in `MoveFuncBodyToWarpOp`.
This prevents functions without a `gpu.return` terminator from
triggering an assertion.

Add a regression test covering a `gpu.func` missing a return terminator,
and switch the existing unknown-op test to `test.unknown` so the file no
longer needs `--allow-unregistered-dialect`.
While touching the test file, trim a few FileCheck lines that were
asserting printer details instead of the transform behavior.

Fix https://github.com/llvm/llvm-project/issues/186037

Added: 
    

Modified: 
    mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp
    mlir/test/Dialect/XeGPU/move-gpu-func-to-warp-op.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp
index 7e8ad733fa0ee..fdfe48c6cdc12 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp
@@ -162,6 +162,11 @@ struct MoveFuncBodyToWarpOp : public OpRewritePattern<gpu::GPUFuncOp> {
           return isa<gpu::WarpExecuteOnLane0Op>(op);
         }))
       return failure();
+    gpu::ReturnOp origReturnOp = dyn_cast_if_present<gpu::ReturnOp>(
+        gpuFuncOp.getBlocks().back().getTerminator());
+    if (!origReturnOp)
+      return rewriter.notifyMatchFailure(
+          gpuFuncOp, "expected gpu.func terminator to be gpu.return");
     // Create a new function with the same signature and same attributes.
     SmallVector<Type> workgroupAttributionsTypes =
         llvm::map_to_vector(gpuFuncOp.getWorkgroupAttributions(),
@@ -187,12 +192,10 @@ struct MoveFuncBodyToWarpOp : public OpRewritePattern<gpu::GPUFuncOp> {
         newGpuFunc.getArgumentTypes());
     Block &warpBodyBlock = warpOp.getBodyRegion().front();
     // Replace the ReturnOp of the original gpu function with a YieldOp.
-    auto origRetunOp =
-        cast<gpu::ReturnOp>(gpuFuncOp.getBlocks().back().getTerminator());
-    rewriter.setInsertionPointAfter(origRetunOp);
-    gpu::YieldOp::create(rewriter, origRetunOp.getLoc(),
-                         origRetunOp.getOperands());
-    rewriter.eraseOp(origRetunOp);
+    rewriter.setInsertionPointAfter(origReturnOp);
+    gpu::YieldOp::create(rewriter, origReturnOp.getLoc(),
+                         origReturnOp.getOperands());
+    rewriter.eraseOp(origReturnOp);
     // Move the original function body to the WarpExecuteOnLane0Op body.
     rewriter.inlineRegionBefore(gpuFuncOp.getBody(), warpOp.getBodyRegion(),
                                 warpOp.getBodyRegion().begin());

diff  --git a/mlir/test/Dialect/XeGPU/move-gpu-func-to-warp-op.mlir b/mlir/test/Dialect/XeGPU/move-gpu-func-to-warp-op.mlir
index 2780212d2917f..57a26fa4d7a7a 100644
--- a/mlir/test/Dialect/XeGPU/move-gpu-func-to-warp-op.mlir
+++ b/mlir/test/Dialect/XeGPU/move-gpu-func-to-warp-op.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt -xevm-attach-target='chip=pvc' -test-xegpu-move-func-to-warp-op -split-input-file --allow-unregistered-dialect %s | FileCheck %s
+// RUN: mlir-opt -xevm-attach-target='chip=pvc' -test-xegpu-move-func-to-warp-op -split-input-file %s | FileCheck %s
 
 gpu.module @test {
 gpu.func @empty()  {
@@ -6,9 +6,8 @@ gpu.func @empty()  {
 }
 }
 
-// CHECK-LABEL: gpu.func @empty() {
+// CHECK-LABEL: gpu.func @empty()
 // CHECK-NEXT:      gpu.return
-// CHECK-NEXT:  }
 
 // -----
 gpu.module @test {
@@ -27,10 +26,10 @@ gpu.func @gemm(%arg0: memref<8x16xf16>, %arg1: memref<16x16xf16>, %arg2: memref<
 
 // CHECK-LABEL: gpu.func @gemm(
 // CHECK:         %[[ARG0:[a-zA-Z0-9]+]]: memref<8x16xf16>, %[[ARG1:[a-zA-Z0-9]+]]: memref<16x16xf16>,
-// CHECK-SAME:    %[[ARG2:[a-zA-Z0-9]+]]: memref<8x16xf32>) {
+// CHECK-SAME:    %[[ARG2:[a-zA-Z0-9]+]]: memref<8x16xf32>)
 // CHECK:         %[[LANEID:.*]] = gpu.lane_id
 // CHECK-NEXT:    gpu.warp_execute_on_lane_0(%[[LANEID]])[16]
-// CHECK-SAME:      args(%[[ARG0]], %[[ARG1]], %[[ARG2]] : memref<8x16xf16>, memref<16x16xf16>, memref<8x16xf32>) {
+// CHECK-SAME:      args(%[[ARG0]], %[[ARG1]], %[[ARG2]] : memref<8x16xf16>, memref<16x16xf16>, memref<8x16xf32>)
 // CHECK:           ^bb0(%[[ARG3:[a-zA-Z0-9]+]]: memref<8x16xf16>, %[[ARG4:[a-zA-Z0-9]+]]: memref<16x16xf16>,
 // CHECK-SAME:      %[[ARG5:[a-zA-Z0-9]+]]: memref<8x16xf32>):
 // CHECK-NEXT:      %[[T1:.*]] = xegpu.create_nd_tdesc %[[ARG3]] : memref<8x16xf16> -> !xegpu.tensor_desc<8x16xf16>
@@ -40,24 +39,34 @@ gpu.func @gemm(%arg0: memref<8x16xf16>, %arg1: memref<16x16xf16>, %arg2: memref<
 // CHECK-NEXT:      %[[T5:.*]] = xegpu.dpas %[[T3]], %[[T4]] : vector<8x16xf16>, vector<16x16xf16> -> vector<8x16xf32>
 // CHECK-NEXT:      %[[T6:.*]] = xegpu.create_nd_tdesc %[[ARG5]] : memref<8x16xf32> -> !xegpu.tensor_desc<8x16xf32>
 // CHECK-NEXT:      xegpu.store_nd %[[T5]], %[[T6]][%{{.*}}]  : vector<8x16xf32>, !xegpu.tensor_desc<8x16xf32>
-// CHECK-NEXT:    }
-// CHECK-NEXT:    gpu.return
+// CHECK:         gpu.return
 
 // -----
 gpu.module @test {
 gpu.func @already_in_warp_op() {
   %laneid = gpu.lane_id
   gpu.warp_execute_on_lane_0(%laneid)[16] {
-    "some_op"() : () -> ()
+    "test.unknown"() : () -> ()
     gpu.yield
   }
   gpu.return
 }
 }
 
-// CHECK-LABEL: gpu.func @already_in_warp_op() {
+// CHECK-LABEL: gpu.func @already_in_warp_op()
 // CHECK:         %[[LANEID:.*]] = gpu.lane_id
-// CHECK:         gpu.warp_execute_on_lane_0(%[[LANEID]])[16] {
-// CHECK:           "some_op"() : () -> ()
-// CHECK:         }
+// CHECK:         gpu.warp_execute_on_lane_0(%[[LANEID]])[16]
+// CHECK:           "test.unknown"() : () -> ()
 // CHECK:         gpu.return
+
+// -----
+gpu.module @test {
+"gpu.func"() ({
+^bb0:
+  "test.unknown"() : () -> ()
+}) {function_type = () -> (), kernel, sym_name = "missing_return_terminator"} : () -> ()
+}
+
+// Regression test for MoveFuncBodyToWarpOp on malformed generic gpu.func.
+// CHECK-LABEL: gpu.func @missing_return_terminator
+// CHECK-NEXT:    "test.unknown"() : () -> ()


        


More information about the Mlir-commits mailing list