summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDarren Wihandi <65404740+fairywreath@users.noreply.github.com>2025-05-30 01:04:27 -0400
committerGitHub <noreply@github.com>2025-05-29 22:04:27 -0700
commitaa3e6bdbe024355b07f6a61806024b248528fe4b (patch)
tree3f11539df4dfd0dfcb7df2b4e7ce877ab9b84179 /tests
parent61f66c116ab10fdfd37492056aab7dfa4276a0b7 (diff)
Fix SPIRV `OpSpecConstantOp` emit (#7158)
* Fix SPIRV specialization constant with floating-point operations * Improve test * WIP * Restrict `OpSpecConstantOp` allowed operations based on SPIRV specifications * Fix typo on floating type check * Emit error on float to int spec cosnt int val casts
Diffstat (limited to 'tests')
-rw-r--r--tests/spirv/spec-constant-int-val-float-to-int-cast.slang15
-rw-r--r--tests/spirv/spec-constant-operations.slang84
2 files changed, 99 insertions, 0 deletions
diff --git a/tests/spirv/spec-constant-int-val-float-to-int-cast.slang b/tests/spirv/spec-constant-int-val-float-to-int-cast.slang
new file mode 100644
index 000000000..9f9f96178
--- /dev/null
+++ b/tests/spirv/spec-constant-int-val-float-to-int-cast.slang
@@ -0,0 +1,15 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -entry computeMain -stage compute -target spirv
+
+// CHECK: error 38041: cannot cast non-integer specialization
+// CHECK-NEXT: const float X
+
+[[SpecializationConstant]]
+const float X = 10.0;
+
+[shader("compute")]
+[numthreads(32, 1, 1)]
+void computeMain() : SV_Target
+{
+ float arr[int(X)];
+ float a = arr[0];
+}
diff --git a/tests/spirv/spec-constant-operations.slang b/tests/spirv/spec-constant-operations.slang
new file mode 100644
index 000000000..86d16ef34
--- /dev/null
+++ b/tests/spirv/spec-constant-operations.slang
@@ -0,0 +1,84 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -output-using-type -emit-spirv-directly
+
+//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<float> outputBuffer;
+
+// `OpSpecConstantOp` can only contain integer operations when targeting Vulkan SPIRV, not floating-point operations.
+// This test checks that floating-point operations that strictly contain specialization constant variables are not declared with `OpSpecContantOp`,
+// while integer operations that strictly contain specializaton constant operands are declared as `OpSpecConstantOp`.
+
+// CHECK-DAG: OpSpecConstant %float 1
+// CHECK-DAG: OpSpecConstant %ulong 256
+// CHECK-DAG: OpSpecConstant %float 100
+// CHECK-DAG: OpSpecConstantOp %half FConvert
+// CHECK-DAG: OpSpecConstantOp %int UConvert
+
+// CHECK-NOT: OpSpecConstantOp {{.*}} FAdd
+// CHECK-NOT: OpSpecConstantOp {{.*}} FSub
+// CHECK-NOT: OpSpecConstantOp {{.*}} FMul
+// CHECK-NOT: OpSpecConstantOp {{.*}} FDiv
+// CHECK-NOT: OpSpecConstantOp {{.*}} SpvOpConvertUToF
+// CHECK-NOT: OpSpecConstantOp {{.*}} SpvOpConvertFToU
+
+[[SpecializationConstant]]
+const float X = 1.0;
+[[SpecializationConstant]]
+const uint64_t Y = 256;
+[[SpecializationConstant]]
+const float Z = 100.0;
+
+int func1()
+{
+ // Test float-to-float and int-to-int conversions.
+ int a = int(Y);
+ half b = half(X);
+ int16_t c = int16_t(Y);
+
+ // Test comparisons.
+ if (X < 2.0)
+ {
+ a = 3;
+ }
+ else if (X > 5.0)
+ {
+ a = 5;
+ }
+
+ if (Y < 200)
+ {
+ b = 2.0h;
+ }
+ else if (Y > 500)
+ {
+ b = 5.0h;
+ }
+
+ return a + int(b) + int(c);
+}
+
+float func2()
+{
+ // Test floating-point arithmetic.
+ float a = X + Z;
+ a += (X - Z);
+ a += (X * Z);
+ a += (X / Z);
+
+ return a;
+}
+
+float func3()
+{
+ // Test float-to-int and int-to-float conversions.
+ int a = int(Z) * 2;
+ return float(Y) + float(a);
+}
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+ // BUF: 818.01
+ outputBuffer[0] = float(func1()) + func2() + func3();
+}