[Mlir-commits] [mlir] [mlir][gpu] Sink integer arithmetic into gpu.launch (PR #221462)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Sep 5 09:18:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Hamza Qureshi (hamzaqureshi5)
<details>
<summary>Changes</summary>
isLikelyAnIndexComputation() accepted constants, memref.dim, arith.select and arith.cmpi, but not integer arithmetic. An index computation such as arith.addi feeding a gpu.launch was left outside as kernel argument, even though it is cheap to recompute inside the kernel. Add arith.addi, arith.subi and arith.muli.
Fixes #<!-- -->221396
---
Full diff: https://github.com/llvm/llvm-project/pull/221462.diff
2 Files Affected:
- (modified) mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp (+7-1)
- (modified) mlir/test/Dialect/GPU/sink-ops.mlir (+29)
``````````diff
diff --git a/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp b/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
index 0ee3d425f66be..79c623edb7456 100644
--- a/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
+++ b/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
@@ -72,9 +72,15 @@ static void injectGpuIndexOperations(Location loc, Region &launchFuncOpBody,
/// Identifies operations that are beneficial to sink into kernels. These
/// operations may not have side-effects, as otherwise sinking (and hence
/// duplicating them) is not legal.
+///
+/// Sinking duplicates an operation into every thread, so only operations that
+/// are cheap to recompute are considered. Simple integer arithmetic is in the
+/// same cost class as the comparisons and selects already handled here, and
+/// sinking it avoids passing the result as an additional kernel argument.
static bool isLikelyAnIndexComputation(Operation *op) {
return matchPattern(op, m_Constant()) ||
- isa<memref::DimOp, arith::SelectOp, arith::CmpIOp>(op);
+ isa<memref::DimOp, arith::SelectOp, arith::CmpIOp, arith::AddIOp,
+ arith::SubIOp, arith::MulIOp>(op);
}
/// For a given operation `op`, computes whether it is beneficial to sink the
diff --git a/mlir/test/Dialect/GPU/sink-ops.mlir b/mlir/test/Dialect/GPU/sink-ops.mlir
index 8f5924f2e3265..41c251c13dc88 100644
--- a/mlir/test/Dialect/GPU/sink-ops.mlir
+++ b/mlir/test/Dialect/GPU/sink-ops.mlir
@@ -98,3 +98,32 @@ func.func @multiple_uses2(%arg0 : memref<*xf32>) {
}
return
}
+
+// -----
+
+// Integer arithmetic feeding the launch is recomputed inside it, so that the
+// value does not have to be passed in as a kernel argument.
+
+// CHECK-LABEL: @index_arithmetic
+// CHECK-SAME: %[[ARG0:.*]]: index
+func.func @index_arithmetic(%arg0: index) {
+ %c1 = arith.constant 1 : index
+ %sum = arith.addi %arg0, %c1 : index
+ %diff = arith.subi %arg0, %c1 : index
+ %prod = arith.muli %arg0, %c1 : index
+ // CHECK: gpu.launch blocks
+ gpu.launch blocks(%bx, %by, %bz) in (%grid_x = %c1, %grid_y = %c1,
+ %grid_z = %c1)
+ threads(%tx, %ty, %tz) in (%block_x = %c1, %block_y = %c1,
+ %block_z = %c1) {
+ // CHECK: %[[C1:.*]] = arith.constant 1 : index
+ // CHECK-NEXT: %[[SUM:.*]] = arith.addi %[[ARG0]], %[[C1]]
+ // CHECK-NEXT: %[[DIFF:.*]] = arith.subi %[[ARG0]], %[[C1]]
+ // CHECK-NEXT: %[[PROD:.*]] = arith.muli %[[ARG0]], %[[C1]]
+ // CHECK-NEXT: "use"(%[[ARG0]], %[[SUM]], %[[DIFF]], %[[PROD]])
+ // CHECK-NEXT: gpu.terminator
+ "use"(%arg0, %sum, %diff, %prod) : (index, index, index, index) -> ()
+ gpu.terminator
+ }
+ return
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/221462
More information about the Mlir-commits
mailing list