Skip to content

Commit e61ea50

Browse files
authored
[SPIR-V] Allow const-evaluatable spec constants (#6606)
Fixes #2957
1 parent 71aec00 commit e61ea50

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ bool isAcceptedSpecConstantBinaryOp(spv::Op op) {
233233

234234
/// Returns true if the given expression is an accepted initializer for a spec
235235
/// constant.
236-
bool isAcceptedSpecConstantInit(const Expr *init) {
236+
bool isAcceptedSpecConstantInit(const Expr *init, ASTContext &astContext) {
237237
// Allow numeric casts
238238
init = init->IgnoreParenCasts();
239239

@@ -244,7 +244,12 @@ bool isAcceptedSpecConstantInit(const Expr *init) {
244244
// Allow the minus operator which is used to specify negative values
245245
if (const auto *unaryOp = dyn_cast<UnaryOperator>(init))
246246
return unaryOp->getOpcode() == UO_Minus &&
247-
isAcceptedSpecConstantInit(unaryOp->getSubExpr());
247+
isAcceptedSpecConstantInit(unaryOp->getSubExpr(), astContext);
248+
249+
// Allow values that can be evaluated to const.
250+
if (init->isEvaluatable(astContext)) {
251+
return true;
252+
}
248253

249254
return false;
250255
}
@@ -7847,7 +7852,7 @@ void SpirvEmitter::createSpecConstant(const VarDecl *varDecl) {
78477852
emitError("missing default value for specialization constant",
78487853
varDecl->getLocation());
78497854
hasError = true;
7850-
} else if (!isAcceptedSpecConstantInit(init)) {
7855+
} else if (!isAcceptedSpecConstantInit(init, astContext)) {
78517856
emitError("unsupported specialization constant initializer",
78527857
init->getLocStart())
78537858
<< init->getSourceRange();
@@ -7859,7 +7864,8 @@ void SpirvEmitter::createSpecConstant(const VarDecl *varDecl) {
78597864

78607865
SpecConstantEnvRAII specConstantEnvRAII(&isSpecConstantMode);
78617866

7862-
const auto specConstant = doExpr(init);
7867+
const auto specConstant =
7868+
constEvaluator.tryToEvaluateAsConst(init, isSpecConstantMode);
78637869

78647870
// We are not creating a variable to hold the spec constant, instead, we
78657871
// translate the varDecl directly into the spec constant here.

tools/clang/test/CodeGenSPIRV/vk.spec-constant.init.hlsl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ float f2 = true;
5757
[[vk::constant_id(33)]]
5858
float f3 = 20;
5959

60+
// CHECK: %u1 = OpSpecConstant %uint 12648430
61+
static const uint u1val = 0xC0FFEE;
62+
[[vk::constant_id(1)]] const uint u1 = u1val;
6063

6164
float main() : A {
6265
return 1.0;

0 commit comments

Comments
 (0)