From b325474c4aba52cca7e0bcd4eae02d23ca4ab9a3 Mon Sep 17 00:00:00 2001 From: kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> Date: Thu, 15 May 2025 11:59:15 -0500 Subject: Implement spec const for generic parameter (#7121) Close #6840. This PR add supports to use specialize constant in generic parameter, and that parameter can also be used as array size, e.g. following code should work: ``` struct MyStruct { float buffer[N]; } MyStruct s; ``` - Loose the restriction from Link-Time to SpecializationConstant when extract generic argument - Tweak the logic of how we decide whether a inst is hoistable. Besides checking existing hoistable flag of each IRInst, when we detect a IRInst's type is SpecConstRateType, we will treat that inst hoistable. Because IRInst in global scope can be deduplicated, and every SpecConstRateType inst should be in the global scope or IRGeneric scope (which will be at global scope after specialization). - Remove the SpecConstIntVal to IRInst map in IR lowering logic, because we already have way to deduplicate the global scope IR. --- tests/spirv/spec-constant-generic.slang | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/spirv/spec-constant-generic.slang (limited to 'tests/spirv') diff --git a/tests/spirv/spec-constant-generic.slang b/tests/spirv/spec-constant-generic.slang new file mode 100644 index 000000000..65eed2810 --- /dev/null +++ b/tests/spirv/spec-constant-generic.slang @@ -0,0 +1,53 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -output-using-type + +// CHECK: %[[C0:[0-9A-Za-z_]+]] = OpSpecConstant %int 32 +// CHECK: %[[C1:[0-9A-Za-z_]+]] = OpSpecConstant %int 2 +// CHECK: %[[COP0:[0-9A-Za-z_]+]] = OpSpecConstantOp %int SDiv %[[C0]] %[[C1]] +// CHECK: %[[ARR_TYPE:[0-9A-Za-z_]+]] = OpTypeArray %float %[[COP0]] +// CHECK: %[[PT_TYPE:[0-9A-Za-z_]+]] = OpTypePointer Function %[[ARR_TYPE]] + +[SpecializationConstant] +const int constValue0 = 32; + +[SpecializationConstant] +const int constValue1 = 2; + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +void func(out float buffer[constValue0 / constValue1]) +{ + for (uint i = 0; i < constValue0 / constValue1; i++) + { + buffer[i] = i; + } +} + +struct MyStruct +{ + float buffer[N / constValue1]; +} + +[shader("compute")] +[numthreads(1, 1, 1)] +void computeMain() +{ + // This test checks we can use spec constants for generic arguments, and also + // we can show that the array size is computed correctly. + // The function call shows that the two arrays are the same type. + MyStruct s; + // CHECK: OpVariable %[[PT_TYPE]] Function + + func(s.buffer); + + float temp = 0.0f; + for (uint i = 0; i < constValue0 / constValue1; i++) + { + temp += s.buffer[i] * 2; + } + + // Result will be (0 + localConst-1) * localConst = 15 * 16 = 240 + outputBuffer[0] = temp; + // BUF: 240 +} -- cgit v1.2.3