[llvm] [DXIL] Add GroupMemoryBarrierWithGroupSync intrinsic (PR #114349)

Adam Yang via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 12 17:05:59 PST 2024


https://github.com/adam-yang updated https://github.com/llvm/llvm-project/pull/114349

>From f6b91f426208ab9a1b0ca69a48ee064ff7496f9d 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/19] 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 af12b74351058e..d6468d7cc2d753 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -278,6 +278,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;
@@ -829,3 +830,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 8acc9c1efa08c0..ecfa120f3d7557 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -234,6 +234,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();
 
@@ -588,6 +616,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 e75ee5137fd7e9bc92cc1196822e0268440da2bc 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/19] 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 ecfa120f3d7557..9f9da213c48419 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -234,19 +234,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);
@@ -616,8 +611,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 93106197ee47972f259f1b2130463d06afca5f3b 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/19] 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 d6468d7cc2d753..12cd7b2589acb9 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -278,7 +278,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;
@@ -836,5 +835,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 02c024b39e0ee14e057290b741e9fabc693b9eaf 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/19] 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 d441956912ea53894adc929dc488bff905b34baa 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/19] 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 12cd7b2589acb9..194ae2656e05e5 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -832,7 +832,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 10fc5207a2d93010372f7d80cd48a57c5030b058 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/19] 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 be310dde751c38041d4e413170629bb23e35b5ff 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/19] 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 194ae2656e05e5..0bdf4f12fb2bf9 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -832,7 +832,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 9f9da213c48419..8acc9c1efa08c0 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -234,29 +234,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();
 
@@ -611,11 +588,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 ee113a037dc754c03bfb3de849ef503abc494e3a 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/19] 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 2c9418064e83da079a596abf7d21958ea8228805 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/19] 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 0bdf4f12fb2bf9..90fc79cab20f1f 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -294,6 +294,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
@@ -308,6 +313,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;
 
@@ -832,7 +839,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 8acc9c1efa08c0..73b43801eabfa0 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -106,20 +106,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;
 
@@ -583,9 +584,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 e74fc00015b404..5ab6b0edd02ab2 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -32,6 +32,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
@@ -42,8 +47,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.
@@ -157,14 +161,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));
+      }
     }
   }
 }
@@ -377,10 +410,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 c82dca2598695623443b60d9807e1b70937ea447 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/19] 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 90fc79cab20f1f..c62d8515962e96 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -294,9 +294,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
@@ -842,7 +874,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 73b43801eabfa0..2c9791ff7fd739 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -106,19 +106,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())
@@ -584,9 +609,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 5ab6b0edd02ab2..06f5f89615c6f3 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -32,9 +32,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 {
@@ -75,6 +84,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
@@ -161,19 +185,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"));
@@ -181,20 +192,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));
       }
@@ -415,11 +449,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 d192f8ec7132e2da8ef903cddf4aa1a8ffeb044f 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/19] 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 2c9791ff7fd739..78ae366001bb0c 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -106,7 +106,7 @@ class OpLowerer {
     return false;
   }
 
-  struct Arg {
+  struct ArgSelect {
     enum class Type {
       Index,
       I8,
@@ -117,25 +117,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) {
@@ -609,10 +609,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 06f5f89615c6f3..540af4869787ac 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -451,16 +451,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 40dc16f2a7d2c787166402117495ee12e6f0c3e7 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/19] 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 c62d8515962e96..a1f10ebadf9c5d 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -345,6 +345,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 ae52497d0ef214cc81ee3a4758d0336725534c6c 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/19] 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 a1f10ebadf9c5d..2af2e8fda1831a 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -326,7 +326,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 540af4869787ac..d68d19320c803a 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -208,13 +208,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 937e49b51fbca61288891aef44767b533f6e6673 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/19] 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 78ae366001bb0c..1ee03b622a7145 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -611,8 +611,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 d68d19320c803a..011a5cad186492 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -84,9 +84,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 e7ebc9b66e1cc1ae28ee3f1b6bb8dce79771c245 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/19] 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 1ee03b622a7145..b5cf1654181c6c 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -117,35 +117,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 011a5cad186492..8bebe608eece47 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -39,7 +39,7 @@ struct DXILArgSelect {
     I8,
   };
   Type Type = Type::Index;
