From ad45062fcc76cd622aaa1a9cb00515d42f8d3528 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 23 Jan 2024 19:37:10 -0800 Subject: SPIRV Legalization fixes. (#3479) * Fix CFG legalization for SPIRV backend. * Emit DepthReplacing execution mode. * Fix do-while lowering. --------- Co-authored-by: Yong He --- source/slang/slang-lower-to-ir.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'source/slang/slang-lower-to-ir.cpp') 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 { 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 -- cgit v1.2.3