summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/emit.cpp64
-rw-r--r--tests/bugs/gh-666.slang11
2 files changed, 60 insertions, 15 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 312e8c0b3..03c788ddb 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2353,14 +2353,6 @@ struct EmitVisitor
case kIROp_Param:
return false;
- // HACK: don't fold these in because we currently lower
- // them to initializer lists, which aren't allowed in
- // general expression contexts.
- //
- case kIROp_makeStruct:
- case kIROp_makeArray:
- return false;
-
// Always fold these in, because they are trivial
//
case kIROp_IntLit:
@@ -2387,6 +2379,25 @@ struct EmitVisitor
if (mode == IREmitMode::GlobalConstant)
return true;
+ switch( inst->op )
+ {
+ default:
+ break;
+
+ // HACK: don't fold these in because we currently lower
+ // them to initializer lists, which aren't allowed in
+ // general expression contexts.
+ //
+ // Note: we are doing this check *after* the check for `GlobalConstant`
+ // mode, because otherwise we'd fail to emit initializer lists in
+ // the main place where we want/need them.
+ //
+ case kIROp_makeStruct:
+ case kIROp_makeArray:
+ return false;
+
+ }
+
// Instructions with specific result *types* will usually
// want to be folded in, because they aren't allowed as types
// for temporary variables.
@@ -2539,9 +2550,25 @@ struct EmitVisitor
{
if( shouldFoldIRInstIntoUseSites(ctx, inst, mode) )
{
- emit("(");
- emitIRInstExpr(ctx, inst, mode);
- emit(")");
+ // HACK: Don't emit parentheses for cases that will
+ // wrap themsevles in `{}` to begin with.
+ //
+ // TODO: This shouldn't be needed once we are more
+ // systematic about not emitting redundant parentheses.
+ //
+ switch(inst->op)
+ {
+ case kIROp_makeArray:
+ case kIROp_makeStruct:
+ emitIRInstExpr(ctx, inst, mode);
+ break;
+
+ default:
+ emit("(");
+ emitIRInstExpr(ctx, inst, mode);
+ emit(")");
+ break;
+ }
return;
}
@@ -5884,10 +5911,17 @@ struct EmitVisitor
auto returnInst = (IRReturnVal*) block->getLastInst();
SLANG_RELEASE_ASSERT(returnInst->op == kIROp_ReturnVal);
- // Now we want to emit the expression form of
- // the value being returned, and force any
- // sub-expressions to be included.
- emitIRInstExpr(ctx, returnInst->getVal(), IREmitMode::GlobalConstant);
+ // We will emit the value in the `GlobalConstant` mode, which
+ // more or less says to fold all instructions into their use
+ // sites, so that we end up with a single expression tree even
+ // in cases that would otherwise trip up our analysis.
+ //
+ // Note: We are emitting the value as an *operand* here instead
+ // of directly calling `emitIRInstExpr` because we need to handle
+ // cases where the value might *need* to emit as a named referenced
+ // (e.g., when it names another constant directly).
+ //
+ emitIROperand(ctx, returnInst->getVal(), IREmitMode::GlobalConstant);
}
void emitIRGlobalConstant(
diff --git a/tests/bugs/gh-666.slang b/tests/bugs/gh-666.slang
new file mode 100644
index 000000000..fa46d1de7
--- /dev/null
+++ b/tests/bugs/gh-666.slang
@@ -0,0 +1,11 @@
+// gh-666.slang
+
+//TEST:COMPARE_HLSL:-no-mangle -profile ps_5_0 -entry main
+
+static const uint foo = 1;
+static const uint bar = foo;
+
+float4 main() : SV_TARGET
+{
+ return bar;
+}