diff options
| author | Julius Ikkala <julius.ikkala@gmail.com> | 2025-06-03 12:03:11 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-03 09:03:11 +0000 |
| commit | b06e94b87a115c5979c728ce13ddf34b80285a9f (patch) | |
| tree | 6ce8bc3fb1cd1f02fbe2ce3314475275884873bf | |
| parent | 289f3dd22629bd65dcf1e9be12a52e88deca925c (diff) | |
Fix specialization constants getting incorrectly folded (#7299)
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 41 | ||||
| -rw-r--r-- | tests/bugs/gh-7293.slang | 15 |
2 files changed, 38 insertions, 18 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 9472138c3..1e052a553 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -1976,26 +1976,31 @@ IntVal* SemanticsVisitor::tryConstantFoldDeclRef( // The values of specialization constants aren't known at compile time even // if they're marked `const`. - if ((decl->hasModifier<SpecializationConstantAttribute>() || - decl->hasModifier<VkConstantIdAttribute>()) && - kind == ConstantFoldingKind::SpecializationConstant) - { - // Float-to-inst casts cannot be`OpSpecConstOp` operations in SPIR-V, - // which means they need to be local instructions can cannot be hoisted to the - // global scope. Deduplication logic is run for `IntVal`s however and without hoisting - // instructions using this `IntVal` will trigger error. Hence we emit error here - // to not allow such cases. - // - // Note that float-to-inst casts for non-`IntVal`s are allowed. - if (!isScalarIntegerType(decl->getType())) + if (decl->hasModifier<SpecializationConstantAttribute>() || + decl->hasModifier<VkConstantIdAttribute>()) + { + if (kind == ConstantFoldingKind::SpecializationConstant) { - getSink()->diagnose(declRef, Diagnostics::intValFromNonIntSpecConstEncountered); - return nullptr; - } + // Float-to-inst casts cannot be`OpSpecConstOp` operations in SPIR-V, + // which means they need to be local instructions can cannot be hoisted to the + // global scope. Deduplication logic is run for `IntVal`s however and without hoisting + // instructions using this `IntVal` will trigger error. Hence we emit error here + // to not allow such cases. + // + // Note that float-to-inst casts for non-`IntVal`s are allowed. + if (!isScalarIntegerType(decl->getType())) + { + getSink()->diagnose(declRef, Diagnostics::intValFromNonIntSpecConstEncountered); + return nullptr; + } - return m_astBuilder->getOrCreate<DeclRefIntVal>( - declRef.substitute(m_astBuilder, decl->getType()), - declRef); + return m_astBuilder->getOrCreate<DeclRefIntVal>( + declRef.substitute(m_astBuilder, decl->getType()), + declRef); + } + // Don't fold on other folding passes, we don't actually know the + // values. + return nullptr; } if (decl->hasModifier<ExternModifier>()) diff --git a/tests/bugs/gh-7293.slang b/tests/bugs/gh-7293.slang new file mode 100644 index 000000000..d5ca48248 --- /dev/null +++ b/tests/bugs/gh-7293.slang @@ -0,0 +1,15 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +[SpecializationConstant] const int MAX_ITERS = 0; + +RWStructuredBuffer<int> outputBuffer; + +[numthreads(1, 1, 1)] +void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) +{ + for (int i = 0; i < MAX_ITERS; i++) { + outputBuffer[i] = i; + } +} + +// CHECK-NOT: 30505 |
