summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/slang/slang.vcxproj2
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters6
-rw-r--r--source/slang/slang-diagnostic-defs.h2
-rw-r--r--source/slang/slang-emit-spirv.cpp6
-rw-r--r--source/slang/slang-emit.cpp5
-rw-r--r--source/slang/slang-ir-check-unsupported-inst.cpp71
-rw-r--r--source/slang/slang-ir-check-unsupported-inst.h10
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp6
-rw-r--r--source/slang/slang-ir-util.cpp20
-rw-r--r--source/slang/slang-ir-util.h2
-rw-r--r--tests/bugs/gh-3780.slang58
-rw-r--r--tests/bugs/gh-3781.slang22
-rw-r--r--tests/bugs/gh-3783.slang17
-rw-r--r--tests/cross-compile/array-of-buffers.slang7
-rw-r--r--tests/diagnostics/recursion.slang15
-rw-r--r--tests/spirv/scalar-buffer-packing.slang2
16 files changed, 245 insertions, 6 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 947ab4b5f..c503e8f4d 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -373,6 +373,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-bit-field-accessors.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-byte-address-legalize.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-check-differentiability.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-check-unsupported-inst.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-cleanup-void.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-clone.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-collect-global-uniforms.h" />
@@ -597,6 +598,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-bit-field-accessors.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-byte-address-legalize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-check-differentiability.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-check-unsupported-inst.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-cleanup-void.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-clone.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-collect-global-uniforms.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index 85476ba7b..9c274990d 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -207,6 +207,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-check-differentiability.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-check-unsupported-inst.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-cleanup-void.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -875,6 +878,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-check-differentiability.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-check-unsupported-inst.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-cleanup-void.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index db17c92a0..ba57e63f9 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -792,6 +792,8 @@ DIAGNOSTIC(54004, Warning, unnecessaryHLSLMeshOutputModifier, "Unnecessary HLSL
DIAGNOSTIC(55101, Error, invalidTorchKernelReturnType, "'$0' is not a valid return type for a pytorch kernel function.")
DIAGNOSTIC(55102, Error, invalidTorchKernelParamType, "'$0' is not a valid parameter type for a pytorch kernel function.")
+DIAGNOSTIC(55200, Error, unsupportedBuiltinType, "'$0' is not a supported builtin type for the target.")
+DIAGNOSTIC(55201, Error, unsupportedRecursion, "recursion detected in call to '$0', but the current code generation target does not allow recursion.")
DIAGNOSTIC(56001, Error, unableToAutoMapCUDATypeToHostType, "Could not automatically map '$0' to a host type. Automatic binding generation failed for '$1'")
DIAGNOSTIC(57001, Warning, spirvOptFailed, "spirv-opt failed. $0")
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index afb1b3a63..6ecffecd1 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3060,6 +3060,12 @@ struct SPIRVEmitContext
case Stage::Callable:
requireSPIRVCapability(SpvCapabilityRayTracingKHR);
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_ray_tracing"));
+ break;
+ case Stage::Mesh:
+ case Stage::Amplification:
+ requireSPIRVCapability(SpvCapabilityMeshShadingEXT);
+ ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_mesh_shader"));
+ break;
default:
break;
}
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index ee38996e6..649858e51 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -8,6 +8,7 @@
#include "slang-ir-any-value-inference.h"
#include "slang-ir-bind-existentials.h"
#include "slang-ir-byte-address-legalize.h"
+#include "slang-ir-check-unsupported-inst.h"
#include "slang-ir-collect-global-uniforms.h"
#include "slang-ir-cleanup-void.h"
#include "slang-ir-composite-reg-to-mem.h"
@@ -1061,7 +1062,9 @@ Result linkAndOptimizeIR(
outLinkedIR.metadata = metadata;
- return SLANG_OK;
+ checkUnsupportedInst(codeGenContext->getTargetReq(), irModule, sink);
+
+ return sink->getErrorCount() == 0 ? SLANG_OK : SLANG_FAIL;
}
SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outArtifact)
diff --git a/source/slang/slang-ir-check-unsupported-inst.cpp b/source/slang/slang-ir-check-unsupported-inst.cpp
new file mode 100644
index 000000000..c89928af5
--- /dev/null
+++ b/source/slang/slang-ir-check-unsupported-inst.cpp
@@ -0,0 +1,71 @@
+#include "slang-ir-check-unsupported-inst.h"
+
+#include "slang-ir.h"
+#include "slang-ir-util.h"
+
+namespace Slang
+{
+ bool isCPUTarget(TargetRequest* targetReq);
+
+ bool checkRecursionImpl(HashSet<IRFunc*>& checkedFuncs, HashSet<IRFunc*>& callStack, IRFunc* func, DiagnosticSink* sink)
+ {
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst : block->getChildren())
+ {
+ auto callInst = as<IRCall>(inst);
+ if (!callInst)
+ continue;
+ auto callee = as<IRFunc>(callInst->getCallee());
+ if (!callee)
+ continue;
+ if (!callStack.add(callee))
+ {
+ sink->diagnose(callInst, Diagnostics::unsupportedRecursion, callee);
+ return false;
+ }
+ if (checkedFuncs.add(callee))
+ checkRecursionImpl(checkedFuncs, callStack, callee, sink);
+ callStack.remove(callee);
+ }
+ }
+ return true;
+ }
+
+ void checkRecursion(HashSet<IRFunc*>& checkedFuncs, IRFunc* func, DiagnosticSink* sink)
+ {
+ HashSet<IRFunc*> callStack;
+ if (checkedFuncs.add(func))
+ {
+ callStack.add(func);
+ checkRecursionImpl(checkedFuncs, callStack, func, sink);
+ }
+ }
+
+ void checkUnsupportedInst(TargetRequest* target, IRModule* module, DiagnosticSink* sink)
+ {
+ HashSet<IRFunc*> checkedFuncsForRecursionDetection;
+
+ for (auto globalInst : module->getGlobalInsts())
+ {
+ switch (globalInst->getOp())
+ {
+ case kIROp_VectorType:
+ case kIROp_MatrixType:
+ {
+ if (!as<IRBasicType>(globalInst->getOperand(0)))
+ {
+ sink->diagnose(findFirstUseLoc(globalInst), Diagnostics::unsupportedBuiltinType, globalInst);
+ }
+ break;
+ }
+ case kIROp_Func:
+ if (!isCPUTarget(target))
+ checkRecursion(checkedFuncsForRecursionDetection, as<IRFunc>(globalInst), sink);
+ default:
+ break;
+ }
+ }
+ }
+
+}
diff --git a/source/slang/slang-ir-check-unsupported-inst.h b/source/slang/slang-ir-check-unsupported-inst.h
new file mode 100644
index 000000000..b52306566
--- /dev/null
+++ b/source/slang/slang-ir-check-unsupported-inst.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace Slang
+{
+ struct IRModule;
+ class DiagnosticSink;
+ class TargetRequest;
+
+ void checkUnsupportedInst(TargetRequest* target, IRModule* module, DiagnosticSink* sink);
+}
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index a7c14242b..2b7e86f47 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -216,8 +216,12 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
auto user = use->getUser();
IRBuilder builder(user);
builder.setInsertBefore(user);
- if(as<IRGetElement>(user) || as<IRFieldExtract>(user))
+
+ if((as<IRGetElement>(user) || as<IRFieldExtract>(user)) &&
+ use == user->getOperands())
{
+ // If the use is the address operand of a getElement or FieldExtract,
+ // replace the inst with the updated address and continue to follow the use chain.
auto basePtrType = as<IRPtrTypeBase>(addr->getDataType());
IRType* ptrType = nullptr;
if (basePtrType->hasAddressSpace())
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 2f059d308..e1eb86508 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -230,6 +230,18 @@ bool isSimpleDataType(IRType* type)
}
}
+SourceLoc findFirstUseLoc(IRInst* inst)
+{
+ for (auto use = inst->firstUse; use; use = use->nextUse)
+ {
+ if (use->getUser()->sourceLoc.isValid())
+ {
+ return use->getUser()->sourceLoc;
+ }
+ }
+ return inst->sourceLoc;
+}
+
IRInst* hoistValueFromGeneric(IRBuilder& inBuilder, IRInst* value, IRInst*& outSpecializedVal, bool replaceExistingValue)
{
auto outerGeneric = as<IRGeneric>(findOuterGeneric(value));
@@ -582,14 +594,20 @@ void getTypeNameHint(StringBuilder& sb, IRInst* type)
getTypeNameHint(sb, as<IRRateQualifiedType>(type)->getValueType());
break;
case kIROp_VectorType:
+ sb << "vector<";
getTypeNameHint(sb, type->getOperand(0));
+ sb << ",";
getTypeNameHint(sb, as<IRVectorType>(type)->getElementCount());
+ sb << ">";
break;
case kIROp_MatrixType:
+ sb << "matrix<";
getTypeNameHint(sb, type->getOperand(0));
+ sb << ",";
getTypeNameHint(sb, as<IRMatrixType>(type)->getRowCount());
- sb << "x";
+ sb << ",";
getTypeNameHint(sb, as<IRMatrixType>(type)->getColumnCount());
+ sb << ">";
break;
case kIROp_IntLit:
sb << as<IRIntLit>(type)->getValue();
diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h
index fd34d81f7..40ba783b9 100644
--- a/source/slang/slang-ir-util.h
+++ b/source/slang/slang-ir-util.h
@@ -89,6 +89,8 @@ bool isValueType(IRInst* type);
bool isSimpleDataType(IRType* type);
+SourceLoc findFirstUseLoc(IRInst* inst);
+
inline bool isChildInstOf(IRInst* inst, IRInst* parent)
{
while (inst)
diff --git a/tests/bugs/gh-3780.slang b/tests/bugs/gh-3780.slang
new file mode 100644
index 000000000..62a9542d7
--- /dev/null
+++ b/tests/bugs/gh-3780.slang
@@ -0,0 +1,58 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly
+
+// CHECK: OpEntryPoint
+
+const static float2 positions[3] = {
+ float2(0.0, -0.5),
+ float2(0.5, 0.5),
+ float2(-0.5, 0.5)
+};
+
+const static float3 colors[3] = {
+ float3(1.0, 1.0, 0.0),
+ float3(0.0, 1.0, 1.0),
+ float3(1.0, 0.0, 1.0)
+};
+
+struct Vertex
+{
+ float4 pos : SV_Position;
+ float3 color;
+};
+
+const static uint MAX_VERTS = 3;
+const static uint MAX_PRIMS = 1;
+
+[outputtopology("triangle")]
+[numthreads(3, 1, 1)]
+[shader("mesh")]
+void entry_mesh(
+ in uint tig : SV_GroupIndex,
+ out vertices Vertex verts[MAX_VERTS],
+ out indices uint3 triangles[MAX_PRIMS])
+{
+ const uint numVertices = 3;
+ const uint numPrimitives = 1;
+ SetMeshOutputCounts(numVertices, numPrimitives);
+
+ if(tig < numVertices) {
+ verts[tig] = {float4(positions[tig], 0, 1), colors[tig]};
+ }
+
+ if(tig < numPrimitives) {
+ triangles[tig] = uint3(0,1,2);
+ }
+}
+
+struct FragmentOut
+{
+ [[vk::location(0)]] float3 color;
+};
+
+[shader("fragment")]
+FragmentOut entry_fragment(in Vertex vertex)
+{
+ FragmentOut frag_out;
+ frag_out.color = float3(1,1,1);
+ return frag_out;
+} \ No newline at end of file
diff --git a/tests/bugs/gh-3781.slang b/tests/bugs/gh-3781.slang
new file mode 100644
index 000000000..89b2957b9
--- /dev/null
+++ b/tests/bugs/gh-3781.slang
@@ -0,0 +1,22 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly
+
+// CHECK: OpEntryPoint
+
+struct Vertex
+{
+ float4 pos : SV_Position;
+ [[vk::location(0)]] float3 color;
+};
+
+const static uint MAX_VERTS = 3;
+const static uint MAX_PRIMS = 1;
+
+[outputtopology("triangle")]
+[numthreads(3, 1, 1)]
+[shader("mesh")]
+void entry_mesh(
+ in uint tig : SV_GroupIndex,
+ out vertices Vertex verts[MAX_VERTS],
+ out indices uint3 triangles[MAX_PRIMS])
+{
+} \ No newline at end of file
diff --git a/tests/bugs/gh-3783.slang b/tests/bugs/gh-3783.slang
new file mode 100644
index 000000000..9e343b22f
--- /dev/null
+++ b/tests/bugs/gh-3783.slang
@@ -0,0 +1,17 @@
+//TEST:SIMPLE(filecheck=CHECK):-target spirv -emit-spirv-directly
+
+// CHECK: error 55200:
+
+RWStructuredBuffer<float> outputBuffer;
+
+float testFunc(vector<vector<float, 3>, 2> v1)
+{
+ return v1.x.x;
+}
+
+[numthreads(1,1,1)]
+void main(uint v : SV_DispatchThreadID)
+{
+ vector<vector<float, 3>, 2> v1 = { { 1, 2, 3 }, { 4, 5, v } };
+ outputBuffer[0] = testFunc(v1);
+} \ No newline at end of file
diff --git a/tests/cross-compile/array-of-buffers.slang b/tests/cross-compile/array-of-buffers.slang
index 31738ccfc..bf2574f29 100644
--- a/tests/cross-compile/array-of-buffers.slang
+++ b/tests/cross-compile/array-of-buffers.slang
@@ -1,7 +1,10 @@
// array-of-buffers.slang
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
-//TEST:CROSS_COMPILE:-target dxil-assembly -entry main -stage fragment -profile sm_6_0
+//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=DXIL):-target dxil-assembly -entry main -stage fragment -profile sm_6_0
+
+// SPIRV: OpEntryPoint
+// DXIL: define void @main()
// This test ensures that we cross-compile arrays of structured/constant
// buffers into appropriate GLSL, where these are not first-class types.
diff --git a/tests/diagnostics/recursion.slang b/tests/diagnostics/recursion.slang
new file mode 100644
index 000000000..b5746820e
--- /dev/null
+++ b/tests/diagnostics/recursion.slang
@@ -0,0 +1,15 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly
+
+// CHECK: error 55201:
+
+float test<let x : int>()
+{
+ return test<x>();
+}
+
+RWStructuredBuffer<float> outputBuffer;
+[numthreads(1,1,1)]
+void main()
+{
+ outputBuffer[0] = test<1>();
+} \ No newline at end of file
diff --git a/tests/spirv/scalar-buffer-packing.slang b/tests/spirv/scalar-buffer-packing.slang
index bc42cfa39..1224ae664 100644
--- a/tests/spirv/scalar-buffer-packing.slang
+++ b/tests/spirv/scalar-buffer-packing.slang
@@ -51,6 +51,6 @@ void computeMain()
// SPIRV: OpEntryPoint GLCompute
-// SPIRV-DAG: %[[STRUCTNAME:[A-Za-z0-9_]+]] = OpTypeStruct %int %_Array_natural_int32
+// SPIRV-DAG: %[[STRUCTNAME:[A-Za-z0-9_]+]] = OpTypeStruct %int %_Array_natural_vector_int_3_2
// SPIRV-DAG: OpMemberDecorate %[[STRUCTNAME:[A-Za-z0-9_]+]] 1 Offset 4