[Mlir-commits] [mlir] dc520a5 - [mlir][GPU] Add ValueBoundsOphinterface to gpu.subgroup_broadcast (#183848)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Feb 27 15:47:00 PST 2026


Author: Krzysztof Drewniak
Date: 2026-02-27T15:46:56-08:00
New Revision: dc520a5f493aac270315304be10b9b8bc5119dfe

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

LOG: [mlir][GPU] Add  ValueBoundsOphinterface to gpu.subgroup_broadcast (#183848)

This commit adds an ValueBoundsOpInterface to gpu.subgroup_broadcast,
matching its integer range interface implementation, so that affine
analysis can peek through subgroup broadcast ops.

Added: 
    

Modified: 
    mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
    mlir/lib/Dialect/GPU/IR/ValueBoundsOpInterfaceImpl.cpp
    mlir/test/Dialect/GPU/value-bounds-op-interface-impl.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
index a66a83b7e3ca1..d347cda64a9f0 100644
--- a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
+++ b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
@@ -283,10 +283,11 @@ void GPUDialect::initialize() {
   addInterfaces<GPUInlinerInterface>();
   declarePromisedInterface<bufferization::BufferDeallocationOpInterface,
                            TerminatorOp>();
-  declarePromisedInterfaces<
-      ValueBoundsOpInterface, ClusterDimOp, ClusterDimBlocksOp, ClusterIdOp,
-      ClusterBlockIdOp, BlockDimOp, BlockIdOp, GridDimOp, ThreadIdOp, LaneIdOp,
-      SubgroupIdOp, GlobalIdOp, NumSubgroupsOp, SubgroupSizeOp, LaunchOp>();
+  declarePromisedInterfaces<ValueBoundsOpInterface, ClusterDimOp,
+                            ClusterDimBlocksOp, ClusterIdOp, ClusterBlockIdOp,
+                            BlockDimOp, BlockIdOp, GridDimOp, ThreadIdOp,
+                            LaneIdOp, SubgroupIdOp, GlobalIdOp, NumSubgroupsOp,
+                            SubgroupSizeOp, LaunchOp, SubgroupBroadcastOp>();
 }
 
 static std::string getSparseHandleKeyword(SparseHandleKind kind) {

diff  --git a/mlir/lib/Dialect/GPU/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/GPU/IR/ValueBoundsOpInterfaceImpl.cpp
index 3bb7082daa5a0..c978aefe3f655 100644
--- a/mlir/lib/Dialect/GPU/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/GPU/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -40,6 +40,28 @@ struct GpuIdOpInterface
   }
 };
 
+/// Implement ValueBoundsOpInterface on subgroup broadcast operations to
+/// indicate that such a broadcast does not modify the ranges of the values in
+/// question. Handles shaped types just in case one wants to broadcast a memref
+/// descriptor.
+struct SubgroupBroadcastOpInterface
+    : public ValueBoundsOpInterface::ExternalModel<SubgroupBroadcastOpInterface,
+                                                   SubgroupBroadcastOp> {
+  void populateBoundsForIndexValue(Operation *op, Value value,
+                                   ValueBoundsConstraintSet &cstr) const {
+    auto broadcastOp = cast<SubgroupBroadcastOp>(op);
+    assert(value == broadcastOp.getResult() && "invalid value");
+    cstr.bound(value) == cstr.getExpr(broadcastOp.getSrc());
+  }
+
+  void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
+                                       ValueBoundsConstraintSet &cstr) const {
+    auto broadcastOp = cast<SubgroupBroadcastOp>(op);
+    assert(value == broadcastOp.getResult() && "invalid value");
+    cstr.bound(value)[dim] == cstr.getExpr(broadcastOp.getSrc(), dim);
+  }
+};
+
 struct GpuLaunchOpInterface
     : public ValueBoundsOpInterface::ExternalModel<GpuLaunchOpInterface,
                                                    LaunchOp> {
@@ -110,5 +132,6 @@ void mlir::gpu::registerValueBoundsOpInterfaceExternalModels(
 #undef REGISTER
 
     LaunchOp::attachInterface<GpuLaunchOpInterface>(*ctx);
+    SubgroupBroadcastOp::attachInterface<SubgroupBroadcastOpInterface>(*ctx);
   });
 }

diff  --git a/mlir/test/Dialect/GPU/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/GPU/value-bounds-op-interface-impl.mlir
index 6facf1e22aab9..d6a2e17e19704 100644
--- a/mlir/test/Dialect/GPU/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/GPU/value-bounds-op-interface-impl.mlir
@@ -157,3 +157,41 @@ module attributes {gpu.container_module} {
     }
   }
 }
+
+// -----
+
+// CHECK-LABEL: func @subgroup_broadcast
+module attributes {gpu.container_module} {
+  gpu.module @gpu_module {
+    gpu.func @subgroup_broadcast(%arg0 : index) kernel {
+      %lane = arith.constant 1 : i32
+
+      %bcast = gpu.subgroup_broadcast %arg0, specific_lane %lane : index
+      // expected-remark @below{{true}}
+      "test.compare"(%bcast, %arg0) {cmp = "EQ"} : (index, index) -> ()
+
+      %bcast2 = gpu.subgroup_broadcast %arg0, first_active_lane : index
+      // expected-remark @below{{true}}
+      "test.compare"(%bcast2, %arg0) {cmp = "EQ"} : (index, index) -> ()
+      gpu.return
+    }
+  }
+}
+
+// -----
+
+// CHECK-LABEL: func @subgroup_broadcast_shaped
+module attributes {gpu.container_module} {
+  gpu.module @gpu_module {
+    gpu.func @subgroup_broadcast_shaped(%arg0 : memref<?xf32>) kernel {
+      %c0 = arith.constant 0 : index
+
+      %bcast = gpu.subgroup_broadcast %arg0, first_active_lane : memref<?xf32>
+      %bdim = memref.dim %bcast, %c0 : memref<?xf32>
+      %dim = memref.dim %arg0, %c0 : memref<?xf32>
+      // expected-remark @below{{true}}
+      "test.compare"(%bdim, %dim) {cmp = "EQ"} : (index, index) -> ()
+      gpu.return
+    }
+  }
+}


        


More information about the Mlir-commits mailing list