summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2017-10-11 14:39:10 -0700
committerGitHub <noreply@github.com>2017-10-11 14:39:10 -0700
commit331ddfa7bfe00bce628dd1aa0f721f24554dfedd (patch)
tree8d12ea176366ce2ffe478cf9e0c78639e2a9236e /tests
parent892b33996d527f430510793308cb9f0859d5041c (diff)
Bug fixing (#207)
* Bug fix for vector initializer lists When a vector was initialized with an initializer list: float4 f = { 0, 1, 2, 3 }; we were following the logic for `struct` types (since `vector<T,N>` is technically a `struct` declaration in our stdlib...), but the type has no field, so we were (silently!) ignoring the actual operands. I've applied a simple fix where we cast the operands to the element type of the vector, but a more complete fix will be needed sooner or later where we check the operand counts properly, etc. * Create implicit cast AST nodes when calling initializers The logic for dealing with implicit conversions was recently beefed up so that it would look at `__init` declarations in the target type, but in those cases the front-end would always create an `InvokeExpr` even when we would rather get an `ImplicitCastExpr` or (in the "rewrite" case) a `HiddenImplicitCastExpr`. I've fixed this up for now by constructing a dummy expression to stand in for the "original" call expression when creating the final call (luckily our `TypeCastExpr` is already just a specialized `InvokeExpr`). A better long-term solution might be to have implicit-ness or hidden-ness be modifiers or flags, rather than needing to use specialized forms of call nodes. * Fix subscript operator for `RWTexture1D` The index type was being declared as `uint1` instead of `uint`, and that created problems for downstream HLSL compilation when we introduced expressions like `uav[uint1(index)]` - the compiler would complain that a vector is not a valid index type. * Fix up constant-folding of integer casts. The old logic was checking for `InvokeExpr` before `TypeCastExpr`, but in the new setup a type cast *is* an `InvokeExpr`, so that case was never triggering. All of the constant-folding code really needs to be revisited, though, so that it can use a more general-purpose evaluation scheme like the bytecode (so that we can handle a moral equivalent of `constexpr` in the long run). * Fix implicit conversion costs for vector types A recent change made it so that the logic for looking up implicit conversions now uses declarations of initializers in the standard library (rather than hand-coding all the cases in `check.cpp`). One mistake made there was that we dropped the logic for computing implicit conversions between vectors of the same size, but different element types. These conversions were still allowed by a catch-all (generic) declaration in the standard library, but that declaration didn't include any implicit conversion cost logic (since it was generic, there was no single cost to use). This change explicitly enumerates the required conversions with their costs. It is a bit unfortunate that this is an O(N^2) amount of code for N base types, but that seems unavoidable for now. * Handle "lowering" of overloaded expressions If we are in the `-no-checking` mode and the user calls an overloaded function from an `__import`ed file in a way such that Slang can't resolve the intended overload, we were failing to emit the definitions of the potential callees. This change simply adds a case for `OverloadedExpr` in `lower.cpp` that explicitly lowers all the declarations that might have been referenced. - There is a potentially for breakage here if we are outputting GLSL and one of the overloads is stage-specific. - A more refined approach might try to recognize which over the overloaded options are even potentially applicable, and then output only those, but doing this would be way more complicated. I've added a test case for this behavior, but it is a bit brittle because we need to confirm that we still produce the same error message as unmodified HLSL.
Diffstat (limited to 'tests')
-rw-r--r--tests/bugs/array-size-static-const.hlsl14
-rw-r--r--tests/bugs/empty.slang5
-rw-r--r--tests/bugs/implicit-conversion-binary-op.hlsl16
-rw-r--r--tests/bugs/import-overload-error.hlsl19
-rw-r--r--tests/bugs/import-overload-error.slang4
-rw-r--r--tests/bugs/uav-write-index.hlsl31
-rw-r--r--tests/bugs/vec-init-list.hlsl19
7 files changed, 108 insertions, 0 deletions
diff --git a/tests/bugs/array-size-static-const.hlsl b/tests/bugs/array-size-static-const.hlsl
new file mode 100644
index 000000000..fe15d402d
--- /dev/null
+++ b/tests/bugs/array-size-static-const.hlsl
@@ -0,0 +1,14 @@
+// array-size-static-const.hlsl
+//TEST:COMPARE_HLSL: -profile cs_5_0 -target dxbc-assembly
+
+// The bug in this case is that were have a (hidden)
+// cast from the `uint` constant to `int` to get
+// the size of the array, and this cast was tripping
+// up the constant-folding logic.
+
+static const uint n = 16;
+groupshared float b[n];
+
+[numthreads(1,1,1)]
+void main()
+{}
diff --git a/tests/bugs/empty.slang b/tests/bugs/empty.slang
new file mode 100644
index 000000000..ac4b3b7ca
--- /dev/null
+++ b/tests/bugs/empty.slang
@@ -0,0 +1,5 @@
+//TEST_IGNORE_FILE:
+// empty.slang
+
+// This is just an empty file so that tets
+// that need to `__import` something can.
diff --git a/tests/bugs/implicit-conversion-binary-op.hlsl b/tests/bugs/implicit-conversion-binary-op.hlsl
new file mode 100644
index 000000000..75ff737da
--- /dev/null
+++ b/tests/bugs/implicit-conversion-binary-op.hlsl
@@ -0,0 +1,16 @@
+// implicit-conversion-binary-op.hlsl
+//TEST:COMPARE_HLSL: -profile ps_5_0 -target dxbc-assembly
+
+// Make sure that we can pick resolve the right overload
+// to call when applying a binary operator to vectors
+// with different element types. We should pick
+// the "better" of the two element types, and not
+// get an ambiguity error.
+
+float4 main(
+ float4 a : A,
+ uint4 b : B
+ ) : SV_Target
+{
+ return a * b;
+}
diff --git a/tests/bugs/import-overload-error.hlsl b/tests/bugs/import-overload-error.hlsl
new file mode 100644
index 000000000..328bb5b26
--- /dev/null
+++ b/tests/bugs/import-overload-error.hlsl
@@ -0,0 +1,19 @@
+//TEST:COMPARE_HLSL: -profile cs_5_0 -target dxbc-assembly -no-checking
+
+#ifdef __SLANG__
+__import import_overload_error;
+#else
+
+void foo(int a) {}
+void foo(float b) {}
+
+#endif
+
+void main()
+{
+// Note(tfoley): futzing around with tokens to
+// make sure error message gets reported at a
+// consistent location between languages.
+int a;
+foo();
+}
diff --git a/tests/bugs/import-overload-error.slang b/tests/bugs/import-overload-error.slang
new file mode 100644
index 000000000..e52ce78bb
--- /dev/null
+++ b/tests/bugs/import-overload-error.slang
@@ -0,0 +1,4 @@
+//TEST_IGNORE_FILE:
+
+void foo(int a) {}
+void foo(float b) {}
diff --git a/tests/bugs/uav-write-index.hlsl b/tests/bugs/uav-write-index.hlsl
new file mode 100644
index 000000000..667c73e89
--- /dev/null
+++ b/tests/bugs/uav-write-index.hlsl
@@ -0,0 +1,31 @@
+//TEST:COMPARE_HLSL: -profile cs_5_0 -target dxbc-assembly -no-checking
+
+// Make sure we handle complex UAV write patterns
+
+// Force import of Slang to ensure that some
+// checking takes place:
+#ifdef __SLANG__
+__import empty;
+#endif
+
+struct Bar
+{
+ uint bar;
+};
+
+RWStructuredBuffer<Bar> gUAV : register(u0);
+
+void foo(RWTexture1D<float2> uav)
+{
+ uint index = gUAV.IncrementCounter();
+ gUAV[index].bar = 1;
+ uav[index] = float2(0,0);
+}
+
+RWTexture1D<float2> gUAV2 : register(u1);
+
+[numthreads(1,1,1)]
+void main()
+{
+ foo(gUAV2);
+}
diff --git a/tests/bugs/vec-init-list.hlsl b/tests/bugs/vec-init-list.hlsl
new file mode 100644
index 000000000..be1bc5c6f
--- /dev/null
+++ b/tests/bugs/vec-init-list.hlsl
@@ -0,0 +1,19 @@
+//TEST:COMPARE_HLSL: -profile vs_5_0 -target dxbc-assembly
+
+// Check handling of initializer list for vector
+
+cbuffer C : register(b0)
+{
+ float4 a;
+};
+
+float w0(float x) { return x; }
+float w1(float x) { return x; }
+float w2(float x) { return x; }
+float w3(float x) { return x; }
+
+float4 main() : SV_Position
+{
+ float4 wx = { w0(a.x), w1(a.x), w2(a.x), w3(a.x), };
+ return wx;
+}