diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt
--- a/llvm/include/llvm/IR/CMakeLists.txt
+++ b/llvm/include/llvm/IR/CMakeLists.txt
@@ -8,6 +8,7 @@
 tablegen(LLVM IntrinsicsAMDGPU.h -gen-intrinsic-enums -intrinsic-prefix=amdgcn)
 tablegen(LLVM IntrinsicsARM.h -gen-intrinsic-enums -intrinsic-prefix=arm)
 tablegen(LLVM IntrinsicsBPF.h -gen-intrinsic-enums -intrinsic-prefix=bpf)
+tablegen(LLVM IntrinsicsDXIL.h -gen-intrinsic-enums -intrinsic-prefix=dxil)
 tablegen(LLVM IntrinsicsHexagon.h -gen-intrinsic-enums -intrinsic-prefix=hexagon)
 tablegen(LLVM IntrinsicsMips.h -gen-intrinsic-enums -intrinsic-prefix=mips)
 tablegen(LLVM IntrinsicsNVPTX.h -gen-intrinsic-enums -intrinsic-prefix=nvvm)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -2044,3 +2044,4 @@
 include "llvm/IR/IntrinsicsRISCV.td"
 include "llvm/IR/IntrinsicsSPIRV.td"
 include "llvm/IR/IntrinsicsVE.td"
+include "llvm/IR/IntrinsicsDXIL.td"
diff --git a/llvm/include/llvm/IR/IntrinsicsDXIL.td b/llvm/include/llvm/IR/IntrinsicsDXIL.td
new file mode 100644
--- /dev/null
+++ b/llvm/include/llvm/IR/IntrinsicsDXIL.td
@@ -0,0 +1,20 @@
+//===- IntrinsicsDXIL.td - Defines DXIL intrinsics -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the R600-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "dxil" in {
+
+def int_dxil_threadId : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
+def int_dxil_groupId : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
+def int_dxil_threadIdInGroup : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
+def int_dxil_flattenedThreadIdInGroup : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrWillReturn]>;
+
+}
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -22,10 +22,14 @@
 
 def Unary : dxil_class<"Unary">;
 def Binary : dxil_class<"Binary">;
+def FlattenedThreadIdInGroupClass : dxil_class<"FlattenedThreadIdInGroup">;
+def ThreadIdInGroupClass : dxil_class<"ThreadIdInGroup">;
+def ThreadIdClass : dxil_class<"ThreadId">;
+def GroupIdClass : dxil_class<"GroupId">;
 
 def binary_uint : dxil_category<"Binary uint">;
 def unary_float : dxil_category<"Unary float">;
-
+def ComputeID : dxil_category<"Compute/Mesh/Amplification shader">;
 
 
 // The parameter description for a DXIL instruction
@@ -105,3 +109,36 @@
   ],
   ["uints"]>,
   dxil_map_intrinsic<int_umax>;
+
+def ThreadId :dxil_op< "ThreadId", 93,  ThreadIdClass, ComputeID, "reads the thread ID", "i32;",  "rn",
+  [
+    dxil_param<0,  "i32",  "",  "thread ID component">,
+    dxil_param<1,  "i32",  "opcode",  "DXIL opcode">,
+    dxil_param<2,  "i32",  "component",  "component to read (x,y,z)">
+  ]>,
+  dxil_map_intrinsic<int_dxil_threadId>;
+
+def GroupId :dxil_op< "GroupId", 94,  GroupIdClass, ComputeID, "reads the group ID (SV_GroupID)", "i32;",  "rn",
+  [
+    dxil_param<0,  "i32",  "",  "group ID component">,
+    dxil_param<1,  "i32",  "opcode",  "DXIL opcode">,
+    dxil_param<2,  "i32",  "component",  "component to read">
+  ]>,
+  dxil_map_intrinsic<int_dxil_groupId>;
+
+def ThreadIdInGroup :dxil_op< "ThreadIdInGroup", 95,  ThreadIdInGroupClass, ComputeID,
+  "reads the thread ID within the group (SV_GroupThreadID)", "i32;",  "rn",
+  [
+    dxil_param<0,  "i32",  "",  "thread ID in group component">,
+    dxil_param<1,  "i32",  "opcode",  "DXIL opcode">,
+    dxil_param<2,  "i32",  "component",  "component to read (x,y,z)">
+  ]>,
+  dxil_map_intrinsic<int_dxil_threadIdInGroup>;
+
+def FlattenedThreadIdInGroup :dxil_op< "FlattenedThreadIdInGroup", 96,  FlattenedThreadIdInGroupClass, ComputeID,
+   "provides a flattened index for a given thread within a given group (SV_GroupIndex)", "i32;",  "rn",
+  [
+    dxil_param<0,  "i32",  "",  "result">,
+    dxil_param<1,  "i32",  "opcode",  "DXIL opcode">
+  ]>,
+  dxil_map_intrinsic<int_dxil_flattenedThreadIdInGroup>;
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -17,6 +17,7 @@
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsDXIL.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Pass.h"
diff --git a/llvm/test/CodeGen/DirectX/comput_ids.ll b/llvm/test/CodeGen/DirectX/comput_ids.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/comput_ids.ll
@@ -0,0 +1,51 @@
+; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
+
+; Make sure dxil operation function calls for all ComputeID dxil operations are generated.
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-pc-shadermodel6.7-library"
+
+; CHECK-LABEL:test_thread_id
+; Function Attrs: noinline nounwind optnone
+define i32 @test_thread_id(i32 %a) #0 {
+entry:
+; CHECK:call i32 @dx.op.threadId.i32(i32 93, i32 %{{.*}})
+  %0 = call i32 @llvm.dxil.threadId(i32 %a)
+  ret i32 %0
+}
+
+; CHECK-LABEL:test_group_id
+; Function Attrs: noinline nounwind optnone
+define i32 @test_group_id(i32 %a) #0 {
+entry:
+; CHECK:call i32 @dx.op.groupId.i32(i32 94, i32 %{{.*}})
+  %0 = call i32 @llvm.dxil.groupId(i32 %a)
+  ret i32 %0
+}
+
+; CHECK-LABEL:test_thread_id_in_group
+; Function Attrs: noinline nounwind optnone
+define i32 @test_thread_id_in_group(i32 %a) #0 {
+entry:
+; CHECK:call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 %{{.*}})
+  %0 = call i32 @llvm.dxil.threadIdInGroup(i32 %a)
+  ret i32 %0
+}
+
+; CHECK-LABEL:test_flattened_thread_id_in_group
+; Function Attrs: noinline nounwind optnone
+define i32 @test_flattened_thread_id_in_group() #0 {
+entry:
+; CHECK:call i32 @dx.op.flattenedThreadIdInGroup.i32(i32 96)
+  %0 = call i32 @llvm.dxil.flattenedThreadIdInGroup()
+  ret i32 %0
+}
+
+; Function Attrs: nounwind readnone willreturn
+declare i32 @llvm.dxil.threadId(i32) #1
+declare i32 @llvm.dxil.groupId(i32) #1
+declare i32 @llvm.dxil.flattenedThreadIdInGroup() #1
+declare i32 @llvm.dxil.threadIdInGroup(i32) #1
+
+attributes #0 = { noinline nounwind }
+attributes #1 = { nounwind readnone willreturn }