[llvm] [DXIL] Add GroupMemoryBarrierWithGroupSync intrinsic (PR #111884)
Adam Yang via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 28 14:46:26 PDT 2024
https://github.com/adam-yang updated https://github.com/llvm/llvm-project/pull/111884
>From 9ccd90704d1a6c7b7141907f37dc7f87ac921c14 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 8 Oct 2024 00:53:11 -0700
Subject: [PATCH 01/15] Added GroupMemoryBarrierWithGroupSync intrinsic for
DXIL
---
llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 ++
llvm/lib/Target/DirectX/DXIL.td | 9 ++++++
llvm/lib/Target/DirectX/DXILConstants.h | 7 +++++
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 31 +++++++++++++++++++
.../GroupMemoryBarrierWithGroupSync.ll | 8 +++++
5 files changed, 57 insertions(+)
create mode 100644 llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index e30d37f69f781e..015cc0ddab4026 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -92,4 +92,6 @@ def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, L
def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_dx_groupMemoryBarrierWithGroupSync : DefaultAttrsIntrinsic<[], [], []>;
}
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 147b32b1ca9903..c5fb6428e63233 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -277,6 +277,7 @@ def IsFeedback : DXILAttribute;
def IsWave : DXILAttribute;
def NeedsUniformInputs : DXILAttribute;
def IsBarrier : DXILAttribute;
+def NoDuplicate : DXILAttribute;
class Overloads<Version ver, list<DXILOpParamType> ols> {
Version dxil_version = ver;
@@ -820,3 +821,11 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
let stages = [Stages<DXIL1_0, [all_stages]>];
let attributes = [Attributes<DXIL1_0, [ReadNone]>];
}
+
+def Barrier : DXILOp<80, barrier> {
+ let Doc = "inserts a memory barrier in the shader";
+ let arguments = [Int32Ty];
+ let result = VoidTy;
+ let stages = [Stages<DXIL1_0, [compute, library]>];
+ let attributes = [Attributes<DXIL1_0, [NoDuplicate]>];
+}
diff --git a/llvm/lib/Target/DirectX/DXILConstants.h b/llvm/lib/Target/DirectX/DXILConstants.h
index 022cd57795a063..38984727761bb3 100644
--- a/llvm/lib/Target/DirectX/DXILConstants.h
+++ b/llvm/lib/Target/DirectX/DXILConstants.h
@@ -30,6 +30,13 @@ enum class OpParamType : unsigned {
#include "DXILOperation.inc"
};
+enum class BarrierMode : unsigned {
+ SyncThreadGroup = 0x00000001,
+ UAVFenceGlobal = 0x00000002,
+ UAVFenceThreadGroup = 0x00000004,
+ TGSMFence = 0x00000008,
+};
+
} // namespace dxil
} // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index c62ba8c21d6791..fa49d8bbe0340a 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -209,6 +209,34 @@ class OpLowerer {
});
}
+ [[nodiscard]] bool lowerBarrier(Function& F, Intrinsic::ID IntrId) {
+ IRBuilder<> &IRB = OpBuilder.getIRB();
+ return replaceFunction(F, [&](CallInst *CI) -> Error {
+ unsigned BarrierMode = 0;
+ switch (IntrId) {
+ default:
+ report_fatal_error("Unhandled barrier operation type.");
+ break;
+ case Intrinsic::dx_groupMemoryBarrierWithGroupSync:
+ BarrierMode = (unsigned)dxil::BarrierMode::TGSMFence | (unsigned)dxil::BarrierMode::SyncThreadGroup;
+ break;
+ }
+
+ std::array<Value *, 1> Args{IRB.getInt32(BarrierMode)};
+
+ IRB.SetInsertPoint(CI);
+ Expected<CallInst *> OpCall =
+ OpBuilder.tryCreateOp(OpCode::Barrier, Args, CI->getName());
+ if (Error E = OpCall.takeError())
+ return E;
+
+ CI->replaceAllUsesWith(OpCall.get());
+ CI->eraseFromParent();
+
+ return Error::success();
+ });
+ }
+
[[nodiscard]] bool lowerToBindAndAnnotateHandle(Function &F) {
IRBuilder<> &IRB = OpBuilder.getIRB();
@@ -476,6 +504,9 @@ class OpLowerer {
HasErrors |= replaceFunctionWithOp(F, OpCode); \
break;
#include "DXILOperation.inc"
+ case Intrinsic::dx_groupMemoryBarrierWithGroupSync:
+ HasErrors |= lowerBarrier(F, ID);
+ break;
case Intrinsic::dx_handle_fromBinding:
HasErrors |= lowerHandleFromBinding(F);
break;
diff --git a/llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll b/llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll
new file mode 100644
index 00000000000000..a99c6757814f3b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll
@@ -0,0 +1,8 @@
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
+
+define void @test_group_memory_barrier_with_group_sync() {
+entry:
+ ; CHECK: call void @dx.op.barrier(i32 80, i32 9)
+ call void @llvm.dx.groupMemoryBarrierWithGroupSync()
+ ret void
+}
\ No newline at end of file
>From 7782046c6188bffc068765258062fd740f8c9aed Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Thu, 10 Oct 2024 12:25:26 -0700
Subject: [PATCH 02/15] Changed naming convention and fixed formatting
---
llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +-
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 23 ++++++++-----------
...> group_memory_barrier_with_group_sync.ll} | 2 +-
3 files changed, 12 insertions(+), 15 deletions(-)
rename llvm/test/CodeGen/DirectX/{GroupMemoryBarrierWithGroupSync.ll => group_memory_barrier_with_group_sync.ll} (80%)
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 015cc0ddab4026..dada426368995d 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -93,5 +93,5 @@ def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_groupMemoryBarrierWithGroupSync : DefaultAttrsIntrinsic<[], [], []>;
+def int_dx_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
}
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index fa49d8bbe0340a..a17877d112c932 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -209,19 +209,14 @@ class OpLowerer {
});
}
- [[nodiscard]] bool lowerBarrier(Function& F, Intrinsic::ID IntrId) {
+ [[nodiscard]] bool lowerBarrier(Function &F, Intrinsic::ID IntrId,
+ ArrayRef<dxil::BarrierMode> BarrierModes) {
+ unsigned BarrierMode = 0;
+ for (const dxil::BarrierMode B : BarrierModes) {
+ BarrierMode |= (unsigned)B;
+ }
IRBuilder<> &IRB = OpBuilder.getIRB();
return replaceFunction(F, [&](CallInst *CI) -> Error {
- unsigned BarrierMode = 0;
- switch (IntrId) {
- default:
- report_fatal_error("Unhandled barrier operation type.");
- break;
- case Intrinsic::dx_groupMemoryBarrierWithGroupSync:
- BarrierMode = (unsigned)dxil::BarrierMode::TGSMFence | (unsigned)dxil::BarrierMode::SyncThreadGroup;
- break;
- }
-
std::array<Value *, 1> Args{IRB.getInt32(BarrierMode)};
IRB.SetInsertPoint(CI);
@@ -504,8 +499,10 @@ class OpLowerer {
HasErrors |= replaceFunctionWithOp(F, OpCode); \
break;
#include "DXILOperation.inc"
- case Intrinsic::dx_groupMemoryBarrierWithGroupSync:
- HasErrors |= lowerBarrier(F, ID);
+ case Intrinsic::dx_group_memory_barrier_with_group_sync:
+ HasErrors |= lowerBarrier(
+ F, ID,
+ {dxil::BarrierMode::TGSMFence, dxil::BarrierMode::SyncThreadGroup});
break;
case Intrinsic::dx_handle_fromBinding:
HasErrors |= lowerHandleFromBinding(F);
diff --git a/llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
similarity index 80%
rename from llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll
rename to llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index a99c6757814f3b..48907647c660f8 100644
--- a/llvm/test/CodeGen/DirectX/GroupMemoryBarrierWithGroupSync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -3,6 +3,6 @@
define void @test_group_memory_barrier_with_group_sync() {
entry:
; CHECK: call void @dx.op.barrier(i32 80, i32 9)
- call void @llvm.dx.groupMemoryBarrierWithGroupSync()
+ call void @llvm.dx.group.memory.barrier.with.group.sync()
ret void
}
\ No newline at end of file
>From 259deddb2369782405d6f6172c6ecc5d27bba5e9 Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Thu, 10 Oct 2024 12:59:52 -0700
Subject: [PATCH 03/15] Got rid of the noduplicate attr
---
llvm/lib/Target/DirectX/DXIL.td | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index c5fb6428e63233..ee66dfa294070f 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -277,7 +277,6 @@ def IsFeedback : DXILAttribute;
def IsWave : DXILAttribute;
def NeedsUniformInputs : DXILAttribute;
def IsBarrier : DXILAttribute;
-def NoDuplicate : DXILAttribute;
class Overloads<Version ver, list<DXILOpParamType> ols> {
Version dxil_version = ver;
@@ -827,5 +826,5 @@ def Barrier : DXILOp<80, barrier> {
let arguments = [Int32Ty];
let result = VoidTy;
let stages = [Stages<DXIL1_0, [compute, library]>];
- let attributes = [Attributes<DXIL1_0, [NoDuplicate]>];
+ let attributes = [Attributes<DXIL1_0, []>];
}
>From 6b4c6f18acf5527758c6249d144d015523f8540d Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Thu, 10 Oct 2024 13:03:52 -0700
Subject: [PATCH 04/15] Shader model changed to 6.0
---
.../CodeGen/DirectX/group_memory_barrier_with_group_sync.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index 48907647c660f8..7cacbe778ac952 100644
--- a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library < %s | FileCheck %s --check-prefix=CHECK
define void @test_group_memory_barrier_with_group_sync() {
entry:
>From 9aafe48d8f5f19ab82fd5e20d735d0ad322c8b29 Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Thu, 10 Oct 2024 13:07:03 -0700
Subject: [PATCH 05/15] Fixed the incorrect arguments list
---
llvm/lib/Target/DirectX/DXIL.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index ee66dfa294070f..5cb6194bfd2743 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -823,7 +823,7 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
def Barrier : DXILOp<80, barrier> {
let Doc = "inserts a memory barrier in the shader";
- let arguments = [Int32Ty];
+ let arguments = [];
let result = VoidTy;
let stages = [Stages<DXIL1_0, [compute, library]>];
let attributes = [Attributes<DXIL1_0, []>];
>From 88b493e4715353131a84a3b36310351e12932eca Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Thu, 10 Oct 2024 13:13:21 -0700
Subject: [PATCH 06/15] Revert "Shader model changed to 6.0"
This reverts commit c7d83cf8ae32d98b0677ff1a88f74fe4827dd61f.
---
.../CodeGen/DirectX/group_memory_barrier_with_group_sync.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index 7cacbe778ac952..48907647c660f8 100644
--- a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library < %s | FileCheck %s --check-prefix=CHECK
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
define void @test_group_memory_barrier_with_group_sync() {
entry:
>From 1ad58f30ddbbe9d38410a1a5ecf201b3b83bffcd Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 15 Oct 2024 15:56:50 -0700
Subject: [PATCH 07/15] Added another intermediate memory barrier intrinsic
that maps directly to the barrier dxil op
---
llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 +
llvm/lib/Target/DirectX/DXIL.td | 3 +-
.../Target/DirectX/DXILIntrinsicExpansion.cpp | 26 +++++++++++++++++
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 28 -------------------
.../group_memory_barrier_with_group_sync.ll | 2 +-
5 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index dada426368995d..d16a71f717b8db 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -93,5 +93,6 @@ def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_memory_barrier : DefaultAttrsIntrinsic<[], [llvm_i32_ty], []>;
def int_dx_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
}
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 5cb6194bfd2743..a1a96cc740d7bd 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -823,7 +823,8 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
def Barrier : DXILOp<80, barrier> {
let Doc = "inserts a memory barrier in the shader";
- let arguments = [];
+ let LLVMIntrinsic = int_dx_memory_barrier;
+ let arguments = [Int32Ty];
let result = VoidTy;
let stages = [Stages<DXIL1_0, [compute, library]>];
let attributes = [Attributes<DXIL1_0, []>];
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index fb5383b3514a5a..56dca69b42f1fe 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -10,6 +10,7 @@
// opcodes in DirectX Intermediate Language (DXIL).
//===----------------------------------------------------------------------===//
+#include "DXILConstants.h"
#include "DXILIntrinsicExpansion.h"
#include "DirectX.h"
#include "llvm/ADT/STLExtras.h"
@@ -66,6 +67,7 @@ static bool isIntrinsicExpansion(Function &F) {
case Intrinsic::dx_sign:
case Intrinsic::dx_step:
case Intrinsic::dx_radians:
+ case Intrinsic::dx_group_memory_barrier_with_group_sync:
return true;
}
return false;
@@ -452,6 +454,27 @@ static Value *expandRadiansIntrinsic(CallInst *Orig) {
return Builder.CreateFMul(X, PiOver180);
}
+static Value *expandMemoryBarrier(CallInst *Orig, Intrinsic::ID IntrinsicId) {
+ assert(IntrinsicId == Intrinsic::dx_group_memory_barrier_with_group_sync);
+ unsigned BarrierMode = 0;
+ switch (IntrinsicId) {
+ case Intrinsic::dx_group_memory_barrier_with_group_sync:
+ BarrierMode = (unsigned)dxil::BarrierMode::TGSMFence |
+ (unsigned)dxil::BarrierMode::SyncThreadGroup;
+ break;
+ default:
+ report_fatal_error(Twine("Unexpected memory barrier intrinsic."),
+ /* gen_crash_diag=*/false);
+ break;
+ }
+
+ IRBuilder<> Builder(Orig);
+ return Builder.CreateIntrinsic(
+ Builder.getVoidTy(), Intrinsic::dx_memory_barrier,
+ ArrayRef<Value *>{Builder.getInt32(BarrierMode)}, nullptr,
+ Orig->getName());
+}
+
static Intrinsic::ID getMaxForClamp(Type *ElemTy,
Intrinsic::ID ClampIntrinsic) {
if (ClampIntrinsic == Intrinsic::dx_uclamp)
@@ -586,6 +609,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
case Intrinsic::dx_radians:
Result = expandRadiansIntrinsic(Orig);
break;
+ case Intrinsic::dx_group_memory_barrier_with_group_sync:
+ Result = expandMemoryBarrier(Orig, IntrinsicId);
+ break;
}
if (Result) {
Orig->replaceAllUsesWith(Result);
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index a17877d112c932..c62ba8c21d6791 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -209,29 +209,6 @@ class OpLowerer {
});
}
- [[nodiscard]] bool lowerBarrier(Function &F, Intrinsic::ID IntrId,
- ArrayRef<dxil::BarrierMode> BarrierModes) {
- unsigned BarrierMode = 0;
- for (const dxil::BarrierMode B : BarrierModes) {
- BarrierMode |= (unsigned)B;
- }
- IRBuilder<> &IRB = OpBuilder.getIRB();
- return replaceFunction(F, [&](CallInst *CI) -> Error {
- std::array<Value *, 1> Args{IRB.getInt32(BarrierMode)};
-
- IRB.SetInsertPoint(CI);
- Expected<CallInst *> OpCall =
- OpBuilder.tryCreateOp(OpCode::Barrier, Args, CI->getName());
- if (Error E = OpCall.takeError())
- return E;
-
- CI->replaceAllUsesWith(OpCall.get());
- CI->eraseFromParent();
-
- return Error::success();
- });
- }
-
[[nodiscard]] bool lowerToBindAndAnnotateHandle(Function &F) {
IRBuilder<> &IRB = OpBuilder.getIRB();
@@ -499,11 +476,6 @@ class OpLowerer {
HasErrors |= replaceFunctionWithOp(F, OpCode); \
break;
#include "DXILOperation.inc"
- case Intrinsic::dx_group_memory_barrier_with_group_sync:
- HasErrors |= lowerBarrier(
- F, ID,
- {dxil::BarrierMode::TGSMFence, dxil::BarrierMode::SyncThreadGroup});
- break;
case Intrinsic::dx_handle_fromBinding:
HasErrors |= lowerHandleFromBinding(F);
break;
diff --git a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index 48907647c660f8..c43625755d6efc 100644
--- a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
+; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
define void @test_group_memory_barrier_with_group_sync() {
entry:
>From a4bd2957fceefdf3a90ead7e4b7d1655bf2bfe0c Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 15 Oct 2024 16:27:13 -0700
Subject: [PATCH 08/15] Format
---
llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 56dca69b42f1fe..649398fc5bd2b4 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -10,8 +10,8 @@
// opcodes in DirectX Intermediate Language (DXIL).
//===----------------------------------------------------------------------===//
-#include "DXILConstants.h"
#include "DXILIntrinsicExpansion.h"
+#include "DXILConstants.h"
#include "DirectX.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
>From 8141a2ab205595bd002914ceda7d61b37e7c488f Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Wed, 16 Oct 2024 17:48:25 -0700
Subject: [PATCH 09/15] Tablegen simple
---
llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 -
llvm/lib/Target/DirectX/DXIL.td | 14 +++-
.../Target/DirectX/DXILIntrinsicExpansion.cpp | 26 --------
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 25 +++----
.../group_memory_barrier_with_group_sync.ll | 2 +-
llvm/utils/TableGen/DXILEmitter.cpp | 66 +++++++++++++++----
6 files changed, 80 insertions(+), 54 deletions(-)
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index d16a71f717b8db..dada426368995d 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -93,6 +93,5 @@ def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_memory_barrier : DefaultAttrsIntrinsic<[], [llvm_i32_ty], []>;
def int_dx_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
}
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index a1a96cc740d7bd..6b290ec09b907b 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -293,6 +293,11 @@ class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
list<DXILAttribute> op_attrs = attrs;
}
+class IntrinsicSelect<Intrinsic intr, list<string> extra_args> {
+ Intrinsic Intr = intr;
+ list<string> ExtraArgs = extra_args;
+}
+
// Abstraction DXIL Operation
class DXILOp<int opcode, DXILOpClass opclass> {
// A short description of the operation
@@ -307,6 +312,8 @@ class DXILOp<int opcode, DXILOpClass opclass> {
// LLVM Intrinsic DXIL Operation maps to
Intrinsic LLVMIntrinsic = ?;
+ list<IntrinsicSelect> intrinsic_selects = [];
+
// Result type of the op
DXILOpParamType result;
@@ -823,7 +830,12 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
def Barrier : DXILOp<80, barrier> {
let Doc = "inserts a memory barrier in the shader";
- let LLVMIntrinsic = int_dx_memory_barrier;
+ let intrinsic_selects = [
+ IntrinsicSelect<
+ int_dx_group_memory_barrier_with_group_sync,
+ [ "OpBuilder.getIRB().getInt32((unsigned)BarrierMode::SyncThreadGroup | (unsigned)BarrierMode::TGSMFence)" ]>,
+ ];
+
let arguments = [Int32Ty];
let result = VoidTy;
let stages = [Stages<DXIL1_0, [compute, library]>];
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 649398fc5bd2b4..fb5383b3514a5a 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//
#include "DXILIntrinsicExpansion.h"
-#include "DXILConstants.h"
#include "DirectX.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
@@ -67,7 +66,6 @@ static bool isIntrinsicExpansion(Function &F) {
case Intrinsic::dx_sign:
case Intrinsic::dx_step:
case Intrinsic::dx_radians:
- case Intrinsic::dx_group_memory_barrier_with_group_sync:
return true;
}
return false;
@@ -454,27 +452,6 @@ static Value *expandRadiansIntrinsic(CallInst *Orig) {
return Builder.CreateFMul(X, PiOver180);
}
-static Value *expandMemoryBarrier(CallInst *Orig, Intrinsic::ID IntrinsicId) {
- assert(IntrinsicId == Intrinsic::dx_group_memory_barrier_with_group_sync);
- unsigned BarrierMode = 0;
- switch (IntrinsicId) {
- case Intrinsic::dx_group_memory_barrier_with_group_sync:
- BarrierMode = (unsigned)dxil::BarrierMode::TGSMFence |
- (unsigned)dxil::BarrierMode::SyncThreadGroup;
- break;
- default:
- report_fatal_error(Twine("Unexpected memory barrier intrinsic."),
- /* gen_crash_diag=*/false);
- break;
- }
-
- IRBuilder<> Builder(Orig);
- return Builder.CreateIntrinsic(
- Builder.getVoidTy(), Intrinsic::dx_memory_barrier,
- ArrayRef<Value *>{Builder.getInt32(BarrierMode)}, nullptr,
- Orig->getName());
-}
-
static Intrinsic::ID getMaxForClamp(Type *ElemTy,
Intrinsic::ID ClampIntrinsic) {
if (ClampIntrinsic == Intrinsic::dx_uclamp)
@@ -609,9 +586,6 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
case Intrinsic::dx_radians:
Result = expandRadiansIntrinsic(Orig);
break;
- case Intrinsic::dx_group_memory_barrier_with_group_sync:
- Result = expandMemoryBarrier(Orig, IntrinsicId);
- break;
}
if (Result) {
Orig->replaceAllUsesWith(Result);
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index c62ba8c21d6791..efa74aa498dac6 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -105,20 +105,21 @@ class OpLowerer {
return false;
}
- [[nodiscard]]
- bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp) {
+ [[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
+ ArrayRef<Value *> ExtraArgs) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
- SmallVector<Value *> Args;
- OpBuilder.getIRB().SetInsertPoint(CI);
+ SmallVector<Value *> NewArgs;
if (IsVectorArgExpansion) {
- SmallVector<Value *> NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
- Args.append(NewArgs.begin(), NewArgs.end());
+ NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
} else
- Args.append(CI->arg_begin(), CI->arg_end());
+ NewArgs.append(CI->arg_begin(), CI->arg_end());
- Expected<CallInst *> OpCall =
- OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), F.getReturnType());
+ NewArgs.append(ExtraArgs.begin(), ExtraArgs.end());
+
+ OpBuilder.getIRB().SetInsertPoint(CI);
+ Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
+ DXILOp, NewArgs, CI->getName(), F.getReturnType());
if (Error E = OpCall.takeError())
return E;
@@ -471,9 +472,9 @@ class OpLowerer {
switch (ID) {
default:
continue;
-#define DXIL_OP_INTRINSIC(OpCode, Intrin) \
- case Intrin: \
- HasErrors |= replaceFunctionWithOp(F, OpCode); \
+#define DXIL_OP_INTRINSIC(OpCode, Intrin, ExtraArgs) \
+ case Intrin: \
+ HasErrors |= replaceFunctionWithOp(F, OpCode, ExtraArgs); \
break;
#include "DXILOperation.inc"
case Intrinsic::dx_handle_fromBinding:
diff --git a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index c43625755d6efc..cd588d464e302b 100644
--- a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
define void @test_group_memory_barrier_with_group_sync() {
entry:
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 0598baea9be7a2..db0c719e0eff41 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -33,6 +33,11 @@ using namespace llvm::dxil;
namespace {
+struct DXILIntrinsicSelect {
+ StringRef Intrinsic;
+ SmallVector<StringRef, 4> ExtraArgs;
+};
+
struct DXILOperationDesc {
std::string OpName; // name of DXIL operation
int OpCode; // ID of DXIL operation
@@ -43,8 +48,7 @@ struct DXILOperationDesc {
SmallVector<const Record *> OverloadRecs;
SmallVector<const Record *> StageRecs;
SmallVector<const Record *> AttrRecs;
- StringRef Intrinsic; // The llvm intrinsic map to OpName. Default is "" which
- // means no map exists
+ SmallVector<DXILIntrinsicSelect> IntrinsicSelects;
SmallVector<StringRef, 4>
ShaderStages; // shader stages to which this applies, empty for all.
int OverloadParamIndex; // Index of parameter with overload type.
@@ -158,14 +162,43 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
OpName);
}
- const RecordVal *RV = R->getValue("LLVMIntrinsic");
- if (RV && RV->getValue()) {
- if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
- auto *IntrinsicDef = DI->getDef();
- auto DefName = IntrinsicDef->getName();
- assert(DefName.starts_with("int_") && "invalid intrinsic name");
- // Remove the int_ from intrinsic name.
- Intrinsic = DefName.substr(4);
+ auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
+ if (RV && RV->getValue()) {
+ if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
+ auto *IntrinsicDef = DI->getDef();
+ auto DefName = IntrinsicDef->getName();
+ assert(DefName.starts_with("int_") && "invalid intrinsic name");
+ // Remove the int_ from intrinsic name.
+ return DefName.substr(4);
+ }
+ }
+ return "";
+ };
+
+ {
+ DXILIntrinsicSelect IntrSelect;
+ IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("LLVMIntrinsic"));
+ if (IntrSelect.Intrinsic.size())
+ IntrinsicSelects.emplace_back(std::move(IntrSelect));
+ }
+
+ Recs = R->getValueAsListOfDefs("intrinsic_selects");
+ if (Recs.size()) {
+ if (IntrinsicSelects.size()) {
+ PrintFatalError(R,
+ Twine("LLVMIntrinsic and intrinsic_match cannot be both "
+ "defined for DXIL operation - ") +
+ OpName);
+ } else {
+ for (const Record *R : Recs) {
+ DXILIntrinsicSelect IntrSelect;
+ IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("Intr"));
+ auto ExtraArgs = R->getValueAsListOfStrings("ExtraArgs");
+ for (StringRef Arg : ExtraArgs) {
+ IntrSelect.ExtraArgs.push_back(Arg);
+ }
+ IntrinsicSelects.emplace_back(std::move(IntrSelect));
+ }
}
}
}
@@ -378,10 +411,17 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
OS << "#ifdef DXIL_OP_INTRINSIC\n";
OS << "\n";
for (const auto &Op : Ops) {
- if (Op.Intrinsic.empty())
+ if (Op.IntrinsicSelects.empty()) {
continue;
- OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
- << ", Intrinsic::" << Op.Intrinsic << ")\n";
+ }
+ for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects) {
+ OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
+ << ", Intrinsic::" << MappedIntr.Intrinsic << ", (ArrayRef<Value *> {";
+ for (const StringRef &Arg : MappedIntr.ExtraArgs) {
+ OS << Arg << ", ";
+ }
+ OS << "}))\n";
+ }
}
OS << "\n";
OS << "#undef DXIL_OP_INTRINSIC\n";
>From 4d1ba4bbc2c2e99cae305c1b73272fa0bf358140 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 21 Oct 2024 10:53:23 -0700
Subject: [PATCH 10/15] All working now
---
llvm/lib/Target/DirectX/DXIL.td | 40 +++++++-
llvm/lib/Target/DirectX/DXILConstants.h | 7 --
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 44 +++++++--
llvm/utils/TableGen/DXILEmitter.cpp | 104 +++++++++++++++------
4 files changed, 146 insertions(+), 49 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 6b290ec09b907b..4ff56ed694e94b 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -293,9 +293,41 @@ class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
list<DXILAttribute> op_attrs = attrs;
}
-class IntrinsicSelect<Intrinsic intr, list<string> extra_args> {
- Intrinsic Intr = intr;
- list<string> ExtraArgs = extra_args;
+class DXILConstant<int value_> {
+ int value = value_;
+}
+
+defset list<DXILConstant> BarrierModes = {
+ def BarrierMode_DeviceMemoryBarrier : DXILConstant<2>;
+ def BarrierMode_DeviceMemoryBarrierWithGroupSync : DXILConstant<3>;
+ def BarrierMode_GroupMemoryBarrier : DXILConstant<8>;
+ def BarrierMode_GroupMemoryBarrierWithGroupSync : DXILConstant<9>;
+ def BarrierMode_AllMemoryBarrier : DXILConstant<10>;
+ def BarrierMode_AllMemoryBarrierWithGroupSync : DXILConstant<11>;
+}
+
+// Intrinsic arg selection
+class Arg {
+ int index = -1;
+ DXILConstant value;
+ bit is_i8 = 0;
+ bit is_i32 = 0;
+}
+class ArgSelect<int index_> : Arg {
+ let index = index_;
+}
+class ArgI32<DXILConstant value_> : Arg {
+ let value = value_;
+ let is_i32 = 1;
+}
+class ArgI8<DXILConstant value_> : Arg {
+ let value = value_;
+ let is_i8 = 1;
+}
+
+class IntrinsicSelect<Intrinsic intrinsic_, list<Arg> args_=?> {
+ Intrinsic intrinsic = intrinsic_;
+ list<Arg> args = args_;
}
// Abstraction DXIL Operation
@@ -833,7 +865,7 @@ def Barrier : DXILOp<80, barrier> {
let intrinsic_selects = [
IntrinsicSelect<
int_dx_group_memory_barrier_with_group_sync,
- [ "OpBuilder.getIRB().getInt32((unsigned)BarrierMode::SyncThreadGroup | (unsigned)BarrierMode::TGSMFence)" ]>,
+ [ ArgI32<BarrierMode_GroupMemoryBarrierWithGroupSync> ]>,
];
let arguments = [Int32Ty];
diff --git a/llvm/lib/Target/DirectX/DXILConstants.h b/llvm/lib/Target/DirectX/DXILConstants.h
index 38984727761bb3..022cd57795a063 100644
--- a/llvm/lib/Target/DirectX/DXILConstants.h
+++ b/llvm/lib/Target/DirectX/DXILConstants.h
@@ -30,13 +30,6 @@ enum class OpParamType : unsigned {
#include "DXILOperation.inc"
};
-enum class BarrierMode : unsigned {
- SyncThreadGroup = 0x00000001,
- UAVFenceGlobal = 0x00000002,
- UAVFenceThreadGroup = 0x00000004,
- TGSMFence = 0x00000008,
-};
-
} // namespace dxil
} // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index efa74aa498dac6..83eea72b1ae404 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -105,19 +105,44 @@ class OpLowerer {
return false;
}
+ struct Arg {
+ enum class Type {
+ Index,
+ I8,
+ I32,
+ };
+ Type Type = Type::Index;
+ int Value = -1;
+ };
+
[[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
- ArrayRef<Value *> ExtraArgs) {
+ ArrayRef<Arg> Args) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
+ OpBuilder.getIRB().SetInsertPoint(CI);
SmallVector<Value *> NewArgs;
- if (IsVectorArgExpansion) {
+ if (Args.size()) {
+ for (const Arg &A : Args) {
+ switch (A.Type) {
+ case Arg::Type::Index:
+ NewArgs.push_back(CI->getArgOperand(A.Value));
+ break;
+ case Arg::Type::I8:
+ NewArgs.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
+ break;
+ case Arg::Type::I32:
+ NewArgs.push_back(OpBuilder.getIRB().getInt32(A.Value));
+ break;
+ default:
+ llvm_unreachable("Invalid type of intrinsic arg.");
+ }
+ }
+ } else if (IsVectorArgExpansion) {
NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
- } else
+ } else {
NewArgs.append(CI->arg_begin(), CI->arg_end());
+ }
- NewArgs.append(ExtraArgs.begin(), ExtraArgs.end());
-
- OpBuilder.getIRB().SetInsertPoint(CI);
Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
DXILOp, NewArgs, CI->getName(), F.getReturnType());
if (Error E = OpCall.takeError())
@@ -472,9 +497,10 @@ class OpLowerer {
switch (ID) {
default:
continue;
-#define DXIL_OP_INTRINSIC(OpCode, Intrin, ExtraArgs) \
- case Intrin: \
- HasErrors |= replaceFunctionWithOp(F, OpCode, ExtraArgs); \
+#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
+ case Intrin: \
+ HasErrors |= replaceFunctionWithOp(F, OpCode, \
+ ArrayRef<Arg>{ __VA_ARGS__ }); \
break;
#include "DXILOperation.inc"
case Intrinsic::dx_handle_fromBinding:
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index db0c719e0eff41..2a2a5f235c1797 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -33,9 +33,18 @@ using namespace llvm::dxil;
namespace {
+struct DXILArgSelect {
+ enum class Type {
+ Index,
+ I32,
+ I8,
+ };
+ Type Type = Type::Index;
+ int Value = 0;
+};
struct DXILIntrinsicSelect {
StringRef Intrinsic;
- SmallVector<StringRef, 4> ExtraArgs;
+ SmallVector<DXILArgSelect, 4> Args;
};
struct DXILOperationDesc {
@@ -76,6 +85,21 @@ static void AscendingSortByVersion(std::vector<const Record *> &Recs) {
});
}
+/// Take a `int_{intrinsic_name}` and return just the intrinsic_name part if available.
+/// Otherwise return the empty string.
+static StringRef GetIntrinsicName(const RecordVal *RV){
+ if (RV && RV->getValue()) {
+ if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
+ auto *IntrinsicDef = DI->getDef();
+ auto DefName = IntrinsicDef->getName();
+ assert(DefName.starts_with("int_") && "invalid intrinsic name");
+ // Remove the int_ from intrinsic name.
+ return DefName.substr(4);
+ }
+ }
+ return "";
+}
+
/// Construct an object using the DXIL Operation records specified
/// in DXIL.td. This serves as the single source of reference of
/// the information extracted from the specified Record R, for
@@ -162,19 +186,6 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
OpName);
}
- auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
- if (RV && RV->getValue()) {
- if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
- auto *IntrinsicDef = DI->getDef();
- auto DefName = IntrinsicDef->getName();
- assert(DefName.starts_with("int_") && "invalid intrinsic name");
- // Remove the int_ from intrinsic name.
- return DefName.substr(4);
- }
- }
- return "";
- };
-
{
DXILIntrinsicSelect IntrSelect;
IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("LLVMIntrinsic"));
@@ -182,20 +193,43 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
IntrinsicSelects.emplace_back(std::move(IntrSelect));
}
- Recs = R->getValueAsListOfDefs("intrinsic_selects");
- if (Recs.size()) {
+ auto IntrinsicSelectRecords = R->getValueAsListOfDefs("intrinsic_selects");
+ if (IntrinsicSelectRecords.size()) {
if (IntrinsicSelects.size()) {
- PrintFatalError(R,
- Twine("LLVMIntrinsic and intrinsic_match cannot be both "
- "defined for DXIL operation - ") +
- OpName);
+ PrintFatalError(
+ R, Twine("LLVMIntrinsic and intrinsic_selects cannot be both "
+ "defined for DXIL operation - ") +
+ OpName);
} else {
- for (const Record *R : Recs) {
+ for (const Record *R : IntrinsicSelectRecords) {
DXILIntrinsicSelect IntrSelect;
- IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("Intr"));
- auto ExtraArgs = R->getValueAsListOfStrings("ExtraArgs");
- for (StringRef Arg : ExtraArgs) {
- IntrSelect.ExtraArgs.push_back(Arg);
+ IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("intrinsic"));
+ auto Args = R->getValueAsListOfDefs("args");
+ for (const Record *Arg : Args) {
+ bool IsI8 = Arg->getValueAsBit("is_i8");
+ bool IsI32 = Arg->getValueAsBit("is_i32");
+ int Index = Arg->getValueAsInt("index");
+ const Record *ValueRec = Arg->getValueAsDef("value");
+
+ DXILArgSelect ArgSelect;
+ if (IsI8) {
+ ArgSelect.Type = DXILArgSelect::Type::I8;
+ ArgSelect.Value = ValueRec->getValueAsInt("value");
+ } else if (IsI32) {
+ ArgSelect.Type = DXILArgSelect::Type::I32;
+ ArgSelect.Value = ValueRec->getValueAsInt("value");
+ } else {
+ if (Index < 0) {
+ PrintFatalError(
+ R, Twine("Index in ArgSelect<index> must be equal to or "
+ "greater than 0 for DXIL operation - ") +
+ OpName);
+ }
+ ArgSelect.Type = DXILArgSelect::Type::Index;
+ ArgSelect.Value = Index;
+ }
+
+ IntrSelect.Args.emplace_back(std::move(ArgSelect));
}
IntrinsicSelects.emplace_back(std::move(IntrSelect));
}
@@ -416,11 +450,23 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
}
for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects) {
OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
- << ", Intrinsic::" << MappedIntr.Intrinsic << ", (ArrayRef<Value *> {";
- for (const StringRef &Arg : MappedIntr.ExtraArgs) {
- OS << Arg << ", ";
+ << ", Intrinsic::" << MappedIntr.Intrinsic;
+ for (const DXILArgSelect &ArgSelect : MappedIntr.Args) {
+ OS << ", (Arg { ";
+ switch (ArgSelect.Type) {
+ case DXILArgSelect::Type::Index:
+ OS << "Arg::Type::Index, ";
+ break;
+ case DXILArgSelect::Type::I8:
+ OS << "Arg::Type::I8, ";
+ break;
+ case DXILArgSelect::Type::I32:
+ OS << "Arg::Type::I32, ";
+ break;
+ }
+ OS << ArgSelect.Value << "})";
}
- OS << "}))\n";
+ OS << ")\n";
}
}
OS << "\n";
>From f44219d1a8bfaef9d6e254bdd10624af7472d2ca Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 21 Oct 2024 11:17:01 -0700
Subject: [PATCH 11/15] Rename and clang-format
---
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 22 +++++++++++-----------
llvm/utils/TableGen/DXILEmitter.cpp | 8 ++++----
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 83eea72b1ae404..451e5d1d92c5cc 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -105,7 +105,7 @@ class OpLowerer {
return false;
}
- struct Arg {
+ struct ArgSelect {
enum class Type {
Index,
I8,
@@ -116,25 +116,25 @@ class OpLowerer {
};
[[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
- ArrayRef<Arg> Args) {
+ ArrayRef<ArgSelect> Args) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
OpBuilder.getIRB().SetInsertPoint(CI);
SmallVector<Value *> NewArgs;
if (Args.size()) {
- for (const Arg &A : Args) {
+ for (const ArgSelect &A : Args) {
switch (A.Type) {
- case Arg::Type::Index:
+ case ArgSelect::Type::Index:
NewArgs.push_back(CI->getArgOperand(A.Value));
break;
- case Arg::Type::I8:
+ case ArgSelect::Type::I8:
NewArgs.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
break;
- case Arg::Type::I32:
+ case ArgSelect::Type::I32:
NewArgs.push_back(OpBuilder.getIRB().getInt32(A.Value));
break;
default:
- llvm_unreachable("Invalid type of intrinsic arg.");
+ llvm_unreachable("Invalid type of intrinsic arg select.");
}
}
} else if (IsVectorArgExpansion) {
@@ -497,10 +497,10 @@ class OpLowerer {
switch (ID) {
default:
continue;
-#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
- case Intrin: \
- HasErrors |= replaceFunctionWithOp(F, OpCode, \
- ArrayRef<Arg>{ __VA_ARGS__ }); \
+#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
+ case Intrin: \
+ HasErrors |= replaceFunctionWithOp(F, OpCode, \
+ ArrayRef<ArgSelect>{ __VA_ARGS__ }); \
break;
#include "DXILOperation.inc"
case Intrinsic::dx_handle_fromBinding:
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 2a2a5f235c1797..781d6a0d5e0fcb 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -452,16 +452,16 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
<< ", Intrinsic::" << MappedIntr.Intrinsic;
for (const DXILArgSelect &ArgSelect : MappedIntr.Args) {
- OS << ", (Arg { ";
+ OS << ", (ArgSelect { ";
switch (ArgSelect.Type) {
case DXILArgSelect::Type::Index:
- OS << "Arg::Type::Index, ";
+ OS << "ArgSelect::Type::Index, ";
break;
case DXILArgSelect::Type::I8:
- OS << "Arg::Type::I8, ";
+ OS << "ArgSelect::Type::I8, ";
break;
case DXILArgSelect::Type::I32:
- OS << "Arg::Type::I32, ";
+ OS << "ArgSelect::Type::I32, ";
break;
}
OS << ArgSelect.Value << "})";
>From 1c1185954f80df5f5e0fdf8a6efb7eaf984398f6 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 21 Oct 2024 11:21:25 -0700
Subject: [PATCH 12/15] Comment
---
llvm/lib/Target/DirectX/DXIL.td | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 4ff56ed694e94b..03a54ce3286be0 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -344,6 +344,7 @@ class DXILOp<int opcode, DXILOpClass opclass> {
// LLVM Intrinsic DXIL Operation maps to
Intrinsic LLVMIntrinsic = ?;
+ // Non-trivial LLVM Intrinsics DXIL Operation maps to
list<IntrinsicSelect> intrinsic_selects = [];
// Result type of the op
>From c5c5d75648495f44f70b09dff31546a992abd6b9 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 21 Oct 2024 12:21:10 -0700
Subject: [PATCH 13/15] Handling the arg select version for other ops
---
llvm/lib/Target/DirectX/DXIL.td | 2 +-
llvm/utils/TableGen/DXILEmitter.cpp | 12 +++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 03a54ce3286be0..73b3905e4bbe52 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -325,7 +325,7 @@ class ArgI8<DXILConstant value_> : Arg {
let is_i8 = 1;
}
-class IntrinsicSelect<Intrinsic intrinsic_, list<Arg> args_=?> {
+class IntrinsicSelect<Intrinsic intrinsic_, list<Arg> args_> {
Intrinsic intrinsic = intrinsic_;
list<Arg> args = args_;
}
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 781d6a0d5e0fcb..b1be890104567e 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -209,13 +209,23 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
bool IsI8 = Arg->getValueAsBit("is_i8");
bool IsI32 = Arg->getValueAsBit("is_i32");
int Index = Arg->getValueAsInt("index");
- const Record *ValueRec = Arg->getValueAsDef("value");
+ const Record *ValueRec = Arg->getValueAsOptionalDef("value");
DXILArgSelect ArgSelect;
if (IsI8) {
+ if (!ValueRec) {
+ PrintFatalError(R, Twine("'value' must be defined for i8 "
+ "ArgSelect for DXIL operation - ") +
+ OpName);
+ }
ArgSelect.Type = DXILArgSelect::Type::I8;
ArgSelect.Value = ValueRec->getValueAsInt("value");
} else if (IsI32) {
+ if (!ValueRec) {
+ PrintFatalError(R, Twine("'value' must be defined for i32 "
+ "ArgSelect for DXIL operation - ") +
+ OpName);
+ }
ArgSelect.Type = DXILArgSelect::Type::I32;
ArgSelect.Value = ValueRec->getValueAsInt("value");
} else {
>From 485e3a8b8222caf367083cfe6528d5582d2a8224 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 21 Oct 2024 12:43:53 -0700
Subject: [PATCH 14/15] Formatting
---
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 4 ++--
llvm/utils/TableGen/DXILEmitter.cpp | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 451e5d1d92c5cc..be06ab2d47e3e4 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -499,8 +499,8 @@ class OpLowerer {
continue;
#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
case Intrin: \
- HasErrors |= replaceFunctionWithOp(F, OpCode, \
- ArrayRef<ArgSelect>{ __VA_ARGS__ }); \
+ HasErrors |= \
+ replaceFunctionWithOp(F, OpCode, ArrayRef<ArgSelect>{__VA_ARGS__}); \
break;
#include "DXILOperation.inc"
case Intrinsic::dx_handle_fromBinding:
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index b1be890104567e..0245bdaae681c8 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -85,9 +85,9 @@ static void AscendingSortByVersion(std::vector<const Record *> &Recs) {
});
}
-/// Take a `int_{intrinsic_name}` and return just the intrinsic_name part if available.
-/// Otherwise return the empty string.
-static StringRef GetIntrinsicName(const RecordVal *RV){
+/// Take a `int_{intrinsic_name}` and return just the intrinsic_name part if
+/// available. Otherwise return the empty string.
+static StringRef GetIntrinsicName(const RecordVal *RV) {
if (RV && RV->getValue()) {
if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
auto *IntrinsicDef = DI->getDef();
>From f13c3a922b4022d4eee042f0e2a4ac6ba2d28515 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 28 Oct 2024 14:39:41 -0700
Subject: [PATCH 15/15] Addressed feedback
---
llvm/lib/Target/DirectX/DXILOpLowering.cpp | 22 +++++++++----------
.../group_memory_barrier_with_group_sync.ll | 2 +-
llvm/utils/TableGen/DXILEmitter.cpp | 2 +-
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index be06ab2d47e3e4..75c349aa419f0a 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -116,35 +116,35 @@ class OpLowerer {
};
[[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
- ArrayRef<ArgSelect> Args) {
+ ArrayRef<ArgSelect> ArgSelects) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
OpBuilder.getIRB().SetInsertPoint(CI);
- SmallVector<Value *> NewArgs;
- if (Args.size()) {
- for (const ArgSelect &A : Args) {
+ SmallVector<Value *> Args;
+ if (ArgSelects.size()) {
+ for (const ArgSelect &A : ArgSelects) {
switch (A.Type) {
case ArgSelect::Type::Index:
- NewArgs.push_back(CI->getArgOperand(A.Value));
+ Args.push_back(CI->getArgOperand(A.Value));
break;
case ArgSelect::Type::I8:
- NewArgs.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
+ Args.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
break;
case ArgSelect::Type::I32:
- NewArgs.push_back(OpBuilder.getIRB().getInt32(A.Value));
+ Args.push_back(OpBuilder.getIRB().getInt32(A.Value));
break;
default:
llvm_unreachable("Invalid type of intrinsic arg select.");
}
}
} else if (IsVectorArgExpansion) {
- NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
+ Args = argVectorFlatten(CI, OpBuilder.getIRB());
} else {
- NewArgs.append(CI->arg_begin(), CI->arg_end());
+ Args.append(CI->arg_begin(), CI->arg_end());
}
- Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
- DXILOp, NewArgs, CI->getName(), F.getReturnType());
+ Expected<CallInst *> OpCall =
+ OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), F.getReturnType());
if (Error E = OpCall.takeError())
return E;
diff --git a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
index cd588d464e302b..baf93d4e177f0f 100644
--- a/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
+++ b/llvm/test/CodeGen/DirectX/group_memory_barrier_with_group_sync.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefix=CHECK
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s
define void @test_group_memory_barrier_with_group_sync() {
entry:
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 0245bdaae681c8..09b241d9666295 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -40,7 +40,7 @@ struct DXILArgSelect {
I8,
};
Type Type = Type::Index;
- int Value = 0;
+ int Value = -1;
};
struct DXILIntrinsicSelect {
StringRef Intrinsic;
More information about the llvm-commits
mailing list