GLSLTest: test interaction of declaration splitting with other passes
In TranslatorHLSL a number of AST simplifications are done, that must
happen in a precise order for things to be correct:
- First for-loops must be split
- Then multideclarations must be split
- Finally comma operators must be split
This adds tests for interaction between this passes to make sure they
are done in the right order.
BUG=668028
Change-Id: I306915b51011bb5467d117352becfd60cbe77be4
Reviewed-on: https://chromium-review.googlesource.com/417989
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 7a2184f..9d4cbbb 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -479,6 +479,17 @@
return constructor;
}
+// static
+TIntermTyped *TIntermTyped::CreateBool(bool value)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setBConst(value);
+
+ TType type(EbtBool, EbpUndefined, EvqConst, 1);
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+ return node;
+}
+
TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
{
mUnionArrayPointer = node.mUnionArrayPointer;
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 50b6ff0..8fe734d 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -176,6 +176,7 @@
static TIntermTyped *CreateIndexNode(int index);
static TIntermTyped *CreateZero(const TType &type);
+ static TIntermTyped *CreateBool(bool value);
protected:
TType mType;
diff --git a/src/compiler/translator/SimplifyLoopConditions.cpp b/src/compiler/translator/SimplifyLoopConditions.cpp
index 1f8a384..a9fad6a 100644
--- a/src/compiler/translator/SimplifyLoopConditions.cpp
+++ b/src/compiler/translator/SimplifyLoopConditions.cpp
@@ -224,29 +224,54 @@
// {
// init;
// bool s0 = expr;
- // while (s0) { { body; } exprB; s0 = expr; }
+ // while (s0) {
+ // { body; }
+ // exprB;
+ // s0 = expr;
+ // }
// }
- TIntermBlock *loopScope = new TIntermBlock();
+ TIntermBlock *loopScope = new TIntermBlock();
+ TIntermSequence *loopScopeSequence = loopScope->getSequence();
+
+ // Insert "init;"
if (node->getInit())
{
- loopScope->getSequence()->push_back(node->getInit());
+ loopScopeSequence->push_back(node->getInit());
}
- loopScope->getSequence()->push_back(
- createTempInitDeclaration(node->getCondition()->deepCopy()));
+ // Insert "bool s0 = expr;" if applicable, "bool s0 = true;" otherwise
+ TIntermTyped *conditionInitializer = nullptr;
+ if (node->getCondition())
+ {
+ conditionInitializer = node->getCondition()->deepCopy();
+ }
+ else
+ {
+ conditionInitializer = TIntermTyped::CreateBool(true);
+ }
+ loopScopeSequence->push_back(createTempInitDeclaration(conditionInitializer));
+
+ // Insert "{ body; }" in the while loop
TIntermBlock *whileLoopBody = new TIntermBlock();
if (node->getBody())
{
whileLoopBody->getSequence()->push_back(node->getBody());
}
+ // Insert "exprB;" in the while loop
if (node->getExpression())
{
whileLoopBody->getSequence()->push_back(node->getExpression());
}
- whileLoopBody->getSequence()->push_back(
- createTempAssignment(node->getCondition()->deepCopy()));
+ // Insert "s0 = expr;" in the while loop
+ if (node->getCondition())
+ {
+ whileLoopBody->getSequence()->push_back(
+ createTempAssignment(node->getCondition()->deepCopy()));
+ }
+
+ // Create "while(s0) { whileLoopBody }"
TIntermLoop *whileLoop = new TIntermLoop(
- ELoopWhile, nullptr, createTempSymbol(node->getCondition()->getType()), nullptr,
+ ELoopWhile, nullptr, createTempSymbol(conditionInitializer->getType()), nullptr,
whileLoopBody);
loopScope->getSequence()->push_back(whileLoop);
queueReplacementWithParent(getAncestorNode(1), node, loopScope,