summaryrefslogtreecommitdiff
path: root/source/slang/slang-lower-to-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-01-23 19:37:10 -0800
committerGitHub <noreply@github.com>2024-01-23 19:37:10 -0800
commitad45062fcc76cd622aaa1a9cb00515d42f8d3528 (patch)
tree28a54911021d4e3c8cd69dc47f67b8f39cdb310a /source/slang/slang-lower-to-ir.cpp
parent1c1d096234d43b2bcb33c2438a6626831bd4e0aa (diff)
SPIRV Legalization fixes. (#3479)
* Fix CFG legalization for SPIRV backend. * Emit DepthReplacing execution mode. * Fix do-while lowering. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
-rw-r--r--source/slang/slang-lower-to-ir.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index f624b0baa..00db77511 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -5695,13 +5695,32 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
{
auto irCondition = getSimpleVal(context,
lowerRValueExpr(context, condExpr));
+ auto invCondition = builder->emitNot(irCondition->getDataType(), irCondition);
// Now we want to `break` if the loop condition is false,
// otherwise we will jump back to the head of the loop.
- builder->emitLoopTest(
- irCondition,
- loopHead,
- breakLabel);
+ //
+ // We need to make sure not to reuse the break block of the loop as
+ // the break/merge block of the ifelse test.
+ // Therefore, we introduce a separate merge block for the loop test.
+ //
+ // Emit the following structure:
+ //
+ // [merge(mergeBlock)]
+ // if (cond) goto loopHead;
+ // else goto mergeBlock;
+ //
+ // mergeBlock:
+ // goto breakLabel;
+ auto mergeBlock = builder->emitBlock();
+ builder->emitBranch(loopHead);
+
+ builder->setInsertInto(testLabel);
+ builder->emitIfElse(
+ invCondition,
+ breakLabel,
+ mergeBlock,
+ mergeBlock);
}
// Finally we insert the label that a `break` will jump to