summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2017-10-12 10:30:48 -0700
committerGitHub <noreply@github.com>2017-10-12 10:30:48 -0700
commit9a231a5efb0ddce635e7e40c2d5b086ff4bd389a (patch)
tree7e9d6a2b97928820687fbc04927bf2224964d40f
parent28ca4dc60aecc0acda8b364d0553a72d2e6c7964 (diff)
Do loop fix (#209)
* Bug fix: emit logic for `do` loops This case was never tested, and I was outputting some garbage characters. This comit fixes the codegen and adds a test case. * Bug fix: make sure to pass through `[allow_uav_condition]` This also fixes the standard library definition of `IncrementCounter()` so that it returns a `uint` instead of `void`.
-rw-r--r--source/slang/emit.cpp8
-rw-r--r--source/slang/hlsl.meta.slang2
-rw-r--r--source/slang/hlsl.meta.slang.h2
-rw-r--r--tests/bugs/do-loop.hlsl35
-rw-r--r--tests/hlsl/simple/allow-uav-conditional.hlsl19
5 files changed, 62 insertions, 4 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 8483caefc..7d7553bc5 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2637,6 +2637,10 @@ struct EmitVisitor
{
Emit("[unroll]");
}
+ else if(getText(attr->getName()) == "allow_uav_condition")
+ {
+ Emit("[allow_uav_condition]");
+ }
}
}
@@ -2790,11 +2794,11 @@ struct EmitVisitor
{
EmitLoopAttributes(doWhileStmt);
- Emit("do(");
+ Emit("do\n");
EmitBlockStmt(doWhileStmt->Statement);
Emit(" while(");
EmitExpr(doWhileStmt->Predicate);
- Emit(")\n");
+ Emit(");\n");
return;
}
else if (auto discardStmt = stmt.As<DiscardStmt>())
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 237ca89e4..442903e6f 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -194,7 +194,7 @@ struct RWStructuredBuffer
out uint numStructs,
out uint stride);
- __intrinsic_op void IncrementCounter();
+ __intrinsic_op uint IncrementCounter();
__intrinsic_op T Load(int location);
__intrinsic_op T Load(int location, out uint status);
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index 96cdd4f11..84f5e89ed 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -196,7 +196,7 @@ sb << " __intrinsic_op void GetDimensions(\n";
sb << " out uint numStructs,\n";
sb << " out uint stride);\n";
sb << "\n";
-sb << " __intrinsic_op void IncrementCounter();\n";
+sb << " __intrinsic_op uint IncrementCounter();\n";
sb << "\n";
sb << " __intrinsic_op T Load(int location);\n";
sb << " __intrinsic_op T Load(int location, out uint status);\n";
diff --git a/tests/bugs/do-loop.hlsl b/tests/bugs/do-loop.hlsl
new file mode 100644
index 000000000..eea62e92a
--- /dev/null
+++ b/tests/bugs/do-loop.hlsl
@@ -0,0 +1,35 @@
+//TEST:COMPARE_HLSL: -profile vs_5_0 -target dxbc-assembly
+
+// Check output for `do` loops
+
+cbuffer C : register(b0)
+{
+ int n;
+};
+
+float4 main() : SV_Position
+{
+ float4 x = 0;
+ int i = n;
+ {
+ do
+ {
+ x = (x + (float)1) * x;
+
+ // Note(tfoley): The "right" thing here would be
+ // `i--`, but that leads to a subtle difference
+ // in the final code between just invokeing `fxc`
+ // and invoking it on the Slang-generated output
+ // (despite the generated HLSL for this line being
+ // identical, modulo some `#line` directives).
+ //
+ // I'm using a binary operator that will yield
+ // the same code with its operands swapped, just
+ // to work around it. A better long-term fix
+ // is to have this test be an end-to-end test
+ // that we execute.
+ i = i*i;
+ } while((bool) i);
+ }
+ return x;
+}
diff --git a/tests/hlsl/simple/allow-uav-conditional.hlsl b/tests/hlsl/simple/allow-uav-conditional.hlsl
new file mode 100644
index 000000000..3da239860
--- /dev/null
+++ b/tests/hlsl/simple/allow-uav-conditional.hlsl
@@ -0,0 +1,19 @@
+//TEST:COMPARE_HLSL: -profile cs_5_0 -target dxbc-assembly
+
+// Check output for `[allow_uav_conditional]`
+
+RWStructuredBuffer<uint> gBuffer : register(u0);
+
+[numthreads(16,1,1)]
+void main(
+ uint tid : SV_DispatchThreadID)
+{
+ uint index = tid;
+
+ [allow_uav_condition]
+ while(gBuffer[index] != 0)
+ {
+ index = gBuffer[index];
+ gBuffer[index]--;
+ }
+}