Skip to content

Commit 6582d7d

Browse files
authored
[HLSL] Add WaveGetLaneCount() intrinsic to FE (#143127)
This commit adds code to lower WaveGetLaneCount() into the SPV or DXIL intrinsic. The backends will then need to lower the intrinsic into proper SPIR-V/DXIL. Related to #99159
1 parent dbec6e4 commit 6582d7d

File tree

7 files changed

+52
-0
lines changed

7 files changed

+52
-0
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,6 +4909,12 @@ def HLSLWaveReadLaneAt : LangBuiltin<"HLSL_LANG"> {
49094909
let Prototype = "void(...)";
49104910
}
49114911

4912+
def HLSLWaveGetLaneCount : LangBuiltin<"HLSL_LANG"> {
4913+
let Spellings = ["__builtin_hlsl_wave_get_lane_count"];
4914+
let Attributes = [NoThrow, Const];
4915+
let Prototype = "unsigned int()";
4916+
}
4917+
49124918
def HLSLClamp : LangBuiltin<"HLSL_LANG"> {
49134919
let Spellings = ["__builtin_hlsl_elementwise_clamp"];
49144920
let Attributes = [NoThrow, Const, CustomTypeChecking];

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
691691
return EmitRuntimeCall(
692692
Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID));
693693
}
694+
case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
695+
Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
696+
return EmitRuntimeCall(
697+
Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID));
698+
}
694699
case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
695700
// Due to the use of variadic arguments we must explicitly retreive them and
696701
// create our function type.

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class CGHLSLRuntime {
107107
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any)
108108
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits)
109109
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
110+
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveGetLaneCount, wave_get_lane_count)
110111
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
111112
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
112113
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,10 @@ _HLSL_AVAILABILITY(shadermodel, 6.0)
23502350
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_is_first_lane)
23512351
__attribute__((convergent)) bool WaveIsFirstLane();
23522352

2353+
_HLSL_AVAILABILITY(shadermodel, 6.0)
2354+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_get_lane_count)
2355+
__attribute__((convergent)) uint WaveGetLaneCount();
2356+
23532357
//===----------------------------------------------------------------------===//
23542358
// WaveReadLaneAt builtins
23552359
//===----------------------------------------------------------------------===//
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
2+
// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \
3+
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
4+
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
5+
// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \
6+
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
7+
8+
[numthreads(1, 1, 1)]
9+
void main() {
10+
uint a, b;
11+
// CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry()
12+
13+
// CHECK-SPIRV: %[[#loop_tok:]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %[[#entry_tok]]) ]
14+
while (a) {
15+
16+
// CHECK-DXIL: %[[#]] = call i32 @llvm.dx.wave.get.lane.count()
17+
// CHECK-SPIRV: %[[#]] = call spir_func i32 @llvm.spv.wave.get.lane.count()
18+
// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#loop_tok]]) ]
19+
a = WaveGetLaneCount();
20+
}
21+
22+
// CHECK-DXIL: %[[#]] = call i32 @llvm.dx.wave.get.lane.count()
23+
// CHECK-SPIRV: %[[#]] = call spir_func i32 @llvm.spv.wave.get.lane.count()
24+
// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#entry_tok]]) ]
25+
b = WaveGetLaneCount();
26+
}
27+
28+
// CHECK-DXIL: i32 @llvm.dx.wave.get.lane.count() #[[#attr:]]
29+
// CHECK-SPIRV: i32 @llvm.spv.wave.get.lane.count() #[[#attr:]]
30+
31+
// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}}
32+

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ def int_dx_wave_reduce_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType
148148
def int_dx_wave_reduce_usum : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
149149
def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
150150
def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
151+
def int_dx_wave_get_lane_count
152+
: DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent]>;
151153
def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
152154
def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
153155
def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>],

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ let TargetPrefix = "spv" in {
102102
def int_spv_wave_reduce_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
103103
def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
104104
def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
105+
def int_spv_wave_get_lane_count
106+
: DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent]>;
105107
def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
106108
def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
107109
def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;

0 commit comments

Comments
 (0)