-  int Value = 0;
+  int Value = -1;
 };
 struct DXILIntrinsicSelect {
   StringRef Intrinsic;

>From 0b4cde1e01e520996a826820eeae6a8c176b18bb Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Wed, 30 Oct 2024 20:47:05 -0700
Subject: [PATCH 16/19] Fixed the warnings on clang

---
 llvm/lib/Target/DirectX/DXILOpLowering.cpp | 2 --
 llvm/utils/TableGen/DXILEmitter.cpp        | 6 +++---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index b5cf1654181c6c..5f278b609690e2 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -134,8 +134,6 @@ class OpLowerer {
           case ArgSelect::Type::I32:
             Args.push_back(OpBuilder.getIRB().getInt32(A.Value));
             break;
-          default:
-            llvm_unreachable("Invalid type of intrinsic arg select.");
           }
         }
       } else if (IsVectorArgExpansion) {
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 8bebe608eece47..4656438d64c80a 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -459,9 +459,9 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
     }
     for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects) {
       OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
-         << ", Intrinsic::" << MappedIntr.Intrinsic;
+         << ", Intrinsic::" << MappedIntr.Intrinsic << ", ";
       for (const DXILArgSelect &ArgSelect : MappedIntr.Args) {
-        OS << ", (ArgSelect { ";
+        OS << "(ArgSelect { ";
         switch (ArgSelect.Type) {
         case DXILArgSelect::Type::Index:
           OS << "ArgSelect::Type::Index, ";
@@ -473,7 +473,7 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
           OS << "ArgSelect::Type::I32, ";
           break;
         }
-        OS << ArgSelect.Value << "})";
+        OS << ArgSelect.Value << "}), ";
       }
       OS << ")\n";
     }

>From 3159e490ddf96a4828dccd499ea51db3a0b769c8 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Wed, 6 Nov 2024 13:19:27 -0800
Subject: [PATCH 17/19] Got rid of DXILConstant in the tablegen

---
 llvm/lib/Target/DirectX/DXIL.td     | 24 +++++++++---------------
 llvm/utils/TableGen/DXILEmitter.cpp | 16 +++-------------
 2 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 2af2e8fda1831a..bb07c9492a1a4b 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -294,34 +294,28 @@ class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
   list<DXILAttribute> op_attrs = attrs;
 }
 
-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>;
-}
+defvar BarrierMode_DeviceMemoryBarrier              = 2;
+defvar BarrierMode_DeviceMemoryBarrierWithGroupSync = 3;
+defvar BarrierMode_GroupMemoryBarrier               = 8;
+defvar BarrierMode_GroupMemoryBarrierWithGroupSync  = 9;
+defvar BarrierMode_AllMemoryBarrier                 = 10;
+defvar BarrierMode_AllMemoryBarrierWithGroupSync    = 11;
 
 // Intrinsic arg selection
 class Arg {
   int index = -1;
-  DXILConstant value;
+  int value = 0;
   bit is_i8 = 0;
   bit is_i32 = 0;
 }
 class ArgSelect<int index_> : Arg {
   let index = index_;
 }
