[Mlir-commits] [mlir] [mlir][gpu] Add `gpu.subgroup_uniform` op (PR #157743)
Mehdi Amini
llvmlistbot at llvm.org
Fri Sep 12 06:17:10 PDT 2025
================
@@ -3255,4 +3255,37 @@ def GPU_SubgroupBroadcastOp : GPU_Op<"subgroup_broadcast",
let hasVerifier = 1;
}
+def GPU_SubgroupUniformOp : GPU_Op<"subgroup_uniform",
+ [Pure, AllTypesMatch<["result", "src"]>,
+ DeclareOpInterfaceMethods<InferIntRangeInterface, ["inferResultRanges"]>] #
+ ElementwiseMappable.traits>,
+ Arguments<(ins AnyType:$src)> {
+ let summary = "Assumes value is unform across the lanes in subgroup";
+ let description = [{
+ The "subgroup_uniform" op assumes that the value is uniform across all lanes
+ in a subgroup. This means that all active lanes in the subgroup are expected
+ to have the same value.
+
+ This op can be used to inform the compiler that a value is uniform across
+ the subgroup, enabling optimizations. The result is poison if the value
+ is not actually uniform.
+
+ This op is functionally no-op as no valid program should change its
+ semantics if this op is removed. Backends can choose to ignore it or do
+ some optimizations (e.g. put value into scalar registers).
+
+ This op can be freely speculated across structured control flow as parent
+ active mask is always superset of current mask and if can hoist input
+ calculation you can hoist the operation itself as well.
+
+ Example:
+
+ ```mlir
+ %1 = gpu.subgroup_uniform %0 : f32
+ ```
+ }];
+ let results = (outs AnyType:$result);
+ let assemblyFormat = "$src attr-dict `:` type($result)";
+}
----------------
joker-eph wrote:
>I argue that assume semantics imply things about the operands, not the results. This works well with dataflow, the semantics are clear
I don't see the argument here? You seem to be repeatingly making claims that I don't understand the rationale behind and I don't see much explanation on the fundamentals behind it.
> and it is the model of llvm.assume.
Actually no: `llvm.assume` is **not** dataflow based, it a path-sensitive representation. You want to add information about a condition at a specific point, which is at-odd with the properties you'd want from a "dataflow based" approach.
> . I claim these are not really compiler assumptions
How so? We encode an assumption on a value, I don't quite see why this makes it "not a compiler assumption". You're identifying yourself later that the operation is a "nop": it's only effect is on the compiler itself, as a metadata that is inserted in the dataflow.
> On the other hand, on 1, I don't think one should combine them.
Right, one probably shouldn't: the assumption is dataflow based instead of path-based.
This is in line with the deferred UB provided by poison here.
You could be smart and combine some of these **if** you reach a point where you're using a value in a context where it creates UB to violate the assumption.
Basically from a:
```
%1 = memref.assume_alignment %0, 8 : memref<4x4xf16>
```
which isn't an immediate UB when violated, you can generate later:
```
memref.assume_alignment %0, 32 : memref<4x4xf16>
```
at a point where %1 is used in a manner that triggers UB.
This dataflow vs path sensitivity, alongside with deferred UB is pretty key to understand the design space hre.
https://github.com/llvm/llvm-project/pull/157743
More information about the Mlir-commits
mailing list