Skip to content

Commit 7674630

Browse files
committed
Add SPIR-V intrinsic. Update tests.
1 parent 0789430 commit 7674630

File tree

5 files changed

+48
-38
lines changed

5 files changed

+48
-38
lines changed

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/Decl.h"
1919
#include "clang/Basic/TargetOptions.h"
2020
#include "llvm/IR/IntrinsicsDirectX.h"
21+
#include "llvm/IR/IntrinsicsSPIRV.h"
2122
#include "llvm/IR/Metadata.h"
2223
#include "llvm/IR/Module.h"
2324
#include "llvm/Support/FormatVariadic.h"
@@ -342,8 +343,19 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
342343
return B.CreateCall(FunctionCallee(DxGroupIndex));
343344
}
344345
if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
345-
llvm::Function *DxThreadID = CGM.getIntrinsic(Intrinsic::dx_thread_id);
346-
return buildVectorInput(B, DxThreadID, Ty);
346+
llvm::Function *ThreadIDIntrinsic;
347+
switch (CGM.getTarget().getTriple().getArch()) {
348+
case llvm::Triple::dxil:
349+
ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_thread_id);
350+
break;
351+
case llvm::Triple::spirv:
352+
ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::spv_thread_id);
353+
break;
354+
default:
355+
llvm_unreachable("Input semantic not supported by target");
356+
break;
357+
}
358+
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
347359
}
348360
assert(false && "Unhandled parameter attribute");
349361
return nullptr;
Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
1-
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
2+
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
23

34
// Make sure SV_DispatchThreadID translated into dx.thread.id.
45

5-
const RWBuffer<float> In;
6-
RWBuffer<float> Out;
7-
8-
// CHECK: define void @foo()
9-
// CHECK: %[[ID:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 0)
10-
// CHECK: call void @"?foo@@YAXH@Z"(i32 %[[ID]])
6+
// CHECK: define void @foo()
7+
// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.dx.thread.id(i32 0)
8+
// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.spv.thread.id(i32 0)
9+
// CHECK: call void @{{.*}}foo{{.*}}(i32 %[[#ID]])
1110
[shader("compute")]
1211
[numthreads(8,8,1)]
13-
void foo(uint Idx : SV_DispatchThreadID) {
14-
Out[Idx] = In[Idx];
15-
}
12+
void foo(uint Idx : SV_DispatchThreadID) {}
1613

17-
// CHECK: define void @bar()
18-
// CHECK: %[[ID_X:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 0)
19-
// CHECK: %[[ID_X_:[0-9a-zA-Z]+]] = insertelement <2 x i32> poison, i32 %[[ID_X]], i64 0
20-
// CHECK: %[[ID_Y:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 1)
21-
// CHECK: %[[ID_XY:[0-9a-zA-Z]+]] = insertelement <2 x i32> %[[ID_X_]], i32 %[[ID_Y]], i64 1
22-
// CHECK: call void @"?bar@@YAXT?$__vector@H$01@__clang@@@Z"(<2 x i32> %[[ID_XY]])
14+
// CHECK: define void @bar()
15+
// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.dx.thread.id(i32 0)
16+
// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.spv.thread.id(i32 0)
17+
// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
18+
// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id(i32 1)
19+
// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.spv.thread.id(i32 1)
20+
// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
21+
// CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
2322
[shader("compute")]
2423
[numthreads(8,8,1)]
25-
void bar(uint2 Idx : SV_DispatchThreadID) {
26-
Out[Idx.y] = In[Idx.x];
27-
}
24+
void bar(uint2 Idx : SV_DispatchThreadID) {}
2825

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ let TargetPrefix = "spv" in {
4141
def int_spv_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>]>;
4242

4343
// The following intrinsic(s) are mirrored from IntrinsicsDirectX.td for HLSL support.
44+
def int_spv_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
4445
def int_spv_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
4546
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
4647
}

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ class SPIRVInstructionSelector : public InstructionSelector {
195195
bool selectLog10(Register ResVReg, const SPIRVType *ResType,
196196
MachineInstr &I) const;
197197

198-
bool selectDXThreadId(Register ResVReg, const SPIRVType *ResType,
199-
MachineInstr &I) const;
198+
bool selectSpvThreadId(Register ResVReg, const SPIRVType *ResType,
199+
MachineInstr &I) const;
200200

201201
bool selectUnmergeValues(MachineInstr &I) const;
202202

@@ -1619,8 +1619,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
16191619
.addUse(I.getOperand(2).getReg())
16201620
.addUse(I.getOperand(3).getReg());
16211621
break;
1622-
case Intrinsic::dx_thread_id:
1623-
return selectDXThreadId(ResVReg, ResType, I);
1622+
case Intrinsic::spv_thread_id:
1623+
return selectSpvThreadId(ResVReg, ResType, I);
16241624
default:
16251625
llvm_unreachable("Intrinsic selection not implemented");
16261626
}
@@ -1871,9 +1871,9 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg,
18711871
return Result;
18721872
}
18731873