-class ArgI32<DXILConstant value_> : Arg {
+class ArgI32<int value_> : Arg {
   let value = value_;
   let is_i32 = 1;
 }
-class ArgI8<DXILConstant value_> : Arg {
+class ArgI8<int value_> : Arg {
   let value = value_;
   let is_i8 = 1;
 }
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 4656438d64c80a..b75696db410525 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -208,25 +208,15 @@ 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->getValueAsOptionalDef("value");
+          int Value = Arg->getValueAsInt("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");
+            ArgSelect.Value = 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");
+            ArgSelect.Value = Value;
           } else {
             if (Index < 0) {
               PrintFatalError(

>From d8b94b2fd43af76bb7139abfbda99157ddb7d64d Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Tue, 12 Nov 2024 16:42:18 -0800
Subject: [PATCH 18/19] Renamed everything, no longer duplicating the structs
 three times

---
 llvm/lib/Target/DirectX/DXIL.td            | 38 +++++-----
 llvm/lib/Target/DirectX/DXILOpLowering.cpp | 23 ++----
 llvm/utils/TableGen/DXILEmitter.cpp        | 86 +++++++++-------------
 3 files changed, 61 insertions(+), 86 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index bb07c9492a1a4b..ecd57240f316b2 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -302,28 +302,24 @@ defvar BarrierMode_AllMemoryBarrier                 = 10;
 defvar BarrierMode_AllMemoryBarrierWithGroupSync    = 11;
 
 // Intrinsic arg selection
-class Arg {
-  int index = -1;
-  int value = 0;
-  bit is_i8 = 0;
-  bit is_i32 = 0;
-}
-class ArgSelect<int index_> : Arg {
-  let index = index_;
-}
-class ArgI32<int value_> : Arg {
-  let value = value_;
-  let is_i32 = 1;
-}
-class ArgI8<int value_> : Arg {
-  let value = value_;
-  let is_i8 = 1;
+class IntrinArgSelectType;
+def IntrinArgSelect_Index : IntrinArgSelectType;
+def IntrinArgSelect_I8    : IntrinArgSelectType;
+def IntrinArgSelect_I32   : IntrinArgSelectType;
+
+class IntrinArgSelect<IntrinArgSelectType type_, int value_> {
+  IntrinArgSelectType type = type_;
+  int value = value_;
 }
+class IntrinArgIndex<int index> : IntrinArgSelect<IntrinArgSelect_Index, index>;
+class IntrinArgI8   <int value> : IntrinArgSelect<IntrinArgSelect_I8,    value>;
+class IntrinArgI32  <int value> : IntrinArgSelect<IntrinArgSelect_I32,   value>;
 
-class IntrinsicSelect<Intrinsic intrinsic_, list<Arg> args_> {
+class IntrinWithArgs<Intrinsic intrinsic_, list<IntrinArgSelect> arg_selects_> {
   Intrinsic intrinsic = intrinsic_;
-  list<Arg> args = args_;
+  list<IntrinArgSelect> arg_selects = arg_selects_;
 }
+class Intrin<Intrinsic intrinsic_> : IntrinWithArgs<intrinsic_, []> {}
 
 // Abstraction DXIL Operation
 class DXILOp<int opcode, DXILOpClass opclass> {
@@ -340,7 +336,7 @@ class DXILOp<int opcode, DXILOpClass opclass> {
   Intrinsic LLVMIntrinsic = ?;
 
   // Non-trivial LLVM Intrinsics DXIL Operation maps to
-  list<IntrinsicSelect> intrinsic_selects = [];
+  list<IntrinWithArgs> intrinsic_selects = [];
 
   // Result type of the op
   DXILOpParamType result;
@@ -867,9 +863,9 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
 def Barrier : DXILOp<80, barrier> {
   let Doc = "inserts a memory barrier in the shader";
   let intrinsic_selects = [
-    IntrinsicSelect<
+    IntrinWithArgs<
         int_dx_group_memory_barrier_with_group_sync,
-        [ ArgI32<BarrierMode_GroupMemoryBarrierWithGroupSync> ]>,
+        [ IntrinArgI32<BarrierMode_GroupMemoryBarrierWithGroupSync> ]>,
   ];
 
   let arguments = [Int32Ty];
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index 5f278b609690e2..6e2a1790a3f9ab 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -106,32 +106,25 @@ class OpLowerer {
     return false;
   }
 
-  struct ArgSelect {
-    enum class Type {
-      Index,
-      I8,
-      I32,
-    };
-    Type Type = Type::Index;
-    int Value = -1;
-  };
+#define DXIL_OP_INTRINSIC_ARG_SELECT_TYPES
+#include "DXILOperation.inc"
 
   [[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
-                                           ArrayRef<ArgSelect> ArgSelects) {
+                                           ArrayRef<IntrinArgSelect> ArgSelects) {
     bool IsVectorArgExpansion = isVectorArgExpansion(F);
     return replaceFunction(F, [&](CallInst *CI) -> Error {
       OpBuilder.getIRB().SetInsertPoint(CI);
       SmallVector<Value *> Args;
       if (ArgSelects.size()) {
-        for (const ArgSelect &A : ArgSelects) {
+        for (const IntrinArgSelect &A : ArgSelects) {
           switch (A.Type) {
-          case ArgSelect::Type::Index:
+          case IntrinArgSelect::Type::Index:
             Args.push_back(CI->getArgOperand(A.Value));
             break;
-          case ArgSelect::Type::I8:
+          case IntrinArgSelect::Type::I8:
             Args.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
             break;
-          case ArgSelect::Type::I32:
+          case IntrinArgSelect::Type::I32:
             Args.push_back(OpBuilder.getIRB().getInt32(A.Value));
             break;
           }
@@ -610,7 +603,7 @@ class OpLowerer {
 #define DXIL_OP_INTRINSIC(OpCode, Intrin, ...)                                 \
   case Intrin:                                                                 \
     HasErrors |=                                                               \
-        replaceFunctionWithOp(F, OpCode, ArrayRef<ArgSelect>{__VA_ARGS__});    \
+        replaceFunctionWithOp(F, OpCode, ArrayRef<IntrinArgSelect>{__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 b75696db410525..37ce442bdcdb85 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -32,20 +32,19 @@ using namespace llvm::dxil;
 
 namespace {
 
-struct DXILArgSelect {
-  enum class Type {
-    Index,
-    I32,
-    I8,
-  };
-  Type Type = Type::Index;
-  int Value = -1;
-};
 struct DXILIntrinsicSelect {
   StringRef Intrinsic;
-  SmallVector<DXILArgSelect, 4> Args;
+  SmallVector<const Record *> ArgSelectRecords;
 };
 
+static StringRef StripIntrinArgSelectTypePrefix(StringRef Type) {
+  StringRef Prefix = "IntrinArgSelect_";
+  if (!Type.starts_with(Prefix)) {
+    PrintFatalError("IntrinArgSelectType definintion must be prefixed with 'IntrinArgSelect_'");
+  }
+  return Type.substr(Prefix.size());
+}
+
 struct DXILOperationDesc {
   std::string OpName; // name of DXIL operation
   int OpCode;         // ID of DXIL operation
@@ -203,32 +202,9 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
       for (const Record *R : IntrinsicSelectRecords) {
         DXILIntrinsicSelect IntrSelect;
         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");
-          int Value = Arg->getValueAsInt("value");
-
-          DXILArgSelect ArgSelect;
-          if (IsI8) {
-            ArgSelect.Type = DXILArgSelect::Type::I8;
-            ArgSelect.Value = Value;
-          } else if (IsI32) {
-            ArgSelect.Type = DXILArgSelect::Type::I32;
-            ArgSelect.Value = 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));
+        auto Args = R->getValueAsListOfDefs("arg_selects");
+        for (const Record *ArgSelect : Args) {
+          IntrSelect.ArgSelectRecords.emplace_back(ArgSelect);
         }
         IntrinsicSelects.emplace_back(std::move(IntrSelect));
       }
@@ -441,6 +417,7 @@ static void emitDXILOpFunctionTypes(ArrayRef<DXILOperationDesc> Ops,
 /// \param Output stream
 static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
                                  raw_ostream &OS) {
+
   OS << "#ifdef DXIL_OP_INTRINSIC\n";
   OS << "\n";
   for (const auto &Op : Ops) {
@@ -450,20 +427,12 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
     for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects) {
       OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
          << ", Intrinsic::" << MappedIntr.Intrinsic << ", ";
-      for (const DXILArgSelect &ArgSelect : MappedIntr.Args) {
-        OS << "(ArgSelect { ";
-        switch (ArgSelect.Type) {
-        case DXILArgSelect::Type::Index:
-          OS << "ArgSelect::Type::Index, ";
-          break;
-        case DXILArgSelect::Type::I8:
-          OS << "ArgSelect::Type::I8, ";
-          break;
-        case DXILArgSelect::Type::I32:
-          OS << "ArgSelect::Type::I32, ";
-          break;
-        }
-        OS << ArgSelect.Value << "}), ";
+      for (const Record *ArgSelect : MappedIntr.ArgSelectRecords) {
+        std::string Type = ArgSelect->getValueAsDef("type")->getNameInitAsString();
+        int Value = ArgSelect->getValueAsInt("value");
+        OS << "(IntrinArgSelect{"
+          << "IntrinArgSelect::Type::" << StripIntrinArgSelectTypePrefix(Type) << ","
+          << Value << "}), ";
       }
       OS << ")\n";
     }
@@ -473,6 +442,22 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
   OS << "#endif\n\n";
 }
 
+static void emitDXILIntrinsicArgSelectTypes(const RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#ifdef DXIL_OP_INTRINSIC_ARG_SELECT_TYPES\n";
+  OS << "struct IntrinArgSelect {\n";
+  OS << "  enum class Type {\n";
+  for (const Record *Records : Records.getAllDerivedDefinitions("IntrinArgSelectType")) {
+    StringRef StrippedName = StripIntrinArgSelectTypePrefix(Records->getName());
+    OS << "    " << StrippedName << ",\n";
+  }
+  OS << "  };\n";
+  OS << "  Type Type;\n";
+  OS << "  int Value;\n";
+  OS << "};\n";
+  OS << "#undef DXIL_OP_INTRINSIC_ARG_SELECT_TYPES\n";
+  OS << "#endif\n\n";
+}
+
 /// Emit DXIL operation table
 /// \param A vector of DXIL Ops
 /// \param Output stream
@@ -613,6 +598,7 @@ static void emitDxilOperation(const RecordKeeper &Records, raw_ostream &OS) {
   emitDXILOpClasses(Records, OS);
   emitDXILOpParamTypes(Records, OS);
   emitDXILOpFunctionTypes(DXILOps, OS);
+  emitDXILIntrinsicArgSelectTypes(Records, OS);
   emitDXILIntrinsicMap(DXILOps, OS);
   OS << "#ifdef DXIL_OP_OPERATION_TABLE\n\n";
   emitDXILOperationTableDataStructs(Records, OS);

>From 1d55049d868f3b2e14c9e8430ae6bd9da454b94b Mon Sep 17 00:00:00 2001
From: Adam Yang <hanbyang at microsoft.com>
Date: Tue, 12 Nov 2024 17:05:33 -0800
Subject: [PATCH 19/19] Got rid of the default LLVMIntrinsic in DXILOp

---
 llvm/lib/Target/DirectX/DXIL.td     | 115 ++++++++++++++++------------
 llvm/utils/TableGen/DXILEmitter.cpp |   7 --
 2 files changed, 68 insertions(+), 54 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index ecd57240f316b2..8a62e06d67ffb4 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -315,11 +315,35 @@ class IntrinArgIndex<int index> : IntrinArgSelect<IntrinArgSelect_Index, index>;
 class IntrinArgI8   <int value> : IntrinArgSelect<IntrinArgSelect_I8,    value>;
 class IntrinArgI32  <int value> : IntrinArgSelect<IntrinArgSelect_I32,   value>;
 
-class IntrinWithArgs<Intrinsic intrinsic_, list<IntrinArgSelect> arg_selects_> {
+// Select which intrinsic to lower from for a DXILOp.
+// If the intrinsic is the only argument given to IntrinSelect, then the arguments of the intrinsic will be copied
+// in the same order. Example:
+//   let intrinsic_selects = [
+//     IntrinSelect<int_dx_my_intrinsic>,
+//     IntrinSelect<int_dx_my_intrinsic2>,
+//   ]
+//=========================================================================================
+// Using IntrinArgIndex<>, arguments of the intrinsic can be copied in specific order:
+//   let intrinsic_selects = [
+//     IntrinSelect<int_dx_my_intrinsic,
+//       [IntrinArgIndex<2>, IntrinArgIndex<1>, IntrinArgIndex<0>> ]
+//     >,
+//   ]
+//=========================================================================================
+// to the dxil op. This can be used in conjunction with IntrinArgIndex:
+//   let intrinsic_selects = [
+//     IntrinSelect<int_dx_wave_active_usum,
+//       [ IntrinArgIndex<0>, IntrinArgI8<0>, IntrinArgI8<1> ]
+//     >,
+//     IntrinSelect<int_dx_wave_active_sum,
+//       [ IntrinArgIndex<0>, IntrinArgI8<0>, IntrinArgI8<0> ]
+//     >,
+//   ]
+//
+class IntrinSelect<Intrinsic intrinsic_, list<IntrinArgSelect> arg_selects_=[]> {
   Intrinsic intrinsic = intrinsic_;
   list<IntrinArgSelect> arg_selects = arg_selects_;
 }
-class Intrin<Intrinsic intrinsic_> : IntrinWithArgs<intrinsic_, []> {}
 
 // Abstraction DXIL Operation
 class DXILOp<int opcode, DXILOpClass opclass> {
@@ -332,10 +356,7 @@ class DXILOp<int opcode, DXILOpClass opclass> {
   // Class of DXIL Operation.
   DXILOpClass OpClass = opclass;
 
-  // LLVM Intrinsic DXIL Operation maps to
-  Intrinsic LLVMIntrinsic = ?;
-
-  // Non-trivial LLVM Intrinsics DXIL Operation maps to
+  // LLVM Intrinsics DXIL Operation maps from
   list<IntrinWithArgs> intrinsic_selects = [];
 
   // Result type of the op
@@ -358,7 +379,7 @@ class DXILOp<int opcode, DXILOpClass opclass> {
 
 def Abs :  DXILOp<6, unary> {
   let Doc = "Returns the absolute value of the input.";
-  let LLVMIntrinsic = int_fabs;
+  let intrinsic_selects = [ IntrinSelect<int_fabs> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy, DoubleTy]>];
@@ -368,7 +389,7 @@ def Abs :  DXILOp<6, unary> {
 
 def Saturate :  DXILOp<7, unary> {
   let Doc = "Clamps a single or double precision floating point value to [0.0f...1.0f].";
-  let LLVMIntrinsic = int_dx_saturate;
+  let intrinsic_selects = [ IntrinSelect<int_dx_saturate> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy, DoubleTy]>];
@@ -378,7 +399,7 @@ def Saturate :  DXILOp<7, unary> {
 
 def IsInf :  DXILOp<9, isSpecialFloat> {
   let Doc = "Determines if the specified value is infinite.";
-  let LLVMIntrinsic = int_dx_isinf;
+  let intrinsic_selects = [ IntrinSelect<int_dx_isinf> ];
   let arguments = [OverloadTy];
   let result = Int1Ty;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -388,7 +409,7 @@ def IsInf :  DXILOp<9, isSpecialFloat> {
 
 def Cos :  DXILOp<12, unary> {
   let Doc = "Returns cosine(theta) for theta in radians.";
-  let LLVMIntrinsic = int_cos;
+  let intrinsic_selects = [ IntrinSelect<int_cos> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -398,7 +419,7 @@ def Cos :  DXILOp<12, unary> {
 
 def Sin :  DXILOp<13, unary> {
   let Doc = "Returns sine(theta) for theta in radians.";
-  let LLVMIntrinsic = int_sin;
+  let intrinsic_selects = [ IntrinSelect<int_sin> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -408,7 +429,7 @@ def Sin :  DXILOp<13, unary> {
 
 def Tan :  DXILOp<14, unary> {
   let Doc = "Returns tangent(theta) for theta in radians.";
-  let LLVMIntrinsic = int_tan;
+  let intrinsic_selects = [ IntrinSelect<int_tan> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -418,7 +439,7 @@ def Tan :  DXILOp<14, unary> {
 
 def ACos :  DXILOp<15, unary> {
   let Doc = "Returns the arccosine of the specified value.";
-  let LLVMIntrinsic = int_acos;
+  let intrinsic_selects = [ IntrinSelect<int_acos> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -428,7 +449,7 @@ def ACos :  DXILOp<15, unary> {
 
 def ASin :  DXILOp<16, unary> {
   let Doc = "Returns the arcsine of the specified value.";
-  let LLVMIntrinsic = int_asin;
+  let intrinsic_selects = [ IntrinSelect<int_asin> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -438,7 +459,7 @@ def ASin :  DXILOp<16, unary> {
 
 def ATan :  DXILOp<17, unary> {
   let Doc = "Returns the arctangent of the specified value.";
-  let LLVMIntrinsic = int_atan;
+  let intrinsic_selects = [ IntrinSelect<int_atan> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -448,7 +469,7 @@ def ATan :  DXILOp<17, unary> {
 
 def HCos :  DXILOp<18, unary> {
   let Doc = "Returns the hyperbolic cosine of the specified value.";
-  let LLVMIntrinsic = int_cosh;
+  let intrinsic_selects = [ IntrinSelect<int_cosh> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -458,7 +479,7 @@ def HCos :  DXILOp<18, unary> {
 
 def HSin :  DXILOp<19, unary> {
   let Doc = "Returns the hyperbolic sine of the specified value.";
-  let LLVMIntrinsic = int_sinh;
+  let intrinsic_selects = [ IntrinSelect<int_sinh> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -468,7 +489,7 @@ def HSin :  DXILOp<19, unary> {
 
 def HTan :  DXILOp<20, unary> {
   let Doc = "Returns the hyperbolic tan of the specified value.";
-  let LLVMIntrinsic = int_tanh;
+  let intrinsic_selects = [ IntrinSelect<int_tanh> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -479,7 +500,7 @@ def HTan :  DXILOp<20, unary> {
 def Exp2 :  DXILOp<21, unary> {
   let Doc = "Returns the base 2 exponential, or 2**x, of the specified value. "
             "exp2(x) = 2**x.";
-  let LLVMIntrinsic = int_exp2;
+  let intrinsic_selects = [ IntrinSelect<int_exp2> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -490,7 +511,7 @@ def Exp2 :  DXILOp<21, unary> {
 def Frac :  DXILOp<22, unary> {
   let Doc = "Returns a fraction from 0 to 1 that represents the decimal part "
             "of the input.";
-  let LLVMIntrinsic = int_dx_frac;
+  let intrinsic_selects = [ IntrinSelect<int_dx_frac> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -500,7 +521,7 @@ def Frac :  DXILOp<22, unary> {
 
 def Log2 :  DXILOp<23, unary> {
   let Doc = "Returns the base-2 logarithm of the specified value.";
-  let LLVMIntrinsic = int_log2;
+  let intrinsic_selects = [ IntrinSelect<int_log2> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -511,7 +532,7 @@ def Log2 :  DXILOp<23, unary> {
 def Sqrt :  DXILOp<24, unary> {
   let Doc = "Returns the square root of the specified floating-point value, "
             "per component.";
-  let LLVMIntrinsic = int_sqrt;
+  let intrinsic_selects = [ IntrinSelect<int_sqrt> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -522,7 +543,7 @@ def Sqrt :  DXILOp<24, unary> {
 def RSqrt :  DXILOp<25, unary> {
   let Doc = "Returns the reciprocal of the square root of the specified value. "
             "rsqrt(x) = 1 / sqrt(x).";
-  let LLVMIntrinsic = int_dx_rsqrt;
+  let intrinsic_selects = [ IntrinSelect<int_dx_rsqrt> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -533,7 +554,7 @@ def RSqrt :  DXILOp<25, unary> {
 def Round :  DXILOp<26, unary> {
   let Doc = "Returns the input rounded to the nearest integer within a "
             "floating-point type.";
-  let LLVMIntrinsic = int_roundeven;
+  let intrinsic_selects = [ IntrinSelect<int_roundeven> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -544,7 +565,7 @@ def Round :  DXILOp<26, unary> {
 def Floor :  DXILOp<27, unary> {
   let Doc =
       "Returns the largest integer that is less than or equal to the input.";
-  let LLVMIntrinsic = int_floor;
+  let intrinsic_selects = [ IntrinSelect<int_floor> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -555,7 +576,7 @@ def Floor :  DXILOp<27, unary> {
 def Ceil :  DXILOp<28, unary> {
   let Doc = "Returns the smallest integer that is greater than or equal to the "
             "input.";
-  let LLVMIntrinsic = int_ceil;
+  let intrinsic_selects = [ IntrinSelect<int_ceil> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -565,7 +586,7 @@ def Ceil :  DXILOp<28, unary> {
 
 def Trunc :  DXILOp<29, unary> {
   let Doc = "Returns the specified value truncated to the integer component.";
-  let LLVMIntrinsic = int_trunc;
+  let intrinsic_selects = [ IntrinSelect<int_trunc> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -575,7 +596,7 @@ def Trunc :  DXILOp<29, unary> {
 
 def Rbits :  DXILOp<30, unary> {
   let Doc = "Returns the specified value with its bits reversed.";
-  let LLVMIntrinsic = int_bitreverse;
+  let intrinsic_selects = [ IntrinSelect<int_bitreverse> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -596,7 +617,7 @@ def CountBits :  DXILOp<31, unaryBits> {
 
 def FMax :  DXILOp<35, binary> {
   let Doc = "Float maximum. FMax(a,b) = a > b ? a : b";
-  let LLVMIntrinsic = int_maxnum;
+  let intrinsic_selects = [ IntrinSelect<int_maxnum> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -607,7 +628,7 @@ def FMax :  DXILOp<35, binary> {
 
 def FMin :  DXILOp<36, binary> {
   let Doc = "Float minimum. FMin(a,b) = a < b ? a : b";
-  let LLVMIntrinsic = int_minnum;
+  let intrinsic_selects = [ IntrinSelect<int_minnum> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -618,7 +639,7 @@ def FMin :  DXILOp<36, binary> {
 
 def SMax :  DXILOp<37, binary> {
   let Doc = "Signed integer maximum. SMax(a,b) = a > b ? a : b";
-  let LLVMIntrinsic = int_smax;
+  let intrinsic_selects = [ IntrinSelect<int_smax> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -629,7 +650,7 @@ def SMax :  DXILOp<37, binary> {
 
 def SMin :  DXILOp<38, binary> {
   let Doc = "Signed integer minimum. SMin(a,b) = a < b ? a : b";
-  let LLVMIntrinsic = int_smin;
+  let intrinsic_selects = [ IntrinSelect<int_smin> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -640,7 +661,7 @@ def SMin :  DXILOp<38, binary> {
 
 def UMax :  DXILOp<39, binary> {
   let Doc = "Unsigned integer maximum. UMax(a,b) = a > b ? a : b";
-  let LLVMIntrinsic = int_umax;
+  let intrinsic_selects = [ IntrinSelect<int_umax> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -651,7 +672,7 @@ def UMax :  DXILOp<39, binary> {
 
 def UMin :  DXILOp<40, binary> {
   let Doc = "Unsigned integer minimum. UMin(a,b) = a < b ? a : b";
-  let LLVMIntrinsic = int_umin;
+  let intrinsic_selects = [ IntrinSelect<int_umin> ];
   let arguments = [OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -663,7 +684,7 @@ def UMin :  DXILOp<40, binary> {
 def FMad :  DXILOp<46, tertiary> {
   let Doc = "Floating point arithmetic multiply/add operation. fmad(m,a,b) = m "
             "* a + b.";
-  let LLVMIntrinsic = int_fmuladd;
+  let intrinsic_selects = [ IntrinSelect<int_fmuladd> ];
   let arguments = [OverloadTy, OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -675,7 +696,7 @@ def FMad :  DXILOp<46, tertiary> {
 def IMad :  DXILOp<48, tertiary> {
   let Doc = "Signed integer arithmetic multiply/add operation. imad(m,a,b) = m "
             "* a + b.";
-  let LLVMIntrinsic = int_dx_imad;
+  let intrinsic_selects = [ IntrinSelect<int_dx_imad> ];
   let arguments = [OverloadTy, OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -687,7 +708,7 @@ def IMad :  DXILOp<48, tertiary> {
 def UMad :  DXILOp<49, tertiary> {
   let Doc = "Unsigned integer arithmetic multiply/add operation. umad(m,a, = m "
             "* a + b.";
-  let LLVMIntrinsic = int_dx_umad;
+  let intrinsic_selects = [ IntrinSelect<int_dx_umad> ];
   let arguments = [OverloadTy, OverloadTy, OverloadTy];
   let result = OverloadTy;
   let overloads =
@@ -699,7 +720,7 @@ def UMad :  DXILOp<49, tertiary> {
 def Dot2 :  DXILOp<54, dot2> {
   let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + "
             "a[n]*b[n] where n is 0 to 1 inclusive";
-  let LLVMIntrinsic = int_dx_dot2;
+  let intrinsic_selects = [ IntrinSelect<int_dx_dot2> ];
   let arguments = !listsplat(OverloadTy, 4);
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -710,7 +731,7 @@ def Dot2 :  DXILOp<54, dot2> {
 def Dot3 :  DXILOp<55, dot3> {
   let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + "
             "a[n]*b[n] where n is 0 to 2 inclusive";
-  let LLVMIntrinsic = int_dx_dot3;
+  let intrinsic_selects = [ IntrinSelect<int_dx_dot3> ];
   let arguments = !listsplat(OverloadTy, 6);
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -721,7 +742,7 @@ def Dot3 :  DXILOp<55, dot3> {
 def Dot4 :  DXILOp<56, dot4> {
   let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + "
             "a[n]*b[n] where n is 0 to 3 inclusive";
-  let LLVMIntrinsic = int_dx_dot4;
+  let intrinsic_selects = [ IntrinSelect<int_dx_dot4> ];
   let arguments = !listsplat(OverloadTy, 8);
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy]>];
@@ -771,7 +792,7 @@ def CheckAccessFullyMapped : DXILOp<71, checkAccessFullyMapped> {
 
 def ThreadId :  DXILOp<93, threadId> {
   let Doc = "Reads the thread ID";
-  let LLVMIntrinsic = int_dx_thread_id;
+  let intrinsic_selects = [ IntrinSelect<int_dx_thread_id> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [Int32Ty]>];
@@ -781,7 +802,7 @@ def ThreadId :  DXILOp<93, threadId> {
 
 def GroupId :  DXILOp<94, groupId> {
   let Doc = "Reads the group ID (SV_GroupID)";
-  let LLVMIntrinsic = int_dx_group_id;
+  let intrinsic_selects = [ IntrinSelect<int_dx_group_id> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [Int32Ty]>];
@@ -791,7 +812,7 @@ def GroupId :  DXILOp<94, groupId> {
 
 def ThreadIdInGroup :  DXILOp<95, threadIdInGroup> {
   let Doc = "Reads the thread ID within the group  (SV_GroupThreadID)";
-  let LLVMIntrinsic = int_dx_thread_id_in_group;
+  let intrinsic_selects = [ IntrinSelect<int_dx_thread_id_in_group> ];
   let arguments = [OverloadTy];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [Int32Ty]>];
@@ -802,7 +823,7 @@ def ThreadIdInGroup :  DXILOp<95, threadIdInGroup> {
 def FlattenedThreadIdInGroup :  DXILOp<96, flattenedThreadIdInGroup> {
   let Doc = "Provides a flattened index for a given thread within a given "
             "group (SV_GroupIndex)";
-  let LLVMIntrinsic = int_dx_flattened_thread_id_in_group;
+  let intrinsic_selects = [ IntrinSelect<int_dx_flattened_thread_id_in_group> ];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [Int32Ty]>];
   let stages = [Stages<DXIL1_0, [compute, mesh, amplification, node]>];
@@ -834,7 +855,7 @@ def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> {
 
 def WaveIsFirstLane :  DXILOp<110, waveIsFirstLane> {
   let Doc = "returns 1 for the first lane in the wave";
-  let LLVMIntrinsic = int_dx_wave_is_first_lane;
+  let intrinsic_selects = [ IntrinSelect<int_dx_wave_is_first_lane> ];
   let arguments = [];
   let result = Int1Ty;
   let stages = [Stages<DXIL1_0, [all_stages]>];
@@ -843,7 +864,7 @@ def WaveIsFirstLane :  DXILOp<110, waveIsFirstLane> {
 
 def WaveReadLaneAt:  DXILOp<117, waveReadLaneAt> {
   let Doc = "returns the value from the specified lane";
-  let LLVMIntrinsic = int_dx_wave_readlane;
+  let intrinsic_selects = [ IntrinSelect<int_dx_wave_readlane> ];
   let arguments = [OverloadTy, Int32Ty];
   let result = OverloadTy;
   let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy, DoubleTy, Int1Ty, Int16Ty, Int32Ty, Int64Ty]>];
@@ -853,7 +874,7 @@ def WaveReadLaneAt:  DXILOp<117, waveReadLaneAt> {
 
 def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> {
   let Doc = "returns the index of the current lane in the wave";
-  let LLVMIntrinsic = int_dx_wave_getlaneindex;
+  let intrinsic_selects = [ IntrinSelect<int_dx_wave_getlaneindex> ];
   let arguments = [];
   let result = Int32Ty;
   let stages = [Stages<DXIL1_0, [all_stages]>];
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 37ce442bdcdb85..fbf9891b7c9853 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -184,13 +184,6 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
                            OpName);
   }
 
-  {
-    DXILIntrinsicSelect IntrSelect;
-    IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("LLVMIntrinsic"));
-    if (IntrSelect.Intrinsic.size())
-      IntrinsicSelects.emplace_back(std::move(IntrSelect));
-  }
-
   auto IntrinsicSelectRecords = R->getValueAsListOfDefs("intrinsic_selects");
   if (IntrinsicSelectRecords.size()) {
     if (IntrinsicSelects.size()) {



More information about the llvm-commits mailing list