-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ROCDL] Added missing named barrier ops (gfx1250) #162488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-mlir Author: None (ravil-mobile) ChangesThis patch introduces some missing s.barrier instructions in the ROCDL dialect handling named barriers Specifically:
Tests:
cc @krzysz00, @amd-eochoalo Full diff: https://github.com/llvm/llvm-project/pull/162488.diff 3 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td b/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td
index db1b7e3af62fd..7560b61137afc 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td
@@ -292,18 +292,50 @@ def ROCDL_BarrierOp : ROCDL_Op<"barrier"> {
let assemblyFormat = "attr-dict";
}
+def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>;
+
+def ROCDL_BarrierInitOp : ROCDL_IntrOp<"s.barrier.init", [], [], [Pure], 0, 0, 0, 0, [1], ["id"]>,
+ Arguments<(ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr, I32Attr:$id)> {
+ let results = (outs);
+ let assemblyFormat = "$ptr `,` $id attr-dict";
+}
+
def ROCDL_BarrierSignalOp : ROCDL_ConcreteNonMemIntrOp<"s.barrier.signal", [], 0, [0], ["id"]>,
Arguments<(ins I32Attr:$id)> {
let results = (outs);
let assemblyFormat = "$id attr-dict";
}
+def ROCDL_BarrierSignalVarOp : ROCDL_IntrOp<"s.barrier.signal.var", [], [], [Pure], 0, 0, 0, 0, [1], ["id"]>,
+ Arguments<(ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr, I32Attr:$id)> {
+ let results = (outs);
+ let assemblyFormat = "$ptr `,` $id attr-dict";
+}
+
+def ROCDL_BarrierJoinOp : ROCDL_IntrOp<"s.barrier.join", [], [], [Pure], 0>,
+ Arguments<(ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr)> {
+ let results = (outs);
+ let assemblyFormat = "$ptr attr-dict";
+}
+
+def ROCDL_BarrierLeaveOp : ROCDL_ConcreteNonMemIntrOp<"s.barrier.leave", [], 0, [0], ["id"]>,
+ Arguments<(ins I16Attr:$id)> {
+ let results = (outs);
+ let assemblyFormat = "$id attr-dict";
+}
+
def ROCDL_BarrierWaitOp : ROCDL_ConcreteNonMemIntrOp<"s.barrier.wait", [], 0, [0], ["id"]>,
Arguments<(ins I16Attr:$id)> {
let results = (outs);
let assemblyFormat = "$id attr-dict";
}
+def ROCDL_BarrierSignalIsfirstOp : ROCDL_ConcreteNonMemIntrOp<"s.barrier.signal.isfirst", [], 1, [0], ["id"]>,
+ Arguments<(ins I32Attr:$id)> {
+ let results = (outs I1:$res);
+ let assemblyFormat = "$id attr-dict `:` type($res)";
+}
+
def ROCDL_WaitDscntOp: ROCDL_ConcreteNonMemIntrOp<"s.wait.dscnt", [], 0, [0], ["count"]>,
Arguments<(ins I16Attr:$count)> {
let summary = "Wait until DSCNT is less than or equal to `count`";
@@ -497,7 +529,6 @@ def ROCDL_wmma_i32_16x16x32_iu4 : ROCDL_Wmma_IntrOp<"wmma.i32.16x16x32.iu4", [1]
// LDS transpose intrinsics (available in GFX950)
def ROCDLGlobalBuffer : LLVM_PointerInAddressSpace<1>;
-def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>;
class ROCDL_LDS_Read_Tr_IntrOp<string mnemonic> :
ROCDL_IntrOp<mnemonic, [1], [], [], 1, 0, 1> {
diff --git a/mlir/test/Dialect/LLVMIR/rocdl.mlir b/mlir/test/Dialect/LLVMIR/rocdl.mlir
index a88b59aeb61b2..9e13baf77a689 100644
--- a/mlir/test/Dialect/LLVMIR/rocdl.mlir
+++ b/mlir/test/Dialect/LLVMIR/rocdl.mlir
@@ -951,6 +951,13 @@ llvm.func @rocdl.s.barrier() {
llvm.return
}
+llvm.func @rocdl.s.barrier.init(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.init
+ // CHECK: rocdl.s.barrier.init %[[PTR:.+]], 1
+ rocdl.s.barrier.init %ptr, 1
+ llvm.return
+}
+
llvm.func @rocdl.s.barrier.signal() {
// CHECK-LABEL: rocdl.s.barrier.signal
// CHECK: rocdl.s.barrier.signal -1
@@ -958,6 +965,27 @@ llvm.func @rocdl.s.barrier.signal() {
llvm.return
}
+llvm.func @rocdl.s.barrier.signal.var(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.signal.var
+ // CHECK: rocdl.s.barrier.signal.var %[[PTR:.+]], 1
+ rocdl.s.barrier.signal.var %ptr, 1
+ llvm.return
+}
+
+llvm.func @rocdl.s.barrier.join(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.join
+ // CHECK: rocdl.s.barrier.join %[[PTR:.+]]
+ rocdl.s.barrier.join %ptr
+ llvm.return
+}
+
+llvm.func @rocdl.s.barrier.leave() {
+ // CHECK-LABEL: rocdl.s.barrier.leave
+ // CHECK: rocdl.s.barrier.leave 1
+ rocdl.s.barrier.leave 1
+ llvm.return
+}
+
llvm.func @rocdl.s.barrier.wait() {
// CHECK-LABEL: rocdl.s.barrier.wait
// CHECK: rocdl.s.barrier.wait -1
@@ -965,6 +993,13 @@ llvm.func @rocdl.s.barrier.wait() {
llvm.return
}
+llvm.func @rocdl.s.barrier.signal.isfirst() {
+ // CHECK-LABEL: rocdl.s.barrier.signal.isfirst
+ // CHECK: rocdl.s.barrier.signal.isfirst 1
+ %0 = rocdl.s.barrier.signal.isfirst 1 : i1
+ llvm.return
+}
+
llvm.func @rocdl.s.wait.dscnt() {
// CHECK-LABEL: rocdl.s.wait.dscnt
// CHECK: rocdl.s.wait.dscnt 0
diff --git a/mlir/test/Target/LLVMIR/rocdl.mlir b/mlir/test/Target/LLVMIR/rocdl.mlir
index 1c0c2eba002aa..3eb404bcb8a40 100644
--- a/mlir/test/Target/LLVMIR/rocdl.mlir
+++ b/mlir/test/Target/LLVMIR/rocdl.mlir
@@ -192,6 +192,13 @@ llvm.func @rocdl.barrier() {
llvm.return
}
+llvm.func @rocdl.s.barrier.init(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.init
+ // CHECK: call void @llvm.amdgcn.s.barrier.init(ptr addrspace(3) %[[PTR:.+]], i32 1)
+ rocdl.s.barrier.init %ptr, 1
+ llvm.return
+}
+
llvm.func @rocdl.s.barrier.signal() {
// CHECK-LABEL: rocdl.s.barrier.signal
// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -1)
@@ -199,6 +206,27 @@ llvm.func @rocdl.s.barrier.signal() {
llvm.return
}
+llvm.func @rocdl.s.barrier.signal.var(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.signal.var
+ // CHECK: call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) %[[PTR:.+]], i32 1)
+ rocdl.s.barrier.signal.var %ptr, 1
+ llvm.return
+}
+
+llvm.func @rocdl.s.barrier.join(%ptr : !llvm.ptr<3>) {
+ // CHECK-LABEL: rocdl.s.barrier.join
+ // CHECK: call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) %[[PTR:.+]])
+ rocdl.s.barrier.join %ptr
+ llvm.return
+}
+
+llvm.func @rocdl.s.barrier.leave() {
+ // CHECK-LABEL: rocdl.s.barrier.leave
+ // CHECK: call void @llvm.amdgcn.s.barrier.leave(i16 1)
+ rocdl.s.barrier.leave 1
+ llvm.return
+}
+
llvm.func @rocdl.s.barrier.wait() {
// CHECK-LABEL: rocdl.s.barrier.wait
// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -1)
@@ -206,6 +234,13 @@ llvm.func @rocdl.s.barrier.wait() {
llvm.return
}
+llvm.func @rocdl.s.barrier.signal.isfirst() {
+ // CHECK-LABEL: rocdl.s.barrier.signal.isfirst
+ // CHECK: %[[OUT:.+]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 1)
+ %0 = rocdl.s.barrier.signal.isfirst 1 : i1
+ llvm.return
+}
+
llvm.func @rocdl.s.wait.dscnt() {
// CHECK-LABEL: rocdl.s.wait.dscnt
// CHECK-NEXT: call void @llvm.amdgcn.s.wait.dscnt(i16 0)
|
5ea786d
to
5135c4f
Compare
@@ -292,18 +292,56 @@ def ROCDL_BarrierOp : ROCDL_Op<"barrier"> { | |||
let assemblyFormat = "attr-dict"; | |||
} | |||
|
|||
def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>; | |||
|
|||
def ROCDL_BarrierInitOp : ROCDL_IntrOp<"s.barrier.init", [], [], [Pure], 0, 0, 0, 0, [1], ["id"]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this pure? I don't see any results returned by this op
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think this is pure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... Heck, the LLVM has IntrHasSideEffects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah should not be pure. this op does not have a return value so it will get eliminated if it is pure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Removed the trait. As I can see there is not HasSideEffect
trait in MLIR. So, I left the list of traits empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add description
s saying which gfxip version introduced these? Example: https://github.com/ravil-mobile/llvm-project/blob/5135c4fdae71ef27192ec190298f3a00ba85ae64/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td#L1043-L1045
} | ||
|
||
def ROCDL_BarrierJoinOp : ROCDL_IntrOp<"s.barrier.join", [], [], [Pure], 0>, | ||
Arguments<(ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr)> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary to mark this as MemRed
- the LLVM intrinsics are marked NoMem
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. You are right. All this functions are marked with IntrNoMem
trait in LLVM. Removed it
All LLVM intrinsics added in this op have property |
def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>; | ||
|
||
def ROCDL_BarrierInitOp : ROCDL_IntrOp<"s.barrier.init", [], [], [Pure], 0, 0, 0, 0, [1], ["id"]>, | ||
Arguments<(ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr, I32Attr:$id)> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See: https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/AMDGPU/s-barrier.ll#L83
so the s_barrier_init
takes a single m0
so it should not read mem.
Same is signal.var
, join
.
The discrepancy here being: barriers need to be defined as a global variable at the LLVM IR level. |
5135c4f
to
41c84bc
Compare
Done |
just want to make sure: do you know if on the rocdl level, is there any way we can declare a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall lgtm
@lialan To answer your question, the declarations I see in tests for these named barriers are
So, at the MLIR level, you just need a (No, I don't know what the So future work will be adding |
@krzysz00 Yeah I do not see the wrapper for type |
@lialan You don't need such a wrapper, just use (We can add a wrapper to AMDGPU, but we don't need one in |
This patch introduces some missing s.barrier instructions in the ROCDL dialect handling named barriers
Specifically:
Tests:
cc @krzysz00, @amd-eochoalo