1874-
bool SPIRVInstructionSelector::selectDXThreadId(Register ResVReg,
1875-
const SPIRVType *ResType,
1876-
MachineInstr &I) const {
1874+
bool SPIRVInstructionSelector::selectSpvThreadId(Register ResVReg,
1875+
const SPIRVType *ResType,
1876+
MachineInstr &I) const {
18771877
// DX intrinsic: @llvm.dx.thread.id(i32)
18781878
// ID Name Description
18791879
// 93 ThreadId reads the thread ID

llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SV_DispatchThreadID.ll

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
; RUN: llc -O0 -mtriple=spirv-vulkan-unknown %s -o - | FileCheck %s
22
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-unknown %s -o - -filetype=obj | spirv-val %}
33

4-
; This file generated from the following HLSL:
5-
; clang -cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - DispatchThreadID.hlsl
6-
;
4+
; This file generated from the following command:
5+
; clang -cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header - -o - <<EOF
76
; [shader("compute")]
87
; [numthreads(1,1,1)]
98
; void main(uint3 ID : SV_DispatchThreadID) {}
9+
; EOF
1010

1111
; CHECK-DAG: %[[#int:]] = OpTypeInt 32 0
1212
; CHECK-DAG: %[[#v3int:]] = OpTypeVector %[[#int]] 3
@@ -19,8 +19,8 @@
1919
; CHECK-DAG: OpDecorate %[[#GlobalInvocationId]] LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
2020
; CHECK-DAG: OpDecorate %[[#GlobalInvocationId]] BuiltIn GlobalInvocationId
2121

22-
; ModuleID = 'DispatchThreadID.hlsl'
23-
source_filename = "DispatchThreadID.hlsl"
22+
; ModuleID = '-'
23+
source_filename = "-"
2424
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
2525
target triple = "spirv-unknown-vulkan-library"
2626

@@ -38,21 +38,21 @@ entry:
3838

3939
; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]]
4040
; CHECK: %[[#load0:]] = OpCompositeExtract %[[#int]] %[[#load]] 0
41-
%0 = call i32 @llvm.dx.thread.id(i32 0)
41+
%0 = call i32 @llvm.spv.thread.id(i32 0)
4242

4343
; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load0]] %[[#tempvar]] 0
4444
%1 = insertelement <3 x i32> poison, i32 %0, i64 0
4545

4646
; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]]
4747
; CHECK: %[[#load1:]] = OpCompositeExtract %[[#int]] %[[#load]] 1
48-
%2 = call i32 @llvm.dx.thread.id(i32 1)
48+
%2 = call i32 @llvm.spv.thread.id(i32 1)
4949

5050
; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load1]] %[[#tempvar]] 1
5151
%3 = insertelement <3 x i32> %1, i32 %2, i64 1
5252

5353
; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]]
5454
; CHECK: %[[#load2:]] = OpCompositeExtract %[[#int]] %[[#load]] 2
55-
%4 = call i32 @llvm.dx.thread.id(i32 2)
55+
%4 = call i32 @llvm.spv.thread.id(i32 2)
5656

5757
; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load2]] %[[#tempvar]] 2
5858
%5 = insertelement <3 x i32> %3, i32 %4, i64 2
@@ -62,7 +62,7 @@ entry:
6262
}
6363

6464
; Function Attrs: nounwind willreturn memory(none)
65-
declare i32 @llvm.dx.thread.id(i32) #2
65+
declare i32 @llvm.spv.thread.id(i32) #2
6666

6767
attributes #0 = { noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
6868
attributes #1 = { norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
@@ -73,4 +73,4 @@ attributes #2 = { nounwind willreturn memory(none) }
7373

7474
!0 = !{i32 1, !"wchar_size", i32 4}
7575
!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
76-
!2 = !{!"clang version 19.0.0git ([email protected]:llvm/llvm-project.git c9afeaa6434a61b3b3a57c8eda6d2cfb25ab675b)"}
76+
!2 = !{!"clang version 19.0.0git ([email protected]:llvm/llvm-project.git 91600507765679e92434ec7c5edb883bf01f847f)"}

0 commit comments

Comments
 (0)