Constant fold vector relational built-ins
This change adds constant folding support for vector relational
built-ins.
BUG=angleproject:913
TEST=dEQP Tests
dEQP-GLES3.functional.shaders.constant_expressions.builtin_functions.vector_relational*
(Fixes all 138 tests)
Change-Id: I291e332f2afb3ce3d6596e634f509995dbf35164
Reviewed-on: https://chromium-review.googlesource.com/272344
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 1bac12c..4f441ae 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -1163,10 +1163,66 @@
return tempNode;
}
+ else if (op == EOpAny || op == EOpAll)
+ {
+ // Do operations where the return type is different from the operand type.
+
+ TType returnType(EbtBool, EbpUndefined, EvqConst);
+ TConstantUnion *tempConstArray = nullptr;
+ if (op == EOpAny)
+ {
+ if (getType().getBasicType() == EbtBool)
+ {
+ tempConstArray = new TConstantUnion();
+ tempConstArray->setBConst(false);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (unionArray[i].getBConst())
+ {
+ tempConstArray->setBConst(true);
+ break;
+ }
+ }
+ }
+ else
+ {
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ }
+ else if (op == EOpAll)
+ {
+ if (getType().getBasicType() == EbtBool)
+ {
+ tempConstArray = new TConstantUnion();
+ tempConstArray->setBConst(true);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (!unionArray[i].getBConst())
+ {
+ tempConstArray->setBConst(false);
+ break;
+ }
+ }
+ }
+ else
+ {
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ }
+ TIntermConstantUnion *tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+ tempNode->setLine(getLine());
+ return tempNode;
+ }
else
{
//
- // Do unary operations
+ // Do unary operations where the return type is the same as operand type.
//
TIntermConstantUnion *newNode = 0;
TConstantUnion* tempConstArray = new TConstantUnion[objectSize];
@@ -1492,6 +1548,17 @@
tempConstArray[i].setFConst(1.0f / tempConstArray[i].getFConst());
break;
+ case EOpVectorLogicalNot:
+ if (getType().getBasicType() == EbtBool)
+ {
+ tempConstArray[i].setBConst(!unionArray[i].getBConst());
+ break;
+ }
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+
default:
return nullptr;
}
@@ -1685,6 +1752,156 @@
}
break;
+ case EOpLessThan:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() < unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() < unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() < unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpLessThanEqual:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() <= unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() <= unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() <= unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpGreaterThan:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() > unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() > unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() > unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpGreaterThanEqual:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() >= unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() >= unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() >= unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpVectorEqual:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() == unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() == unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() == unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ tempConstArray[i].setBConst(unionArrays[0][i].getBConst() == unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpVectorNotEqual:
+ {
+ tempConstArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ tempConstArray[i].setBConst(unionArrays[0][i].getFConst() != unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getIConst() != unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setBConst(unionArrays[0][i].getUConst() != unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ tempConstArray[i].setBConst(unionArrays[0][i].getBConst() != unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
default:
UNREACHABLE();
// TODO: Add constant folding support for other built-in operations that take 2 parameters and not handled above.
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index b48269e..a5f83a4 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -471,6 +471,12 @@
case EOpMix:
case EOpStep:
case EOpSmoothStep:
+ case EOpLessThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThan:
+ case EOpGreaterThanEqual:
+ case EOpVectorEqual:
+ case EOpVectorNotEqual:
return TIntermConstantUnion::FoldAggregateBuiltIn(op, aggregate, mInfoSink);
default:
// Constant folding not supported for the built-in.