Fix VectorizeVectorScalarArithmetic statement insertion
The traverser must avoid inserting two statements to the same position
on a single traversal, so it doesn't trigger an assert.
BUG=chromium:784078
TEST=angle_unittests
Change-Id: I855054e62cc1b1cf4e6bb02af527954151c7d0e7
Reviewed-on: https://chromium-review.googlesource.com/771611
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 53ff8f9..6c25c6c 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -122,6 +122,15 @@
{
}
+const TIntermBlock *TIntermTraverser::getParentBlock() const
+{
+ if (!mParentBlockStack.empty())
+ {
+ return mParentBlockStack.back().node;
+ }
+ return nullptr;
+}
+
void TIntermTraverser::pushParentBlock(TIntermBlock *node)
{
mParentBlockStack.push_back(ParentBlock(node, 0));
diff --git a/src/compiler/translator/IntermTraverse.h b/src/compiler/translator/IntermTraverse.h
index d9912c3..f0300b5 100644
--- a/src/compiler/translator/IntermTraverse.h
+++ b/src/compiler/translator/IntermTraverse.h
@@ -143,6 +143,8 @@
return nullptr;
}
+ const TIntermBlock *getParentBlock() const;
+
void pushParentBlock(TIntermBlock *node);
void incrementParentBlockPos();
void popParentBlock();
diff --git a/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp b/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
index d1ea069..1e79a60 100644
--- a/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
+++ b/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
@@ -11,6 +11,8 @@
#include "compiler/translator/VectorizeVectorScalarArithmetic.h"
+#include <set>
+
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermTraverse.h"
@@ -29,7 +31,11 @@
}
bool didReplaceScalarsWithVectors() { return mReplaced; }
- void nextIteration() { mReplaced = false; }
+ void nextIteration()
+ {
+ mReplaced = false;
+ mModifiedBlocks.clear();
+ }
protected:
bool visitBinary(Visit visit, TIntermBinary *node) override;
@@ -47,6 +53,7 @@
TIntermTraverser::OriginalNode *originalNodeFate);
bool mReplaced;
+ std::set<const TIntermBlock *> mModifiedBlocks;
};
TIntermTyped *VectorizeVectorScalarArithmeticTraverser::Vectorize(
@@ -241,11 +248,17 @@
// leave that be.
if (!argBinary->getLeft()->hasSideEffects())
{
- replaceAssignInsideConstructor(node, argBinary);
- mReplaced = true;
- // Don't replace more nodes in the same subtree on this traversal.
- // However, nodes elsewhere in the tree may still be replaced.
- return false;
+ const TIntermBlock *parentBlock = getParentBlock();
+ // We can't do more than one insertion to the same block on the same traversal.
+ if (mModifiedBlocks.find(parentBlock) == mModifiedBlocks.end())
+ {
+ replaceAssignInsideConstructor(node, argBinary);
+ mModifiedBlocks.insert(parentBlock);
+ mReplaced = true;
+ // Don't replace more nodes in the same subtree on this traversal.
+ // However, nodes elsewhere in the tree may still be replaced.
+ return false;
+ }
}
break;
}