Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2012-2015 LunarG, Inc.
      4 // Copyright (C) 2015-2016 Google, Inc.
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions
     10 // are met:
     11 //
     12 //    Redistributions of source code must retain the above copyright
     13 //    notice, this list of conditions and the following disclaimer.
     14 //
     15 //    Redistributions in binary form must reproduce the above
     16 //    copyright notice, this list of conditions and the following
     17 //    disclaimer in the documentation and/or other materials provided
     18 //    with the distribution.
     19 //
     20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     21 //    contributors may be used to endorse or promote products derived
     22 //    from this software without specific prior written permission.
     23 //
     24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35 // POSSIBILITY OF SUCH DAMAGE.
     36 //
     37 
     38 //
     39 // Build the intermediate representation.
     40 //
     41 
     42 #include "localintermediate.h"
     43 #include "RemoveTree.h"
     44 #include "SymbolTable.h"
     45 #include "propagateNoContraction.h"
     46 
     47 #include <cfloat>
     48 #include <utility>
     49 
     50 namespace glslang {
     51 
     52 ////////////////////////////////////////////////////////////////////////////
     53 //
     54 // First set of functions are to help build the intermediate representation.
     55 // These functions are not member functions of the nodes.
     56 // They are called from parser productions.
     57 //
     58 /////////////////////////////////////////////////////////////////////////////
     59 
     60 //
     61 // Add a terminal node for an identifier in an expression.
     62 //
     63 // Returns the added node.
     64 //
     65 
     66 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray,
     67                                         TIntermTyped* constSubtree, const TSourceLoc& loc)
     68 {
     69     TIntermSymbol* node = new TIntermSymbol(id, name, type);
     70     node->setLoc(loc);
     71     node->setConstArray(constArray);
     72     node->setConstSubtree(constSubtree);
     73 
     74     return node;
     75 }
     76 
     77 TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol)
     78 {
     79     return addSymbol(intermSymbol.getId(),
     80                      intermSymbol.getName(),
     81                      intermSymbol.getType(),
     82                      intermSymbol.getConstArray(),
     83                      intermSymbol.getConstSubtree(),
     84                      intermSymbol.getLoc());
     85 }
     86 
     87 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable)
     88 {
     89     glslang::TSourceLoc loc; // just a null location
     90     loc.init();
     91 
     92     return addSymbol(variable, loc);
     93 }
     94 
     95 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
     96 {
     97     return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
     98 }
     99 
    100 TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc)
    101 {
    102     TConstUnionArray unionArray;  // just a null constant
    103 
    104     return addSymbol(0, "", type, unionArray, nullptr, loc);
    105 }
    106 
    107 //
    108 // Connect two nodes with a new parent that does a binary operation on the nodes.
    109 //
    110 // Returns the added node.
    111 //
    112 // Returns nullptr if the working conversions and promotions could not be found.
    113 //
    114 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
    115 {
    116     // No operations work on blocks
    117     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
    118         return nullptr;
    119 
    120     // Try converting the children's base types to compatible types.
    121     TIntermTyped* child = addConversion(op, left->getType(), right);
    122     if (child)
    123         right = child;
    124     else {
    125         child = addConversion(op, right->getType(), left);
    126         if (child)
    127             left = child;
    128         else
    129             return nullptr;
    130     }
    131 
    132     // Convert the children's type shape to be compatible.
    133     addBiShapeConversion(op, left, right);
    134     if (left == nullptr || right == nullptr)
    135         return nullptr;
    136 
    137     //
    138     // Need a new node holding things together.  Make
    139     // one and promote it to the right type.
    140     //
    141     TIntermBinary* node = addBinaryNode(op, left, right, loc);
    142     if (! promote(node))
    143         return nullptr;
    144 
    145     node->updatePrecision();
    146 
    147     //
    148     // If they are both (non-specialization) constants, they must be folded.
    149     // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
    150     //
    151     TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion();
    152     TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion();
    153     if (leftTempConstant && rightTempConstant) {
    154         TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
    155         if (folded)
    156             return folded;
    157     }
    158 
    159     // If can propagate spec-constantness and if the operation is an allowed
    160     // specialization-constant operation, make a spec-constant.
    161     if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
    162         node->getWritableType().getQualifier().makeSpecConstant();
    163 
    164     return node;
    165 }
    166 
    167 //
    168 // Low level: add binary node (no promotions or other argument modifications)
    169 //
    170 TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const
    171 {
    172     // build the node
    173     TIntermBinary* node = new TIntermBinary(op);
    174     if (loc.line == 0)
    175         loc = left->getLoc();
    176     node->setLoc(loc);
    177     node->setLeft(left);
    178     node->setRight(right);
    179 
    180     return node;
    181 }
    182 
    183 //
    184 // like non-type form, but sets node's type.
    185 //
    186 TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const
    187 {
    188     TIntermBinary* node = addBinaryNode(op, left, right, loc);
    189     node->setType(type);
    190     return node;
    191 }
    192 
    193 //
    194 // Low level: add unary node (no promotions or other argument modifications)
    195 //
    196 TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const
    197 {
    198     TIntermUnary* node = new TIntermUnary(op);
    199     if (loc.line == 0)
    200         loc = child->getLoc();
    201     node->setLoc(loc);
    202     node->setOperand(child);
    203 
    204     return node;
    205 }
    206 
    207 //
    208 // like non-type form, but sets node's type.
    209 //
    210 TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const
    211 {
    212     TIntermUnary* node = addUnaryNode(op, child, loc);
    213     node->setType(type);
    214     return node;
    215 }
    216 
    217 //
    218 // Connect two nodes through an assignment.
    219 //
    220 // Returns the added node.
    221 //
    222 // Returns nullptr if the 'right' type could not be converted to match the 'left' type,
    223 // or the resulting operation cannot be properly promoted.
    224 //
    225 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
    226 {
    227     // No block assignment
    228     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
    229         return nullptr;
    230 
    231     //
    232     // Like adding binary math, except the conversion can only go
    233     // from right to left.
    234     //
    235 
    236     // convert base types, nullptr return means not possible
    237     right = addConversion(op, left->getType(), right);
    238     if (right == nullptr)
    239         return nullptr;
    240 
    241     // convert shape
    242     right = addUniShapeConversion(op, left->getType(), right);
    243 
    244     // build the node
    245     TIntermBinary* node = addBinaryNode(op, left, right, loc);
    246 
    247     if (! promote(node))
    248         return nullptr;
    249 
    250     node->updatePrecision();
    251 
    252     return node;
    253 }
    254 
    255 //
    256 // Connect two nodes through an index operator, where the left node is the base
    257 // of an array or struct, and the right node is a direct or indirect offset.
    258 //
    259 // Returns the added node.
    260 // The caller should set the type of the returned node.
    261 //
    262 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
    263 {
    264     // caller should set the type
    265     return addBinaryNode(op, base, index, loc);
    266 }
    267 
    268 //
    269 // Add one node as the parent of another that it operates on.
    270 //
    271 // Returns the added node.
    272 //
    273 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
    274 {
    275     if (child == 0)
    276         return nullptr;
    277 
    278     if (child->getType().getBasicType() == EbtBlock)
    279         return nullptr;
    280 
    281     switch (op) {
    282     case EOpLogicalNot:
    283         if (source == EShSourceHlsl) {
    284             break; // HLSL can promote logical not
    285         }
    286 
    287         if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
    288             return nullptr;
    289         }
    290         break;
    291 
    292     case EOpPostIncrement:
    293     case EOpPreIncrement:
    294     case EOpPostDecrement:
    295     case EOpPreDecrement:
    296     case EOpNegative:
    297         if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
    298             return nullptr;
    299     default: break; // some compilers want this
    300     }
    301 
    302     //
    303     // Do we need to promote the operand?
    304     //
    305     TBasicType newType = EbtVoid;
    306     switch (op) {
    307     case EOpConstructInt:    newType = EbtInt;    break;
    308     case EOpConstructUint:   newType = EbtUint;   break;
    309     case EOpConstructInt64:  newType = EbtInt64;  break;
    310     case EOpConstructUint64: newType = EbtUint64; break;
    311 #ifdef AMD_EXTENSIONS
    312     case EOpConstructInt16:  newType = EbtInt16;  break;
    313     case EOpConstructUint16: newType = EbtUint16; break;
    314 #endif
    315     case EOpConstructBool:   newType = EbtBool;   break;
    316     case EOpConstructFloat:  newType = EbtFloat;  break;
    317     case EOpConstructDouble: newType = EbtDouble; break;
    318 #ifdef AMD_EXTENSIONS
    319     case EOpConstructFloat16: newType = EbtFloat16; break;
    320 #endif
    321     default: break; // some compilers want this
    322     }
    323 
    324     if (newType != EbtVoid) {
    325         child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
    326                                                                child->getMatrixCols(),
    327                                                                child->getMatrixRows(),
    328                                                                child->isVector()),
    329                               child);
    330         if (child == nullptr)
    331             return nullptr;
    332     }
    333 
    334     //
    335     // For constructors, we are now done, it was all in the conversion.
    336     // TODO: but, did this bypass constant folding?
    337     //
    338     switch (op) {
    339     case EOpConstructInt:
    340     case EOpConstructUint:
    341     case EOpConstructInt64:
    342     case EOpConstructUint64:
    343 #ifdef AMD_EXTENSIONS
    344     case EOpConstructInt16:
    345     case EOpConstructUint16:
    346 #endif
    347     case EOpConstructBool:
    348     case EOpConstructFloat:
    349     case EOpConstructDouble:
    350 #ifdef AMD_EXTENSIONS
    351     case EOpConstructFloat16:
    352 #endif
    353         return child;
    354     default: break; // some compilers want this
    355     }
    356 
    357     //
    358     // Make a new node for the operator.
    359     //
    360     TIntermUnary* node = addUnaryNode(op, child, loc);
    361 
    362     if (! promote(node))
    363         return nullptr;
    364 
    365     node->updatePrecision();
    366 
    367     // If it's a (non-specialization) constant, it must be folded.
    368     if (node->getOperand()->getAsConstantUnion())
    369         return node->getOperand()->getAsConstantUnion()->fold(op, node->getType());
    370 
    371     // If it's a specialization constant, the result is too,
    372     // if the operation is allowed for specialization constants.
    373     if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
    374         node->getWritableType().getQualifier().makeSpecConstant();
    375 
    376     return node;
    377 }
    378 
    379 TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType)
    380 {
    381     if (unary) {
    382         //
    383         // Treat it like a unary operator.
    384         // addUnaryMath() should get the type correct on its own;
    385         // including constness (which would differ from the prototype).
    386         //
    387         TIntermTyped* child = childNode->getAsTyped();
    388         if (child == nullptr)
    389             return nullptr;
    390 
    391         if (child->getAsConstantUnion()) {
    392             TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
    393             if (folded)
    394                 return folded;
    395         }
    396 
    397         return addUnaryNode(op, child, child->getLoc(), returnType);
    398     } else {
    399         // setAggregateOperater() calls fold() for constant folding
    400         TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);
    401 
    402         return node;
    403     }
    404 }
    405 
    406 //
    407 // This is the safe way to change the operator on an aggregate, as it
    408 // does lots of error checking and fixing.  Especially for establishing
    409 // a function call's operation on it's set of parameters.  Sequences
    410 // of instructions are also aggregates, but they just directly set
    411 // their operator to EOpSequence.
    412 //
    413 // Returns an aggregate node, which could be the one passed in if
    414 // it was already an aggregate.
    415 //
    416 TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
    417 {
    418     TIntermAggregate* aggNode;
    419 
    420     //
    421     // Make sure we have an aggregate.  If not turn it into one.
    422     //
    423     if (node) {
    424         aggNode = node->getAsAggregate();
    425         if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
    426             //
    427             // Make an aggregate containing this node.
    428             //
    429             aggNode = new TIntermAggregate();
    430             aggNode->getSequence().push_back(node);
    431             if (loc.line == 0)
    432                 loc = node->getLoc();
    433         }
    434     } else
    435         aggNode = new TIntermAggregate();
    436 
    437     //
    438     // Set the operator.
    439     //
    440     aggNode->setOperator(op);
    441     if (loc.line != 0)
    442         aggNode->setLoc(loc);
    443 
    444     aggNode->setType(type);
    445 
    446     return fold(aggNode);
    447 }
    448 
    449 //
    450 // Convert the node's type to the given type, as allowed by the operation involved: 'op'.
    451 // For implicit conversions, 'op' is not the requested conversion, it is the explicit
    452 // operation requiring the implicit conversion.
    453 //
    454 // Returns a node representing the conversion, which could be the same
    455 // node passed in if no conversion was needed.
    456 //
    457 // Generally, this is focused on basic type conversion, not shape conversion.
    458 // See addShapeConversion().
    459 //
    460 // Return nullptr if a conversion can't be done.
    461 //
    462 TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const
    463 {
    464     //
    465     // Does the base type even allow the operation?
    466     //
    467     switch (node->getBasicType()) {
    468     case EbtVoid:
    469         return nullptr;
    470     case EbtAtomicUint:
    471     case EbtSampler:
    472         // opaque types can be passed to functions
    473         if (op == EOpFunction)
    474             break;
    475 
    476         // HLSL can assign samplers directly (no constructor)
    477         if (source == EShSourceHlsl && node->getBasicType() == EbtSampler)
    478             break;
    479 
    480         // samplers can get assigned via a sampler constructor
    481         // (well, not yet, but code in the rest of this function is ready for it)
    482         if (node->getBasicType() == EbtSampler && op == EOpAssign &&
    483             node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
    484             break;
    485 
    486         // otherwise, opaque types can't even be operated on, let alone converted
    487         return nullptr;
    488     default:
    489         break;
    490     }
    491 
    492     // Otherwise, if types are identical, no problem
    493     if (type == node->getType())
    494         return node;
    495 
    496     // If one's a structure, then no conversions.
    497     if (type.isStruct() || node->isStruct())
    498         return nullptr;
    499 
    500     // If one's an array, then no conversions.
    501     if (type.isArray() || node->getType().isArray())
    502         return nullptr;
    503 
    504     // Note: callers are responsible for other aspects of shape,
    505     // like vector and matrix sizes.
    506 
    507     TBasicType promoteTo;
    508 
    509     switch (op) {
    510     //
    511     // Explicit conversions (unary operations)
    512     //
    513     case EOpConstructBool:
    514         promoteTo = EbtBool;
    515         break;
    516     case EOpConstructFloat:
    517         promoteTo = EbtFloat;
    518         break;
    519     case EOpConstructDouble:
    520         promoteTo = EbtDouble;
    521         break;
    522 #ifdef AMD_EXTENSIONS
    523     case EOpConstructFloat16:
    524         promoteTo = EbtFloat16;
    525         break;
    526 #endif
    527     case EOpConstructInt:
    528         promoteTo = EbtInt;
    529         break;
    530     case EOpConstructUint:
    531         promoteTo = EbtUint;
    532         break;
    533     case EOpConstructInt64:
    534         promoteTo = EbtInt64;
    535         break;
    536     case EOpConstructUint64:
    537         promoteTo = EbtUint64;
    538         break;
    539 #ifdef AMD_EXTENSIONS
    540     case EOpConstructInt16:
    541         promoteTo = EbtInt16;
    542         break;
    543     case EOpConstructUint16:
    544         promoteTo = EbtUint16;
    545         break;
    546 #endif
    547 
    548     //
    549     // List all the binary ops that can implicitly convert one operand to the other's type;
    550     // This implements the 'policy' for implicit type conversion.
    551     //
    552     case EOpLessThan:
    553     case EOpGreaterThan:
    554     case EOpLessThanEqual:
    555     case EOpGreaterThanEqual:
    556     case EOpEqual:
    557     case EOpNotEqual:
    558 
    559     case EOpAdd:
    560     case EOpSub:
    561     case EOpMul:
    562     case EOpDiv:
    563     case EOpMod:
    564 
    565     case EOpVectorTimesScalar:
    566     case EOpVectorTimesMatrix:
    567     case EOpMatrixTimesVector:
    568     case EOpMatrixTimesScalar:
    569 
    570     case EOpAnd:
    571     case EOpInclusiveOr:
    572     case EOpExclusiveOr:
    573     case EOpAndAssign:
    574     case EOpInclusiveOrAssign:
    575     case EOpExclusiveOrAssign:
    576     case EOpLogicalNot:
    577     case EOpLogicalAnd:
    578     case EOpLogicalOr:
    579     case EOpLogicalXor:
    580 
    581     case EOpFunctionCall:
    582     case EOpReturn:
    583     case EOpAssign:
    584     case EOpAddAssign:
    585     case EOpSubAssign:
    586     case EOpMulAssign:
    587     case EOpVectorTimesScalarAssign:
    588     case EOpMatrixTimesScalarAssign:
    589     case EOpDivAssign:
    590     case EOpModAssign:
    591 
    592     case EOpAtan:
    593     case EOpClamp:
    594     case EOpCross:
    595     case EOpDistance:
    596     case EOpDot:
    597     case EOpDst:
    598     case EOpFaceForward:
    599     case EOpFma:
    600     case EOpFrexp:
    601     case EOpLdexp:
    602     case EOpMix:
    603     case EOpLit:
    604     case EOpMax:
    605     case EOpMin:
    606     case EOpModf:
    607     case EOpPow:
    608     case EOpReflect:
    609     case EOpRefract:
    610     case EOpSmoothStep:
    611     case EOpStep:
    612 
    613     case EOpSequence:
    614     case EOpConstructStruct:
    615 
    616         if (type.getBasicType() == node->getType().getBasicType())
    617             return node;
    618 
    619         if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType(), op))
    620             promoteTo = type.getBasicType();
    621         else
    622             return nullptr;
    623 
    624         break;
    625 
    626     // Shifts can have mixed types as long as they are integer, without converting.
    627     // It's the left operand's type that determines the resulting type, so no issue
    628     // with assign shift ops either.
    629     case EOpLeftShift:
    630     case EOpRightShift:
    631     case EOpLeftShiftAssign:
    632     case EOpRightShiftAssign:
    633         if ((type.getBasicType() == EbtInt ||
    634              type.getBasicType() == EbtUint ||
    635 #ifdef AMD_EXTENSIONS
    636              type.getBasicType() == EbtInt16 ||
    637              type.getBasicType() == EbtUint16 ||
    638 #endif
    639              type.getBasicType() == EbtInt64 ||
    640              type.getBasicType() == EbtUint64) &&
    641             (node->getType().getBasicType() == EbtInt ||
    642              node->getType().getBasicType() == EbtUint ||
    643 #ifdef AMD_EXTENSIONS
    644              node->getType().getBasicType() == EbtInt16 ||
    645              node->getType().getBasicType() == EbtUint16 ||
    646 #endif
    647              node->getType().getBasicType() == EbtInt64 ||
    648              node->getType().getBasicType() == EbtUint64))
    649 
    650             return node;
    651         else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) {
    652             promoteTo = type.getBasicType();
    653             break;
    654         } else
    655             return nullptr;
    656 
    657     default:
    658         // default is to require a match; all exceptions should have case statements above
    659 
    660         if (type.getBasicType() == node->getType().getBasicType())
    661             return node;
    662         else
    663             return nullptr;
    664     }
    665 
    666     if (node->getAsConstantUnion())
    667         return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
    668 
    669     //
    670     // Add a new newNode for the conversion.
    671     //
    672     TIntermUnary* newNode = nullptr;
    673 
    674     TOperator newOp = EOpNull;
    675 
    676     // This is 'mechanism' here, it does any conversion told.  The policy comes
    677     // from the shader or the above code.
    678     switch (promoteTo) {
    679     case EbtDouble:
    680         switch (node->getBasicType()) {
    681         case EbtInt:   newOp = EOpConvIntToDouble;   break;
    682         case EbtUint:  newOp = EOpConvUintToDouble;  break;
    683         case EbtBool:  newOp = EOpConvBoolToDouble;  break;
    684         case EbtFloat: newOp = EOpConvFloatToDouble; break;
    685 #ifdef AMD_EXTENSIONS
    686         case EbtFloat16: newOp = EOpConvFloat16ToDouble; break;
    687 #endif
    688         case EbtInt64: newOp = EOpConvInt64ToDouble; break;
    689         case EbtUint64: newOp = EOpConvUint64ToDouble; break;
    690 #ifdef AMD_EXTENSIONS
    691         case EbtInt16:  newOp = EOpConvInt16ToDouble;  break;
    692         case EbtUint16: newOp = EOpConvUint16ToDouble; break;
    693 #endif
    694         default:
    695             return nullptr;
    696         }
    697         break;
    698     case EbtFloat:
    699         switch (node->getBasicType()) {
    700         case EbtInt:    newOp = EOpConvIntToFloat;    break;
    701         case EbtUint:   newOp = EOpConvUintToFloat;   break;
    702         case EbtBool:   newOp = EOpConvBoolToFloat;   break;
    703         case EbtDouble: newOp = EOpConvDoubleToFloat; break;
    704 #ifdef AMD_EXTENSIONS
    705         case EbtFloat16: newOp = EOpConvFloat16ToFloat; break;
    706 #endif
    707         case EbtInt64:  newOp = EOpConvInt64ToFloat;  break;
    708         case EbtUint64: newOp = EOpConvUint64ToFloat; break;
    709 #ifdef AMD_EXTENSIONS
    710         case EbtInt16:  newOp = EOpConvInt16ToFloat;  break;
    711         case EbtUint16: newOp = EOpConvUint16ToFloat; break;
    712 #endif
    713         default:
    714             return nullptr;
    715         }
    716         break;
    717 #ifdef AMD_EXTENSIONS
    718     case EbtFloat16:
    719         switch (node->getBasicType()) {
    720         case EbtInt:    newOp = EOpConvIntToFloat16;    break;
    721         case EbtUint:   newOp = EOpConvUintToFloat16;   break;
    722         case EbtBool:   newOp = EOpConvBoolToFloat16;   break;
    723         case EbtFloat:  newOp = EOpConvFloatToFloat16;  break;
    724         case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
    725         case EbtInt64:  newOp = EOpConvInt64ToFloat16;  break;
    726         case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
    727         case EbtInt16:  newOp = EOpConvInt16ToFloat16;  break;
    728         case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
    729         default:
    730             return nullptr;
    731         }
    732         break;
    733 #endif
    734     case EbtBool:
    735         switch (node->getBasicType()) {
    736         case EbtInt:    newOp = EOpConvIntToBool;    break;
    737         case EbtUint:   newOp = EOpConvUintToBool;   break;
    738         case EbtFloat:  newOp = EOpConvFloatToBool;  break;
    739         case EbtDouble: newOp = EOpConvDoubleToBool; break;
    740 #ifdef AMD_EXTENSIONS
    741         case EbtFloat16: newOp = EOpConvFloat16ToBool; break;
    742 #endif
    743         case EbtInt64:  newOp = EOpConvInt64ToBool;  break;
    744         case EbtUint64: newOp = EOpConvUint64ToBool; break;
    745 #ifdef AMD_EXTENSIONS
    746         case EbtInt16:  newOp = EOpConvInt16ToBool;  break;
    747         case EbtUint16: newOp = EOpConvUint16ToBool; break;
    748 #endif
    749         default:
    750             return nullptr;
    751         }
    752         break;
    753     case EbtInt:
    754         switch (node->getBasicType()) {
    755         case EbtUint:   newOp = EOpConvUintToInt;   break;
    756         case EbtBool:   newOp = EOpConvBoolToInt;   break;
    757         case EbtFloat:  newOp = EOpConvFloatToInt;  break;
    758         case EbtDouble: newOp = EOpConvDoubleToInt; break;
    759 #ifdef AMD_EXTENSIONS
    760         case EbtFloat16: newOp = EOpConvFloat16ToInt; break;
    761 #endif
    762         case EbtInt64:  newOp = EOpConvInt64ToInt;  break;
    763         case EbtUint64: newOp = EOpConvUint64ToInt; break;
    764 #ifdef AMD_EXTENSIONS
    765         case EbtInt16:  newOp = EOpConvInt16ToInt;  break;
    766         case EbtUint16: newOp = EOpConvUint16ToInt; break;
    767 #endif
    768         default:
    769             return nullptr;
    770         }
    771         break;
    772     case EbtUint:
    773         switch (node->getBasicType()) {
    774         case EbtInt:    newOp = EOpConvIntToUint;    break;
    775         case EbtBool:   newOp = EOpConvBoolToUint;   break;
    776         case EbtFloat:  newOp = EOpConvFloatToUint;  break;
    777         case EbtDouble: newOp = EOpConvDoubleToUint; break;
    778 #ifdef AMD_EXTENSIONS
    779         case EbtFloat16: newOp = EOpConvFloat16ToUint; break;
    780 #endif
    781         case EbtInt64:  newOp = EOpConvInt64ToUint;  break;
    782         case EbtUint64: newOp = EOpConvUint64ToUint; break;
    783 #ifdef AMD_EXTENSIONS
    784         case EbtInt16:  newOp = EOpConvInt16ToUint;  break;
    785         case EbtUint16: newOp = EOpConvUint16ToUint; break;
    786 #endif
    787         default:
    788             return nullptr;
    789         }
    790         break;
    791     case EbtInt64:
    792         switch (node->getBasicType()) {
    793         case EbtInt:    newOp = EOpConvIntToInt64;    break;
    794         case EbtUint:   newOp = EOpConvUintToInt64;   break;
    795         case EbtBool:   newOp = EOpConvBoolToInt64;   break;
    796         case EbtFloat:  newOp = EOpConvFloatToInt64;  break;
    797         case EbtDouble: newOp = EOpConvDoubleToInt64; break;
    798 #ifdef AMD_EXTENSIONS
    799         case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
    800 #endif
    801         case EbtUint64: newOp = EOpConvUint64ToInt64; break;
    802 #ifdef AMD_EXTENSIONS
    803         case EbtInt16:  newOp = EOpConvInt16ToInt64;  break;
    804         case EbtUint16: newOp = EOpConvUint16ToInt64; break;
    805 #endif
    806         default:
    807             return nullptr;
    808         }
    809         break;
    810     case EbtUint64:
    811         switch (node->getBasicType()) {
    812         case EbtInt:    newOp = EOpConvIntToUint64;    break;
    813         case EbtUint:   newOp = EOpConvUintToUint64;   break;
    814         case EbtBool:   newOp = EOpConvBoolToUint64;   break;
    815         case EbtFloat:  newOp = EOpConvFloatToUint64;  break;
    816         case EbtDouble: newOp = EOpConvDoubleToUint64; break;
    817 #ifdef AMD_EXTENSIONS
    818         case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
    819 #endif
    820         case EbtInt64:  newOp = EOpConvInt64ToUint64;  break;
    821 #ifdef AMD_EXTENSIONS
    822         case EbtInt16:  newOp = EOpConvInt16ToUint64;  break;
    823         case EbtUint16: newOp = EOpConvUint16ToUint64; break;
    824 #endif
    825         default:
    826             return nullptr;
    827         }
    828         break;
    829 #ifdef AMD_EXTENSIONS
    830     case EbtInt16:
    831         switch (node->getBasicType()) {
    832         case EbtInt:     newOp = EOpConvIntToInt16;     break;
    833         case EbtUint:    newOp = EOpConvUintToInt16;    break;
    834         case EbtBool:    newOp = EOpConvBoolToInt16;    break;
    835         case EbtFloat:   newOp = EOpConvFloatToInt16;   break;
    836         case EbtDouble:  newOp = EOpConvDoubleToInt16;  break;
    837         case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
    838         case EbtInt64:   newOp = EOpConvInt64ToInt16;   break;
    839         case EbtUint64:  newOp = EOpConvUint64ToInt16;  break;
    840         case EbtUint16:  newOp = EOpConvUint16ToInt16;  break;
    841         default:
    842             return nullptr;
    843         }
    844         break;
    845     case EbtUint16:
    846         switch (node->getBasicType()) {
    847         case EbtInt:     newOp = EOpConvIntToUint16;     break;
    848         case EbtUint:    newOp = EOpConvUintToUint16;    break;
    849         case EbtBool:    newOp = EOpConvBoolToUint16;    break;
    850         case EbtFloat:   newOp = EOpConvFloatToUint16;   break;
    851         case EbtDouble:  newOp = EOpConvDoubleToUint16;  break;
    852         case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
    853         case EbtInt64:   newOp = EOpConvInt64ToUint16;   break;
    854         case EbtUint64:  newOp = EOpConvUint64ToUint16;  break;
    855         case EbtInt16:   newOp = EOpConvInt16ToUint16;   break;
    856         default:
    857             return nullptr;
    858         }
    859         break;
    860 #endif
    861     default:
    862         return nullptr;
    863     }
    864 
    865     TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
    866     newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
    867 
    868     // TODO: it seems that some unary folding operations should occur here, but are not
    869 
    870     // Propagate specialization-constant-ness, if allowed
    871     if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
    872         newNode->getWritableType().getQualifier().makeSpecConstant();
    873 
    874     return newNode;
    875 }
    876 
    877 // Convert the node's shape of type for the given type, as allowed by the
    878 // operation involved: 'op'.  This is for situations where there is only one
    879 // direction to consider doing the shape conversion.
    880 //
    881 // This implements policy, it call addShapeConversion() for the mechanism.
    882 //
    883 // Generally, the AST represents allowed GLSL shapes, so this isn't needed
    884 // for GLSL.  Bad shapes are caught in conversion or promotion.
    885 //
    886 // Return 'node' if no conversion was done. Promotion handles final shape
    887 // checking.
    888 //
    889 TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
    890 {
    891     // some source languages don't do this
    892     switch (source) {
    893     case EShSourceHlsl:
    894         break;
    895     case EShSourceGlsl:
    896     default:
    897         return node;
    898     }
    899 
    900     // some operations don't do this
    901     switch (op) {
    902     case EOpFunctionCall:
    903     case EOpReturn:
    904         break;
    905 
    906     case EOpMulAssign:
    907         // want to support vector *= scalar native ops in AST and lower, not smear, similarly for
    908         // matrix *= scalar, etc.
    909 
    910     case EOpAddAssign:
    911     case EOpSubAssign:
    912     case EOpDivAssign:
    913     case EOpAndAssign:
    914     case EOpInclusiveOrAssign:
    915     case EOpExclusiveOrAssign:
    916     case EOpRightShiftAssign:
    917     case EOpLeftShiftAssign:
    918         if (node->getVectorSize() == 1)
    919             return node;
    920         break;
    921 
    922     case EOpAssign:
    923         break;
    924 
    925     case EOpMix:
    926         break;
    927 
    928     default:
    929         return node;
    930     }
    931 
    932     return addShapeConversion(type, node);
    933 }
    934 
    935 // Convert the nodes' shapes to be compatible for the operation 'op'.
    936 //
    937 // This implements policy, it call addShapeConversion() for the mechanism.
    938 //
    939 // Generally, the AST represents allowed GLSL shapes, so this isn't needed
    940 // for GLSL.  Bad shapes are caught in conversion or promotion.
    941 //
    942 void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
    943 {
    944     // some source languages don't do this
    945     switch (source) {
    946     case EShSourceHlsl:
    947         break;
    948     case EShSourceGlsl:
    949     default:
    950         return;
    951     }
    952 
    953     // some operations don't do this
    954     // 'break' will mean attempt bidirectional conversion
    955     switch (op) {
    956     case EOpMulAssign:
    957     case EOpAssign:
    958     case EOpAddAssign:
    959     case EOpSubAssign:
    960     case EOpDivAssign:
    961     case EOpAndAssign:
    962     case EOpInclusiveOrAssign:
    963     case EOpExclusiveOrAssign:
    964     case EOpRightShiftAssign:
    965     case EOpLeftShiftAssign:
    966         // switch to unidirectional conversion (the lhs can't change)
    967         rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
    968         return;
    969 
    970     case EOpAdd:
    971     case EOpSub:
    972     case EOpMul:
    973     case EOpDiv:
    974         // want to support vector * scalar native ops in AST and lower, not smear, similarly for
    975         // matrix * vector, etc.
    976         if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
    977             return;
    978         break;
    979 
    980     case EOpRightShift:
    981     case EOpLeftShift:
    982         // can natively support the right operand being a scalar and the left a vector,
    983         // but not the reverse
    984         if (rhsNode->getVectorSize() == 1)
    985             return;
    986         break;
    987 
    988     case EOpLessThan:
    989     case EOpGreaterThan:
    990     case EOpLessThanEqual:
    991     case EOpGreaterThanEqual:
    992 
    993     case EOpEqual:
    994     case EOpNotEqual:
    995 
    996     case EOpLogicalAnd:
    997     case EOpLogicalOr:
    998     case EOpLogicalXor:
    999 
   1000     case EOpAnd:
   1001     case EOpInclusiveOr:
   1002     case EOpExclusiveOr:
   1003 
   1004     case EOpMix:
   1005         break;
   1006 
   1007     default:
   1008         return;
   1009     }
   1010 
   1011     // Do bidirectional conversions
   1012     if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
   1013         if (lhsNode->getType().isScalarOrVec1())
   1014             lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
   1015         else
   1016             rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
   1017     }
   1018     lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
   1019     rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
   1020 }
   1021 
   1022 // Convert the node's shape of type for the given type. It's not necessarily
   1023 // an error if they are different and not converted, as some operations accept
   1024 // mixed types.  Promotion will do final shape checking.
   1025 //
   1026 // If there is a chance of two nodes, with conversions possible in each direction,
   1027 // the policy for what to ask for must be in the caller; this will do what is asked.
   1028 //
   1029 // Return 'node' if no conversion was done. Promotion handles final shape
   1030 // checking.
   1031 //
   1032 TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
   1033 {
   1034     // no conversion needed
   1035     if (node->getType() == type)
   1036         return node;
   1037 
   1038     // structures and arrays don't change shape, either to or from
   1039     if (node->getType().isStruct() || node->getType().isArray() ||
   1040         type.isStruct() || type.isArray())
   1041         return node;
   1042 
   1043     // The new node that handles the conversion
   1044     TOperator constructorOp = mapTypeToConstructorOp(type);
   1045 
   1046     // HLSL has custom semantics for scalar->mat shape conversions.
   1047     if (source == EShSourceHlsl) {
   1048         if (node->getType().isScalarOrVec1() && type.isMatrix()) {
   1049 
   1050             // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix.  Left to its
   1051             // own devices, the constructor from a scalar would populate the diagonal.  This forces replication
   1052             // to every matrix element.
   1053 
   1054             // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
   1055             // repeatedly, so we copy it to a temp, then use the temp.
   1056             const int matSize = type.getMatrixRows() * type.getMatrixCols();
   1057             TIntermAggregate* rhsAggregate = new TIntermAggregate();
   1058 
   1059             const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
   1060 
   1061             if (!isSimple) {
   1062                 assert(0); // TODO: use node replicator service when available.
   1063             }
   1064 
   1065             for (int x=0; x<matSize; ++x)
   1066                 rhsAggregate->getSequence().push_back(node);
   1067 
   1068             return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
   1069         }
   1070     }
   1071 
   1072     // scalar -> vector or vec1 -> vector or
   1073     // vector -> scalar or
   1074     // bigger vector -> smaller vector
   1075     if ((node->getType().isScalarOrVec1() && type.isVector()) ||
   1076         (node->getType().isVector() && type.isScalar()) ||
   1077         (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
   1078         return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
   1079 
   1080     return node;
   1081 }
   1082 
   1083 //
   1084 // See if the 'from' type is allowed to be implicitly converted to the
   1085 // 'to' type.  This is not about vector/array/struct, only about basic type.
   1086 //
   1087 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
   1088 {
   1089     if (profile == EEsProfile || version == 110)
   1090         return false;
   1091 
   1092     if (from == to)
   1093         return true;
   1094 
   1095     // TODO: Move more policies into language-specific handlers.
   1096     // Some languages allow more general (or potentially, more specific) conversions under some conditions.
   1097     if (source == EShSourceHlsl) {
   1098         const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool);
   1099         const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool);
   1100 
   1101         if (fromConvertable && toConvertable) {
   1102             switch (op) {
   1103             case EOpAndAssign:               // assignments can perform arbitrary conversions
   1104             case EOpInclusiveOrAssign:       // ...
   1105             case EOpExclusiveOrAssign:       // ...
   1106             case EOpAssign:                  // ...
   1107             case EOpAddAssign:               // ...
   1108             case EOpSubAssign:               // ...
   1109             case EOpMulAssign:               // ...
   1110             case EOpVectorTimesScalarAssign: // ...
   1111             case EOpMatrixTimesScalarAssign: // ...
   1112             case EOpDivAssign:               // ...
   1113             case EOpModAssign:               // ...
   1114             case EOpReturn:                  // function returns can also perform arbitrary conversions
   1115             case EOpFunctionCall:            // conversion of a calling parameter
   1116             case EOpLogicalNot:
   1117             case EOpLogicalAnd:
   1118             case EOpLogicalOr:
   1119             case EOpLogicalXor:
   1120             case EOpConstructStruct:
   1121                 return true;
   1122             default:
   1123                 break;
   1124             }
   1125         }
   1126     }
   1127 
   1128     switch (to) {
   1129     case EbtDouble:
   1130         switch (from) {
   1131         case EbtInt:
   1132         case EbtUint:
   1133         case EbtInt64:
   1134         case EbtUint64:
   1135 #ifdef AMD_EXTENSIONS
   1136         case EbtInt16:
   1137         case EbtUint16:
   1138 #endif
   1139         case EbtFloat:
   1140         case EbtDouble:
   1141 #ifdef AMD_EXTENSIONS
   1142         case EbtFloat16:
   1143 #endif
   1144             return true;
   1145         default:
   1146             return false;
   1147         }
   1148     case EbtFloat:
   1149         switch (from) {
   1150         case EbtInt:
   1151         case EbtUint:
   1152 #ifdef AMD_EXTENSIONS
   1153         case EbtInt16:
   1154         case EbtUint16:
   1155 #endif
   1156         case EbtFloat:
   1157 #ifdef AMD_EXTENSIONS
   1158         case EbtFloat16:
   1159 #endif
   1160             return true;
   1161         case EbtBool:
   1162             return (source == EShSourceHlsl);
   1163         default:
   1164             return false;
   1165         }
   1166     case EbtUint:
   1167         switch (from) {
   1168         case EbtInt:
   1169             return version >= 400 || (source == EShSourceHlsl);
   1170         case EbtUint:
   1171 #ifdef AMD_EXTENSIONS
   1172         case EbtInt16:
   1173         case EbtUint16:
   1174 #endif
   1175             return true;
   1176         case EbtBool:
   1177             return (source == EShSourceHlsl);
   1178         default:
   1179             return false;
   1180         }
   1181     case EbtInt:
   1182         switch (from) {
   1183         case EbtInt:
   1184 #ifdef AMD_EXTENSIONS
   1185         case EbtInt16:
   1186 #endif
   1187             return true;
   1188         case EbtBool:
   1189             return (source == EShSourceHlsl);
   1190         default:
   1191             return false;
   1192         }
   1193     case EbtUint64:
   1194         switch (from) {
   1195         case EbtInt:
   1196         case EbtUint:
   1197         case EbtInt64:
   1198         case EbtUint64:
   1199 #ifdef AMD_EXTENSIONS
   1200         case EbtInt16:
   1201         case EbtUint16:
   1202 #endif
   1203             return true;
   1204         default:
   1205             return false;
   1206         }
   1207     case EbtInt64:
   1208         switch (from) {
   1209         case EbtInt:
   1210         case EbtInt64:
   1211 #ifdef AMD_EXTENSIONS
   1212         case EbtInt16:
   1213 #endif
   1214             return true;
   1215         default:
   1216             return false;
   1217         }
   1218 #ifdef AMD_EXTENSIONS
   1219     case EbtFloat16:
   1220         switch (from) {
   1221         case EbtInt16:
   1222         case EbtUint16:
   1223         case EbtFloat16:
   1224             return true;
   1225         default:
   1226             return false;
   1227         }
   1228     case EbtUint16:
   1229         switch (from) {
   1230         case EbtInt16:
   1231         case EbtUint16:
   1232             return true;
   1233         default:
   1234             return false;
   1235         }
   1236 #endif
   1237     default:
   1238         return false;
   1239     }
   1240 }
   1241 
   1242 //
   1243 // Given a type, find what operation would fully construct it.
   1244 //
   1245 TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
   1246 {
   1247     TOperator op = EOpNull;
   1248 
   1249     switch (type.getBasicType()) {
   1250     case EbtStruct:
   1251         op = EOpConstructStruct;
   1252         break;
   1253     case EbtSampler:
   1254         if (type.getSampler().combined)
   1255             op = EOpConstructTextureSampler;
   1256         break;
   1257     case EbtFloat:
   1258         if (type.isMatrix()) {
   1259             switch (type.getMatrixCols()) {
   1260             case 2:
   1261                 switch (type.getMatrixRows()) {
   1262                 case 2: op = EOpConstructMat2x2; break;
   1263                 case 3: op = EOpConstructMat2x3; break;
   1264                 case 4: op = EOpConstructMat2x4; break;
   1265                 default: break; // some compilers want this
   1266                 }
   1267                 break;
   1268             case 3:
   1269                 switch (type.getMatrixRows()) {
   1270                 case 2: op = EOpConstructMat3x2; break;
   1271                 case 3: op = EOpConstructMat3x3; break;
   1272                 case 4: op = EOpConstructMat3x4; break;
   1273                 default: break; // some compilers want this
   1274                 }
   1275                 break;
   1276             case 4:
   1277                 switch (type.getMatrixRows()) {
   1278                 case 2: op = EOpConstructMat4x2; break;
   1279                 case 3: op = EOpConstructMat4x3; break;
   1280                 case 4: op = EOpConstructMat4x4; break;
   1281                 default: break; // some compilers want this
   1282                 }
   1283                 break;
   1284             default: break; // some compilers want this
   1285             }
   1286         } else {
   1287             switch(type.getVectorSize()) {
   1288             case 1: op = EOpConstructFloat; break;
   1289             case 2: op = EOpConstructVec2;  break;
   1290             case 3: op = EOpConstructVec3;  break;
   1291             case 4: op = EOpConstructVec4;  break;
   1292             default: break; // some compilers want this
   1293             }
   1294         }
   1295         break;
   1296     case EbtDouble:
   1297         if (type.getMatrixCols()) {
   1298             switch (type.getMatrixCols()) {
   1299             case 2:
   1300                 switch (type.getMatrixRows()) {
   1301                 case 2: op = EOpConstructDMat2x2; break;
   1302                 case 3: op = EOpConstructDMat2x3; break;
   1303                 case 4: op = EOpConstructDMat2x4; break;
   1304                 default: break; // some compilers want this
   1305                 }
   1306                 break;
   1307             case 3:
   1308                 switch (type.getMatrixRows()) {
   1309                 case 2: op = EOpConstructDMat3x2; break;
   1310                 case 3: op = EOpConstructDMat3x3; break;
   1311                 case 4: op = EOpConstructDMat3x4; break;
   1312                 default: break; // some compilers want this
   1313                 }
   1314                 break;
   1315             case 4:
   1316                 switch (type.getMatrixRows()) {
   1317                 case 2: op = EOpConstructDMat4x2; break;
   1318                 case 3: op = EOpConstructDMat4x3; break;
   1319                 case 4: op = EOpConstructDMat4x4; break;
   1320                 default: break; // some compilers want this
   1321                 }
   1322                 break;
   1323             }
   1324         } else {
   1325             switch(type.getVectorSize()) {
   1326             case 1: op = EOpConstructDouble; break;
   1327             case 2: op = EOpConstructDVec2;  break;
   1328             case 3: op = EOpConstructDVec3;  break;
   1329             case 4: op = EOpConstructDVec4;  break;
   1330             default: break; // some compilers want this
   1331             }
   1332         }
   1333         break;
   1334 #ifdef AMD_EXTENSIONS
   1335     case EbtFloat16:
   1336         if (type.getMatrixCols()) {
   1337             switch (type.getMatrixCols()) {
   1338             case 2:
   1339                 switch (type.getMatrixRows()) {
   1340                 case 2: op = EOpConstructF16Mat2x2; break;
   1341                 case 3: op = EOpConstructF16Mat2x3; break;
   1342                 case 4: op = EOpConstructF16Mat2x4; break;
   1343                 default: break; // some compilers want this
   1344                 }
   1345                 break;
   1346             case 3:
   1347                 switch (type.getMatrixRows()) {
   1348                 case 2: op = EOpConstructF16Mat3x2; break;
   1349                 case 3: op = EOpConstructF16Mat3x3; break;
   1350                 case 4: op = EOpConstructF16Mat3x4; break;
   1351                 default: break; // some compilers want this
   1352                 }
   1353                 break;
   1354             case 4:
   1355                 switch (type.getMatrixRows()) {
   1356                 case 2: op = EOpConstructF16Mat4x2; break;
   1357                 case 3: op = EOpConstructF16Mat4x3; break;
   1358                 case 4: op = EOpConstructF16Mat4x4; break;
   1359                 default: break; // some compilers want this
   1360                 }
   1361                 break;
   1362             }
   1363         }
   1364         else {
   1365             switch (type.getVectorSize()) {
   1366             case 1: op = EOpConstructFloat16;  break;
   1367             case 2: op = EOpConstructF16Vec2;  break;
   1368             case 3: op = EOpConstructF16Vec3;  break;
   1369             case 4: op = EOpConstructF16Vec4;  break;
   1370             default: break; // some compilers want this
   1371             }
   1372         }
   1373         break;
   1374 #endif
   1375     case EbtInt:
   1376         if (type.getMatrixCols()) {
   1377             switch (type.getMatrixCols()) {
   1378             case 2:
   1379                 switch (type.getMatrixRows()) {
   1380                 case 2: op = EOpConstructIMat2x2; break;
   1381                 case 3: op = EOpConstructIMat2x3; break;
   1382                 case 4: op = EOpConstructIMat2x4; break;
   1383                 default: break; // some compilers want this
   1384                 }
   1385                 break;
   1386             case 3:
   1387                 switch (type.getMatrixRows()) {
   1388                 case 2: op = EOpConstructIMat3x2; break;
   1389                 case 3: op = EOpConstructIMat3x3; break;
   1390                 case 4: op = EOpConstructIMat3x4; break;
   1391                 default: break; // some compilers want this
   1392                 }
   1393                 break;
   1394             case 4:
   1395                 switch (type.getMatrixRows()) {
   1396                 case 2: op = EOpConstructIMat4x2; break;
   1397                 case 3: op = EOpConstructIMat4x3; break;
   1398                 case 4: op = EOpConstructIMat4x4; break;
   1399                 default: break; // some compilers want this
   1400                 }
   1401                 break;
   1402             }
   1403         } else {
   1404             switch(type.getVectorSize()) {
   1405             case 1: op = EOpConstructInt;   break;
   1406             case 2: op = EOpConstructIVec2; break;
   1407             case 3: op = EOpConstructIVec3; break;
   1408             case 4: op = EOpConstructIVec4; break;
   1409             default: break; // some compilers want this
   1410             }
   1411         }
   1412         break;
   1413     case EbtUint:
   1414         if (type.getMatrixCols()) {
   1415             switch (type.getMatrixCols()) {
   1416             case 2:
   1417                 switch (type.getMatrixRows()) {
   1418                 case 2: op = EOpConstructUMat2x2; break;
   1419                 case 3: op = EOpConstructUMat2x3; break;
   1420                 case 4: op = EOpConstructUMat2x4; break;
   1421                 default: break; // some compilers want this
   1422                 }
   1423                 break;
   1424             case 3:
   1425                 switch (type.getMatrixRows()) {
   1426                 case 2: op = EOpConstructUMat3x2; break;
   1427                 case 3: op = EOpConstructUMat3x3; break;
   1428                 case 4: op = EOpConstructUMat3x4; break;
   1429                 default: break; // some compilers want this
   1430                 }
   1431                 break;
   1432             case 4:
   1433                 switch (type.getMatrixRows()) {
   1434                 case 2: op = EOpConstructUMat4x2; break;
   1435                 case 3: op = EOpConstructUMat4x3; break;
   1436                 case 4: op = EOpConstructUMat4x4; break;
   1437                 default: break; // some compilers want this
   1438                 }
   1439                 break;
   1440             }
   1441         } else {
   1442             switch(type.getVectorSize()) {
   1443             case 1: op = EOpConstructUint;  break;
   1444             case 2: op = EOpConstructUVec2; break;
   1445             case 3: op = EOpConstructUVec3; break;
   1446             case 4: op = EOpConstructUVec4; break;
   1447             default: break; // some compilers want this
   1448             }
   1449         }
   1450         break;
   1451     case EbtInt64:
   1452         switch(type.getVectorSize()) {
   1453         case 1: op = EOpConstructInt64;   break;
   1454         case 2: op = EOpConstructI64Vec2; break;
   1455         case 3: op = EOpConstructI64Vec3; break;
   1456         case 4: op = EOpConstructI64Vec4; break;
   1457         default: break; // some compilers want this
   1458         }
   1459         break;
   1460     case EbtUint64:
   1461         switch(type.getVectorSize()) {
   1462         case 1: op = EOpConstructUint64;  break;
   1463         case 2: op = EOpConstructU64Vec2; break;
   1464         case 3: op = EOpConstructU64Vec3; break;
   1465         case 4: op = EOpConstructU64Vec4; break;
   1466         default: break; // some compilers want this
   1467         }
   1468         break;
   1469 #ifdef AMD_EXTENSIONS
   1470     case EbtInt16:
   1471         switch(type.getVectorSize()) {
   1472         case 1: op = EOpConstructInt16;   break;
   1473         case 2: op = EOpConstructI16Vec2; break;
   1474         case 3: op = EOpConstructI16Vec3; break;
   1475         case 4: op = EOpConstructI16Vec4; break;
   1476         default: break; // some compilers want this
   1477         }
   1478         break;
   1479     case EbtUint16:
   1480         switch(type.getVectorSize()) {
   1481         case 1: op = EOpConstructUint16;  break;
   1482         case 2: op = EOpConstructU16Vec2; break;
   1483         case 3: op = EOpConstructU16Vec3; break;
   1484         case 4: op = EOpConstructU16Vec4; break;
   1485         default: break; // some compilers want this
   1486         }
   1487         break;
   1488 #endif
   1489     case EbtBool:
   1490         if (type.getMatrixCols()) {
   1491             switch (type.getMatrixCols()) {
   1492             case 2:
   1493                 switch (type.getMatrixRows()) {
   1494                 case 2: op = EOpConstructBMat2x2; break;
   1495                 case 3: op = EOpConstructBMat2x3; break;
   1496                 case 4: op = EOpConstructBMat2x4; break;
   1497                 default: break; // some compilers want this
   1498                 }
   1499                 break;
   1500             case 3:
   1501                 switch (type.getMatrixRows()) {
   1502                 case 2: op = EOpConstructBMat3x2; break;
   1503                 case 3: op = EOpConstructBMat3x3; break;
   1504                 case 4: op = EOpConstructBMat3x4; break;
   1505                 default: break; // some compilers want this
   1506                 }
   1507                 break;
   1508             case 4:
   1509                 switch (type.getMatrixRows()) {
   1510                 case 2: op = EOpConstructBMat4x2; break;
   1511                 case 3: op = EOpConstructBMat4x3; break;
   1512                 case 4: op = EOpConstructBMat4x4; break;
   1513                 default: break; // some compilers want this
   1514                 }
   1515                 break;
   1516             }
   1517         } else {
   1518             switch(type.getVectorSize()) {
   1519             case 1:  op = EOpConstructBool;  break;
   1520             case 2:  op = EOpConstructBVec2; break;
   1521             case 3:  op = EOpConstructBVec3; break;
   1522             case 4:  op = EOpConstructBVec4; break;
   1523             default: break; // some compilers want this
   1524             }
   1525         }
   1526         break;
   1527     default:
   1528         break;
   1529     }
   1530 
   1531     return op;
   1532 }
   1533 
   1534 //
   1535 // Safe way to combine two nodes into an aggregate.  Works with null pointers,
   1536 // a node that's not a aggregate yet, etc.
   1537 //
   1538 // Returns the resulting aggregate, unless nullptr was passed in for
   1539 // both existing nodes.
   1540 //
   1541 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
   1542 {
   1543     if (left == nullptr && right == nullptr)
   1544         return nullptr;
   1545 
   1546     TIntermAggregate* aggNode = nullptr;
   1547     if (left != nullptr)
   1548         aggNode = left->getAsAggregate();
   1549     if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
   1550         aggNode = new TIntermAggregate;
   1551         if (left != nullptr)
   1552             aggNode->getSequence().push_back(left);
   1553     }
   1554 
   1555     if (right != nullptr)
   1556         aggNode->getSequence().push_back(right);
   1557 
   1558     return aggNode;
   1559 }
   1560 
   1561 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
   1562 {
   1563     TIntermAggregate* aggNode = growAggregate(left, right);
   1564     if (aggNode)
   1565         aggNode->setLoc(loc);
   1566 
   1567     return aggNode;
   1568 }
   1569 
   1570 //
   1571 // Turn an existing node into an aggregate.
   1572 //
   1573 // Returns an aggregate, unless nullptr was passed in for the existing node.
   1574 //
   1575 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
   1576 {
   1577     if (node == nullptr)
   1578         return nullptr;
   1579 
   1580     TIntermAggregate* aggNode = new TIntermAggregate;
   1581     aggNode->getSequence().push_back(node);
   1582     aggNode->setLoc(node->getLoc());
   1583 
   1584     return aggNode;
   1585 }
   1586 
   1587 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
   1588 {
   1589     if (node == nullptr)
   1590         return nullptr;
   1591 
   1592     TIntermAggregate* aggNode = new TIntermAggregate;
   1593     aggNode->getSequence().push_back(node);
   1594     aggNode->setLoc(loc);
   1595 
   1596     return aggNode;
   1597 }
   1598 
   1599 //
   1600 // Make an aggregate with an empty sequence.
   1601 //
   1602 TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
   1603 {
   1604     TIntermAggregate* aggNode = new TIntermAggregate;
   1605     aggNode->setLoc(loc);
   1606 
   1607     return aggNode;
   1608 }
   1609 
   1610 //
   1611 // For "if" test nodes.  There are three children; a condition,
   1612 // a true path, and a false path.  The two paths are in the
   1613 // nodePair.
   1614 //
   1615 // Returns the selection node created.
   1616 //
   1617 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control)
   1618 {
   1619     //
   1620     // Don't prune the false path for compile-time constants; it's needed
   1621     // for static access analysis.
   1622     //
   1623 
   1624     TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
   1625     node->setLoc(loc);
   1626     node->setSelectionControl(control);
   1627 
   1628     return node;
   1629 }
   1630 
   1631 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
   1632 {
   1633     // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
   1634     // ... are not included in the operators that can create a constant expression.
   1635     //
   1636     // if (left->getType().getQualifier().storage == EvqConst &&
   1637     //    right->getType().getQualifier().storage == EvqConst) {
   1638 
   1639     //    return right;
   1640     //}
   1641 
   1642     TIntermTyped *commaAggregate = growAggregate(left, right, loc);
   1643     commaAggregate->getAsAggregate()->setOperator(EOpComma);
   1644     commaAggregate->setType(right->getType());
   1645     commaAggregate->getWritableType().getQualifier().makeTemporary();
   1646 
   1647     return commaAggregate;
   1648 }
   1649 
   1650 TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
   1651 {
   1652     TIntermMethod* method = new TIntermMethod(object, type, *name);
   1653     method->setLoc(loc);
   1654 
   1655     return method;
   1656 }
   1657 
   1658 //
   1659 // For "?:" test nodes.  There are three children; a condition,
   1660 // a true path, and a false path.  The two paths are specified
   1661 // as separate parameters. For vector 'cond', the true and false
   1662 // are not paths, but vectors to mix.
   1663 //
   1664 // Specialization constant operations include
   1665 //     - The ternary operator ( ? : )
   1666 //
   1667 // Returns the selection node created, or nullptr if one could not be.
   1668 //
   1669 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control)
   1670 {
   1671     // If it's void, go to the if-then-else selection()
   1672     if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
   1673         TIntermNodePair pair = { trueBlock, falseBlock };
   1674         return addSelection(cond, pair, loc, control);
   1675     }
   1676 
   1677     //
   1678     // Get compatible types.
   1679     //
   1680     TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
   1681     if (child)
   1682         falseBlock = child;
   1683     else {
   1684         child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
   1685         if (child)
   1686             trueBlock = child;
   1687         else
   1688             return nullptr;
   1689     }
   1690 
   1691     // Handle a vector condition as a mix
   1692     if (!cond->getType().isScalarOrVec1()) {
   1693         TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
   1694                                cond->getType().getVectorSize());
   1695         // smear true/false operands as needed
   1696         trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
   1697         falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);
   1698 
   1699         // After conversion, types have to match.
   1700         if (falseBlock->getType() != trueBlock->getType())
   1701             return nullptr;
   1702 
   1703         // make the mix operation
   1704         TIntermAggregate* mix = makeAggregate(loc);
   1705         mix = growAggregate(mix, falseBlock);
   1706         mix = growAggregate(mix, trueBlock);
   1707         mix = growAggregate(mix, cond);
   1708         mix->setType(targetVectorType);
   1709         mix->setOp(EOpMix);
   1710 
   1711         return mix;
   1712     }
   1713 
   1714     // Now have a scalar condition...
   1715 
   1716     // Convert true and false expressions to matching types
   1717     addBiShapeConversion(EOpMix, trueBlock, falseBlock);
   1718 
   1719     // After conversion, types have to match.
   1720     if (falseBlock->getType() != trueBlock->getType())
   1721         return nullptr;
   1722 
   1723     // Eliminate the selection when the condition is a scalar and all operands are constant.
   1724     if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
   1725         if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
   1726             return trueBlock;
   1727         else
   1728             return falseBlock;
   1729     }
   1730 
   1731     //
   1732     // Make a selection node.
   1733     //
   1734     TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
   1735     node->setLoc(loc);
   1736     node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
   1737 
   1738     if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
   1739         (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
   1740                                                  falseBlock->getQualifier().isConstant()))
   1741         node->getQualifier().makeSpecConstant();
   1742     else
   1743         node->getQualifier().makeTemporary();
   1744 
   1745     return node;
   1746 }
   1747 
   1748 //
   1749 // Constant terminal nodes.  Has a union that contains bool, float or int constants
   1750 //
   1751 // Returns the constant union node created.
   1752 //
   1753 
   1754 TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
   1755 {
   1756     TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
   1757     node->getQualifier().storage = EvqConst;
   1758     node->setLoc(loc);
   1759     if (literal)
   1760         node->setLiteral();
   1761 
   1762     return node;
   1763 }
   1764 
   1765 TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
   1766 {
   1767     TConstUnionArray unionArray(1);
   1768     unionArray[0].setIConst(i);
   1769 
   1770     return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
   1771 }
   1772 
   1773 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
   1774 {
   1775     TConstUnionArray unionArray(1);
   1776     unionArray[0].setUConst(u);
   1777 
   1778     return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
   1779 }
   1780 
   1781 TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const
   1782 {
   1783     TConstUnionArray unionArray(1);
   1784     unionArray[0].setI64Const(i64);
   1785 
   1786     return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal);
   1787 }
   1788 
   1789 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const
   1790 {
   1791     TConstUnionArray unionArray(1);
   1792     unionArray[0].setU64Const(u64);
   1793 
   1794     return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
   1795 }
   1796 
   1797 #ifdef AMD_EXTENSIONS
   1798 TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const
   1799 {
   1800     TConstUnionArray unionArray(1);
   1801     unionArray[0].setIConst(i16);
   1802 
   1803     return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal);
   1804 }
   1805 
   1806 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const
   1807 {
   1808     TConstUnionArray unionArray(1);
   1809     unionArray[0].setUConst(u16);
   1810 
   1811     return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal);
   1812 }
   1813 #endif
   1814 
   1815 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
   1816 {
   1817     TConstUnionArray unionArray(1);
   1818     unionArray[0].setBConst(b);
   1819 
   1820     return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
   1821 }
   1822 
   1823 TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
   1824 {
   1825 #ifdef AMD_EXTENSIONS
   1826     assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
   1827 #else
   1828     assert(baseType == EbtFloat || baseType == EbtDouble);
   1829 #endif
   1830 
   1831     TConstUnionArray unionArray(1);
   1832     unionArray[0].setDConst(d);
   1833 
   1834     return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
   1835 }
   1836 
   1837 TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const
   1838 {
   1839     TConstUnionArray unionArray(1);
   1840     unionArray[0].setSConst(s);
   1841 
   1842     return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal);
   1843 }
   1844 
   1845 // Put vector swizzle selectors onto the given sequence
   1846 void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc)
   1847 {
   1848     TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc);
   1849     sequence.push_back(constIntNode);
   1850 }
   1851 
   1852 // Put matrix swizzle selectors onto the given sequence
   1853 void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc)
   1854 {
   1855     TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc);
   1856     sequence.push_back(constIntNode);
   1857     constIntNode = addConstantUnion(selector.coord2, loc);
   1858     sequence.push_back(constIntNode);
   1859 }
   1860 
   1861 // Make an aggregate node that has a sequence of all selectors.
   1862 template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc);
   1863 template TIntermTyped* TIntermediate::addSwizzle<TMatrixSelector>(TSwizzleSelectors<TMatrixSelector>& selector, const TSourceLoc& loc);
   1864 template<typename selectorType>
   1865 TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selector, const TSourceLoc& loc)
   1866 {
   1867     TIntermAggregate* node = new TIntermAggregate(EOpSequence);
   1868 
   1869     node->setLoc(loc);
   1870     TIntermSequence &sequenceVector = node->getSequence();
   1871 
   1872     for (int i = 0; i < selector.size(); i++)
   1873         pushSelector(sequenceVector, selector[i], loc);
   1874 
   1875     return node;
   1876 }
   1877 
   1878 //
   1879 // Follow the left branches down to the root of an l-value
   1880 // expression (just "." and []).
   1881 //
   1882 // Return the base of the l-value (where following indexing quits working).
   1883 // Return nullptr if a chain following dereferences cannot be followed.
   1884 //
   1885 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
   1886 // a valid part of the dereference chain.
   1887 //
   1888 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
   1889 {
   1890     do {
   1891         const TIntermBinary* binary = node->getAsBinaryNode();
   1892         if (binary == nullptr)
   1893             return node;
   1894         TOperator op = binary->getOp();
   1895         if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
   1896             return nullptr;
   1897         if (! swizzleOkay) {
   1898             if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
   1899                 return nullptr;
   1900             if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
   1901                 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
   1902                 ! binary->getLeft()->getType().isArray())
   1903                 return nullptr;
   1904         }
   1905         node = node->getAsBinaryNode()->getLeft();
   1906     } while (true);
   1907 }
   1908 
   1909 //
   1910 // Create while and do-while loop nodes.
   1911 //
   1912 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
   1913 {
   1914     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
   1915     node->setLoc(loc);
   1916     node->setLoopControl(control);
   1917 
   1918     return node;
   1919 }
   1920 
   1921 //
   1922 // Create a for-loop sequence.
   1923 //
   1924 TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
   1925 {
   1926     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
   1927     node->setLoc(loc);
   1928     node->setLoopControl(control);
   1929 
   1930     // make a sequence of the initializer and statement, but try to reuse the
   1931     // aggregate already created for whatever is in the initializer, if there is one
   1932     TIntermAggregate* loopSequence = (initializer == nullptr ||
   1933                                       initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
   1934                                                                                 : initializer->getAsAggregate();
   1935     if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
   1936         loopSequence->setOp(EOpNull);
   1937     loopSequence = growAggregate(loopSequence, node);
   1938     loopSequence->setOperator(EOpSequence);
   1939 
   1940     return loopSequence;
   1941 }
   1942 
   1943 //
   1944 // Add branches.
   1945 //
   1946 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
   1947 {
   1948     return addBranch(branchOp, nullptr, loc);
   1949 }
   1950 
   1951 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
   1952 {
   1953     TIntermBranch* node = new TIntermBranch(branchOp, expression);
   1954     node->setLoc(loc);
   1955 
   1956     return node;
   1957 }
   1958 
   1959 //
   1960 // This is to be executed after the final root is put on top by the parsing
   1961 // process.
   1962 //
   1963 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
   1964 {
   1965     if (root == nullptr)
   1966         return true;
   1967 
   1968     // Finish off the top-level sequence
   1969     TIntermAggregate* aggRoot = root->getAsAggregate();
   1970     if (aggRoot && aggRoot->getOp() == EOpNull)
   1971         aggRoot->setOperator(EOpSequence);
   1972 
   1973     // Propagate 'noContraction' label in backward from 'precise' variables.
   1974     glslang::PropagateNoContraction(*this);
   1975 
   1976     switch (textureSamplerTransformMode) {
   1977     case EShTexSampTransKeep:
   1978         break;
   1979     case EShTexSampTransUpgradeTextureRemoveSampler:
   1980         performTextureUpgradeAndSamplerRemovalTransformation(root);
   1981         break;
   1982     }
   1983 
   1984     return true;
   1985 }
   1986 
   1987 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
   1988 {
   1989     // Add top-level nodes for declarations that must be checked cross
   1990     // compilation unit by a linker, yet might not have been referenced
   1991     // by the AST.
   1992     //
   1993     // Almost entirely, translation of symbols is driven by what's present
   1994     // in the AST traversal, not by translating the symbol table.
   1995     //
   1996     // However, there are some special cases:
   1997     //  - From the specification: "Special built-in inputs gl_VertexID and
   1998     //    gl_InstanceID are also considered active vertex attributes."
   1999     //  - Linker-based type mismatch error reporting needs to see all
   2000     //    uniforms/ins/outs variables and blocks.
   2001     //  - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active.
   2002     //
   2003 
   2004     // if (ftransformUsed) {
   2005         // TODO: 1.1 lowering functionality: track ftransform() usage
   2006     //    addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
   2007     //    addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
   2008     //}
   2009 
   2010     if (language == EShLangVertex) {
   2011         // the names won't be found in the symbol table unless the versions are right,
   2012         // so version logic does not need to be repeated here
   2013         addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
   2014         addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
   2015     }
   2016 
   2017     // Add a child to the root node for the linker objects
   2018     linkage->setOperator(EOpLinkerObjects);
   2019     treeRoot = growAggregate(treeRoot, linkage);
   2020 }
   2021 
   2022 //
   2023 // Add the given name or symbol to the list of nodes at the end of the tree used
   2024 // for link-time checking and external linkage.
   2025 //
   2026 
   2027 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
   2028 {
   2029     TSymbol* symbol = symbolTable.find(name);
   2030     if (symbol)
   2031         addSymbolLinkageNode(linkage, *symbol->getAsVariable());
   2032 }
   2033 
   2034 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
   2035 {
   2036     const TVariable* variable = symbol.getAsVariable();
   2037     if (! variable) {
   2038         // This must be a member of an anonymous block, and we need to add the whole block
   2039         const TAnonMember* anon = symbol.getAsAnonMember();
   2040         variable = &anon->getAnonContainer();
   2041     }
   2042     TIntermSymbol* node = addSymbol(*variable);
   2043     linkage = growAggregate(linkage, node);
   2044 }
   2045 
   2046 //
   2047 // Add a caller->callee relationship to the call graph.
   2048 // Assumes the strings are unique per signature.
   2049 //
   2050 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
   2051 {
   2052     // Duplicates are okay, but faster to not keep them, and they come grouped by caller,
   2053     // as long as new ones are push on the same end we check on for duplicates
   2054     for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
   2055         if (call->caller != caller)
   2056             break;
   2057         if (call->callee == callee)
   2058             return;
   2059     }
   2060 
   2061     callGraph.push_front(TCall(caller, callee));
   2062 }
   2063 
   2064 //
   2065 // This deletes the tree.
   2066 //
   2067 void TIntermediate::removeTree()
   2068 {
   2069     if (treeRoot)
   2070         RemoveAllTreeNodes(treeRoot);
   2071 }
   2072 
   2073 //
   2074 // Implement the part of KHR_vulkan_glsl that lists the set of operations
   2075 // that can result in a specialization constant operation.
   2076 //
   2077 // "5.x Specialization Constant Operations"
   2078 //
   2079 //    Only some operations discussed in this section may be applied to a
   2080 //    specialization constant and still yield a result that is as
   2081 //    specialization constant.  The operations allowed are listed below.
   2082 //    When a specialization constant is operated on with one of these
   2083 //    operators and with another constant or specialization constant, the
   2084 //    result is implicitly a specialization constant.
   2085 //
   2086 //     - int(), uint(), and bool() constructors for type conversions
   2087 //       from any of the following types to any of the following types:
   2088 //         * int
   2089 //         * uint
   2090 //         * bool
   2091 //     - vector versions of the above conversion constructors
   2092 //     - allowed implicit conversions of the above
   2093 //     - swizzles (e.g., foo.yx)
   2094 //     - The following when applied to integer or unsigned integer types:
   2095 //         * unary negative ( - )
   2096 //         * binary operations ( + , - , * , / , % )
   2097 //         * shift ( <<, >> )
   2098 //         * bitwise operations ( & , | , ^ )
   2099 //     - The following when applied to integer or unsigned integer scalar types:
   2100 //         * comparison ( == , != , > , >= , < , <= )
   2101 //     - The following when applied to the Boolean scalar type:
   2102 //         * not ( ! )
   2103 //         * logical operations ( && , || , ^^ )
   2104 //         * comparison ( == , != )"
   2105 //
   2106 // This function just handles binary and unary nodes.  Construction
   2107 // rules are handled in construction paths that are not covered by the unary
   2108 // and binary paths, while required conversions will still show up here
   2109 // as unary converters in the from a construction operator.
   2110 //
   2111 bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
   2112 {
   2113     // The operations resulting in floating point are quite limited
   2114     // (However, some floating-point operations result in bool, like ">",
   2115     // so are handled later.)
   2116     if (node.getType().isFloatingDomain()) {
   2117         switch (node.getOp()) {
   2118         case EOpIndexDirect:
   2119         case EOpIndexIndirect:
   2120         case EOpIndexDirectStruct:
   2121         case EOpVectorSwizzle:
   2122         case EOpConvFloatToDouble:
   2123         case EOpConvDoubleToFloat:
   2124 #ifdef AMD_EXTENSIONS
   2125         case EOpConvFloat16ToFloat:
   2126         case EOpConvFloatToFloat16:
   2127         case EOpConvFloat16ToDouble:
   2128         case EOpConvDoubleToFloat16:
   2129 #endif
   2130             return true;
   2131         default:
   2132             return false;
   2133         }
   2134     }
   2135 
   2136     // Check for floating-point arguments
   2137     if (const TIntermBinary* bin = node.getAsBinaryNode())
   2138         if (bin->getLeft() ->getType().isFloatingDomain() ||
   2139             bin->getRight()->getType().isFloatingDomain())
   2140             return false;
   2141 
   2142     // So, for now, we can assume everything left is non-floating-point...
   2143 
   2144     // Now check for integer/bool-based operations
   2145     switch (node.getOp()) {
   2146 
   2147     // dereference/swizzle
   2148     case EOpIndexDirect:
   2149     case EOpIndexIndirect:
   2150     case EOpIndexDirectStruct:
   2151     case EOpVectorSwizzle:
   2152 
   2153     // conversion constructors
   2154     case EOpConvIntToBool:
   2155     case EOpConvUintToBool:
   2156     case EOpConvUintToInt:
   2157     case EOpConvBoolToInt:
   2158     case EOpConvIntToUint:
   2159     case EOpConvBoolToUint:
   2160     case EOpConvInt64ToBool:
   2161     case EOpConvBoolToInt64:
   2162     case EOpConvUint64ToBool:
   2163     case EOpConvBoolToUint64:
   2164     case EOpConvInt64ToInt:
   2165     case EOpConvIntToInt64:
   2166     case EOpConvUint64ToUint:
   2167     case EOpConvUintToUint64:
   2168     case EOpConvInt64ToUint64:
   2169     case EOpConvUint64ToInt64:
   2170     case EOpConvInt64ToUint:
   2171     case EOpConvUintToInt64:
   2172     case EOpConvUint64ToInt:
   2173     case EOpConvIntToUint64:
   2174 #ifdef AMD_EXTENSIONS
   2175     case EOpConvInt16ToBool:
   2176     case EOpConvBoolToInt16:
   2177     case EOpConvInt16ToInt:
   2178     case EOpConvIntToInt16:
   2179     case EOpConvInt16ToUint:
   2180     case EOpConvUintToInt16:
   2181     case EOpConvInt16ToInt64:
   2182     case EOpConvInt64ToInt16:
   2183     case EOpConvInt16ToUint64:
   2184     case EOpConvUint64ToInt16:
   2185     case EOpConvUint16ToBool:
   2186     case EOpConvBoolToUint16:
   2187     case EOpConvUint16ToInt:
   2188     case EOpConvIntToUint16:
   2189     case EOpConvUint16ToUint:
   2190     case EOpConvUintToUint16:
   2191     case EOpConvUint16ToInt64:
   2192     case EOpConvInt64ToUint16:
   2193     case EOpConvUint16ToUint64:
   2194     case EOpConvUint64ToUint16:
   2195     case EOpConvInt16ToUint16:
   2196     case EOpConvUint16ToInt16:
   2197 #endif
   2198 
   2199     // unary operations
   2200     case EOpNegative:
   2201     case EOpLogicalNot:
   2202     case EOpBitwiseNot:
   2203 
   2204     // binary operations
   2205     case EOpAdd:
   2206     case EOpSub:
   2207     case EOpMul:
   2208     case EOpVectorTimesScalar:
   2209     case EOpDiv:
   2210     case EOpMod:
   2211     case EOpRightShift:
   2212     case EOpLeftShift:
   2213     case EOpAnd:
   2214     case EOpInclusiveOr:
   2215     case EOpExclusiveOr:
   2216     case EOpLogicalOr:
   2217     case EOpLogicalXor:
   2218     case EOpLogicalAnd:
   2219     case EOpEqual:
   2220     case EOpNotEqual:
   2221     case EOpLessThan:
   2222     case EOpGreaterThan:
   2223     case EOpLessThanEqual:
   2224     case EOpGreaterThanEqual:
   2225         return true;
   2226     default:
   2227         return false;
   2228     }
   2229 }
   2230 
   2231 ////////////////////////////////////////////////////////////////
   2232 //
   2233 // Member functions of the nodes used for building the tree.
   2234 //
   2235 ////////////////////////////////////////////////////////////////
   2236 
   2237 //
   2238 // Say whether or not an operation node changes the value of a variable.
   2239 //
   2240 // Returns true if state is modified.
   2241 //
   2242 bool TIntermOperator::modifiesState() const
   2243 {
   2244     switch (op) {
   2245     case EOpPostIncrement:
   2246     case EOpPostDecrement:
   2247     case EOpPreIncrement:
   2248     case EOpPreDecrement:
   2249     case EOpAssign:
   2250     case EOpAddAssign:
   2251     case EOpSubAssign:
   2252     case EOpMulAssign:
   2253     case EOpVectorTimesMatrixAssign:
   2254     case EOpVectorTimesScalarAssign:
   2255     case EOpMatrixTimesScalarAssign:
   2256     case EOpMatrixTimesMatrixAssign:
   2257     case EOpDivAssign:
   2258     case EOpModAssign:
   2259     case EOpAndAssign:
   2260     case EOpInclusiveOrAssign:
   2261     case EOpExclusiveOrAssign:
   2262     case EOpLeftShiftAssign:
   2263     case EOpRightShiftAssign:
   2264         return true;
   2265     default:
   2266         return false;
   2267     }
   2268 }
   2269 
   2270 //
   2271 // returns true if the operator is for one of the constructors
   2272 //
   2273 bool TIntermOperator::isConstructor() const
   2274 {
   2275     return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
   2276 }
   2277 
   2278 //
   2279 // Make sure the type of an operator is appropriate for its
   2280 // combination of operation and operand type.  This will invoke
   2281 // promoteUnary, promoteBinary, etc as needed.
   2282 //
   2283 // Returns false if nothing makes sense.
   2284 //
   2285 bool TIntermediate::promote(TIntermOperator* node)
   2286 {
   2287     if (node == nullptr)
   2288         return false;
   2289 
   2290     if (node->getAsUnaryNode())
   2291         return promoteUnary(*node->getAsUnaryNode());
   2292 
   2293     if (node->getAsBinaryNode())
   2294         return promoteBinary(*node->getAsBinaryNode());
   2295 
   2296     if (node->getAsAggregate())
   2297         return promoteAggregate(*node->getAsAggregate());
   2298 
   2299     return false;
   2300 }
   2301 
   2302 //
   2303 // See TIntermediate::promote
   2304 //
   2305 bool TIntermediate::promoteUnary(TIntermUnary& node)
   2306 {
   2307     const TOperator op    = node.getOp();
   2308     TIntermTyped* operand = node.getOperand();
   2309 
   2310     switch (op) {
   2311     case EOpLogicalNot:
   2312         // Convert operand to a boolean type
   2313         if (operand->getBasicType() != EbtBool) {
   2314             // Add constructor to boolean type. If that fails, we can't do it, so return false.
   2315             TIntermTyped* converted = convertToBasicType(op, EbtBool, operand);
   2316             if (converted == nullptr)
   2317                 return false;
   2318 
   2319             // Use the result of converting the node to a bool.
   2320             node.setOperand(operand = converted); // also updates stack variable
   2321         }
   2322         break;
   2323     case EOpBitwiseNot:
   2324         if (operand->getBasicType() != EbtInt &&
   2325             operand->getBasicType() != EbtUint &&
   2326 #ifdef AMD_EXTENSIONS
   2327             operand->getBasicType() != EbtInt16 &&
   2328             operand->getBasicType() != EbtUint16 &&
   2329 #endif
   2330             operand->getBasicType() != EbtInt64 &&
   2331             operand->getBasicType() != EbtUint64)
   2332 
   2333             return false;
   2334         break;
   2335     case EOpNegative:
   2336     case EOpPostIncrement:
   2337     case EOpPostDecrement:
   2338     case EOpPreIncrement:
   2339     case EOpPreDecrement:
   2340         if (operand->getBasicType() != EbtInt &&
   2341             operand->getBasicType() != EbtUint &&
   2342             operand->getBasicType() != EbtInt64 &&
   2343             operand->getBasicType() != EbtUint64 &&
   2344 #ifdef AMD_EXTENSIONS
   2345             operand->getBasicType() != EbtInt16 &&
   2346             operand->getBasicType() != EbtUint16 &&
   2347 #endif
   2348             operand->getBasicType() != EbtFloat &&
   2349 #ifdef AMD_EXTENSIONS
   2350             operand->getBasicType() != EbtFloat16 &&
   2351 #endif
   2352             operand->getBasicType() != EbtDouble)
   2353 
   2354             return false;
   2355         break;
   2356 
   2357     default:
   2358         if (operand->getBasicType() != EbtFloat)
   2359 
   2360             return false;
   2361     }
   2362 
   2363     node.setType(operand->getType());
   2364     node.getWritableType().getQualifier().makeTemporary();
   2365 
   2366     return true;
   2367 }
   2368 
   2369 void TIntermUnary::updatePrecision()
   2370 {
   2371 #ifdef AMD_EXTENSIONS
   2372     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
   2373 #else
   2374     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
   2375 #endif
   2376         if (operand->getQualifier().precision > getQualifier().precision)
   2377             getQualifier().precision = operand->getQualifier().precision;
   2378     }
   2379 }
   2380 
   2381 // If it is not already, convert this node to the given basic type.
   2382 TIntermTyped* TIntermediate::convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const
   2383 {
   2384     if (node == nullptr)
   2385         return nullptr;
   2386 
   2387     // It's already this basic type: nothing needs to be done, so use the node directly.
   2388     if (node->getBasicType() == basicType)
   2389         return node;
   2390 
   2391     const TType& type = node->getType();
   2392     const TType newType(basicType, type.getQualifier().storage,
   2393                         type.getVectorSize(), type.getMatrixCols(), type.getMatrixRows(), type.isVector());
   2394 
   2395     // Add constructor to the right vectorness of the right type. If that fails, we can't do it, so return nullptr.
   2396     return addConversion(op, newType, node);
   2397 }
   2398 
   2399 //
   2400 // See TIntermediate::promote
   2401 //
   2402 bool TIntermediate::promoteBinary(TIntermBinary& node)
   2403 {
   2404     TOperator     op    = node.getOp();
   2405     TIntermTyped* left  = node.getLeft();
   2406     TIntermTyped* right = node.getRight();
   2407 
   2408     // Arrays and structures have to be exact matches.
   2409     if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
   2410         && left->getType() != right->getType())
   2411         return false;
   2412 
   2413     // Base assumption:  just make the type the same as the left
   2414     // operand.  Only deviations from this will be coded.
   2415     node.setType(left->getType());
   2416     node.getWritableType().getQualifier().clear();
   2417 
   2418     // Composite and opaque types don't having pending operator changes, e.g.,
   2419     // array, structure, and samplers.  Just establish final type and correctness.
   2420     if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) {
   2421         switch (op) {
   2422         case EOpEqual:
   2423         case EOpNotEqual:
   2424             if (left->getBasicType() == EbtSampler) {
   2425                 // can't compare samplers
   2426                 return false;
   2427             } else {
   2428                 // Promote to conditional
   2429                 node.setType(TType(EbtBool));
   2430             }
   2431 
   2432             return true;
   2433 
   2434         case EOpAssign:
   2435             // Keep type from above
   2436 
   2437             return true;
   2438 
   2439         default:
   2440             return false;
   2441         }
   2442     }
   2443 
   2444     //
   2445     // We now have only scalars, vectors, and matrices to worry about.
   2446     //
   2447 
   2448     // HLSL implicitly promotes bool -> int for numeric operations.
   2449     // (Implicit conversions to make the operands match each other's types were already done.)
   2450     if (getSource() == EShSourceHlsl &&
   2451         (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) {
   2452         switch (op) {
   2453         case EOpLessThan:
   2454         case EOpGreaterThan:
   2455         case EOpLessThanEqual:
   2456         case EOpGreaterThanEqual:
   2457 
   2458         case EOpRightShift:
   2459         case EOpLeftShift:
   2460 
   2461         case EOpMod:
   2462 
   2463         case EOpAnd:
   2464         case EOpInclusiveOr:
   2465         case EOpExclusiveOr:
   2466 
   2467         case EOpAdd:
   2468         case EOpSub:
   2469         case EOpDiv:
   2470         case EOpMul:
   2471             left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left);
   2472             right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right);
   2473             if (left == nullptr || right == nullptr)
   2474                 return false;
   2475             node.setLeft(left);
   2476             node.setRight(right);
   2477             break;
   2478 
   2479         default:
   2480             break;
   2481         }
   2482     }
   2483 
   2484     // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
   2485     switch (op) {
   2486     case EOpLessThan:
   2487     case EOpGreaterThan:
   2488     case EOpLessThanEqual:
   2489     case EOpGreaterThanEqual:
   2490         // Relational comparisons need numeric types and will promote to scalar Boolean.
   2491         if (left->getBasicType() == EbtBool)
   2492             return false;
   2493 
   2494         node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
   2495         break;
   2496 
   2497     case EOpEqual:
   2498     case EOpNotEqual:
   2499         if (getSource() == EShSourceHlsl) {
   2500             const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize());
   2501 
   2502             // In HLSL, == or != on vectors means component-wise comparison.
   2503             if (resultWidth > 1) {
   2504                 op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual;
   2505                 node.setOp(op);
   2506             }
   2507 
   2508             node.setType(TType(EbtBool, EvqTemporary, resultWidth));
   2509         } else {
   2510             // All the above comparisons result in a bool (but not the vector compares)
   2511             node.setType(TType(EbtBool));
   2512         }
   2513         break;
   2514 
   2515     case EOpLogicalAnd:
   2516     case EOpLogicalOr:
   2517     case EOpLogicalXor:
   2518         if (getSource() == EShSourceHlsl) {
   2519             TIntermTyped* convertedL = convertToBasicType(op, EbtBool, left);
   2520             TIntermTyped* convertedR = convertToBasicType(op, EbtBool, right);
   2521             if (convertedL == nullptr || convertedR == nullptr)
   2522                 return false;
   2523             node.setLeft(left = convertedL);   // also updates stack variable
   2524             node.setRight(right = convertedR); // also updates stack variable
   2525         } else {
   2526             // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
   2527             if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix())
   2528                 return false;
   2529         }
   2530 
   2531         node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
   2532 
   2533         break;
   2534 
   2535     case EOpRightShift:
   2536     case EOpLeftShift:
   2537     case EOpRightShiftAssign:
   2538     case EOpLeftShiftAssign:
   2539 
   2540     case EOpMod:
   2541     case EOpModAssign:
   2542 
   2543     case EOpAnd:
   2544     case EOpInclusiveOr:
   2545     case EOpExclusiveOr:
   2546     case EOpAndAssign:
   2547     case EOpInclusiveOrAssign:
   2548     case EOpExclusiveOrAssign:
   2549         if (getSource() == EShSourceHlsl)
   2550             break;
   2551 
   2552         // Check for integer-only operands.
   2553         if ((left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint &&
   2554 #ifdef AMD_EXTENSIONS
   2555              left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 &&
   2556 #endif
   2557              left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) ||
   2558             (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
   2559 #ifdef AMD_EXTENSIONS
   2560              right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 &&
   2561 #endif
   2562              right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
   2563             return false;
   2564         if (left->isMatrix() || right->isMatrix())
   2565             return false;
   2566 
   2567         break;
   2568 
   2569     case EOpAdd:
   2570     case EOpSub:
   2571     case EOpDiv:
   2572     case EOpMul:
   2573     case EOpAddAssign:
   2574     case EOpSubAssign:
   2575     case EOpMulAssign:
   2576     case EOpDivAssign:
   2577         // check for non-Boolean operands
   2578         if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
   2579             return false;
   2580 
   2581     default:
   2582         break;
   2583     }
   2584 
   2585     // Compare left and right, and finish with the cases where the operand types must match
   2586     switch (op) {
   2587     case EOpLessThan:
   2588     case EOpGreaterThan:
   2589     case EOpLessThanEqual:
   2590     case EOpGreaterThanEqual:
   2591 
   2592     case EOpEqual:
   2593     case EOpNotEqual:
   2594     case EOpVectorEqual:
   2595     case EOpVectorNotEqual:
   2596 
   2597     case EOpLogicalAnd:
   2598     case EOpLogicalOr:
   2599     case EOpLogicalXor:
   2600         return left->getType() == right->getType();
   2601 
   2602     case EOpMod:
   2603     case EOpModAssign:
   2604 
   2605     case EOpAnd:
   2606     case EOpInclusiveOr:
   2607     case EOpExclusiveOr:
   2608     case EOpAndAssign:
   2609     case EOpInclusiveOrAssign:
   2610     case EOpExclusiveOrAssign:
   2611 
   2612     case EOpAdd:
   2613     case EOpSub:
   2614     case EOpDiv:
   2615 
   2616     case EOpAddAssign:
   2617     case EOpSubAssign:
   2618     case EOpDivAssign:
   2619         // Quick out in case the types do match
   2620         if (left->getType() == right->getType())
   2621             return true;
   2622 
   2623         // Fall through
   2624 
   2625     case EOpMul:
   2626     case EOpMulAssign:
   2627         // At least the basic type has to match
   2628         if (left->getBasicType() != right->getBasicType())
   2629             return false;
   2630 
   2631     default:
   2632         break;
   2633     }
   2634 
   2635     // Finish handling the case, for all ops, where both operands are scalars.
   2636     if (left->isScalar() && right->isScalar())
   2637         return true;
   2638 
   2639     // Finish handling the case, for all ops, where there are two vectors of different sizes
   2640     if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
   2641         return false;
   2642 
   2643     //
   2644     // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
   2645     //
   2646 
   2647     // Can these two operands be combined, what is the resulting type?
   2648     TBasicType basicType = left->getBasicType();
   2649     switch (op) {
   2650     case EOpMul:
   2651         if (!left->isMatrix() && right->isMatrix()) {
   2652             if (left->isVector()) {
   2653                 if (left->getVectorSize() != right->getMatrixRows())
   2654                     return false;
   2655                 node.setOp(op = EOpVectorTimesMatrix);
   2656                 node.setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
   2657             } else {
   2658                 node.setOp(op = EOpMatrixTimesScalar);
   2659                 node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
   2660             }
   2661         } else if (left->isMatrix() && !right->isMatrix()) {
   2662             if (right->isVector()) {
   2663                 if (left->getMatrixCols() != right->getVectorSize())
   2664                     return false;
   2665                 node.setOp(op = EOpMatrixTimesVector);
   2666                 node.setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
   2667             } else {
   2668                 node.setOp(op = EOpMatrixTimesScalar);
   2669             }
   2670         } else if (left->isMatrix() && right->isMatrix()) {
   2671             if (left->getMatrixCols() != right->getMatrixRows())
   2672                 return false;
   2673             node.setOp(op = EOpMatrixTimesMatrix);
   2674             node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
   2675         } else if (! left->isMatrix() && ! right->isMatrix()) {
   2676             if (left->isVector() && right->isVector()) {
   2677                 ; // leave as component product
   2678             } else if (left->isVector() || right->isVector()) {
   2679                 node.setOp(op = EOpVectorTimesScalar);
   2680                 if (right->isVector())
   2681                     node.setType(TType(basicType, EvqTemporary, right->getVectorSize()));
   2682             }
   2683         } else {
   2684             return false;
   2685         }
   2686         break;
   2687     case EOpMulAssign:
   2688         if (! left->isMatrix() && right->isMatrix()) {
   2689             if (left->isVector()) {
   2690                 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
   2691                     return false;
   2692                 node.setOp(op = EOpVectorTimesMatrixAssign);
   2693             } else {
   2694                 return false;
   2695             }
   2696         } else if (left->isMatrix() && !right->isMatrix()) {
   2697             if (right->isVector()) {
   2698                 return false;
   2699             } else {
   2700                 node.setOp(op = EOpMatrixTimesScalarAssign);
   2701             }
   2702         } else if (left->isMatrix() && right->isMatrix()) {
   2703             if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
   2704                 return false;
   2705             node.setOp(op = EOpMatrixTimesMatrixAssign);
   2706         } else if (!left->isMatrix() && !right->isMatrix()) {
   2707             if (left->isVector() && right->isVector()) {
   2708                 // leave as component product
   2709             } else if (left->isVector() || right->isVector()) {
   2710                 if (! left->isVector())
   2711                     return false;
   2712                 node.setOp(op = EOpVectorTimesScalarAssign);
   2713             }
   2714         } else {
   2715             return false;
   2716         }
   2717         break;
   2718 
   2719     case EOpRightShift:
   2720     case EOpLeftShift:
   2721     case EOpRightShiftAssign:
   2722     case EOpLeftShiftAssign:
   2723         if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
   2724             return false;
   2725         break;
   2726 
   2727     case EOpAssign:
   2728         if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
   2729             return false;
   2730         // fall through
   2731 
   2732     case EOpAdd:
   2733     case EOpSub:
   2734     case EOpDiv:
   2735     case EOpMod:
   2736     case EOpAnd:
   2737     case EOpInclusiveOr:
   2738     case EOpExclusiveOr:
   2739     case EOpAddAssign:
   2740     case EOpSubAssign:
   2741     case EOpDivAssign:
   2742     case EOpModAssign:
   2743     case EOpAndAssign:
   2744     case EOpInclusiveOrAssign:
   2745     case EOpExclusiveOrAssign:
   2746 
   2747         if ((left->isMatrix() && right->isVector()) ||
   2748             (left->isVector() && right->isMatrix()) ||
   2749             left->getBasicType() != right->getBasicType())
   2750             return false;
   2751         if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
   2752             return false;
   2753         if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
   2754             return false;
   2755         if (right->isVector() || right->isMatrix()) {
   2756             node.getWritableType().shallowCopy(right->getType());
   2757             node.getWritableType().getQualifier().makeTemporary();
   2758         }
   2759         break;
   2760 
   2761     default:
   2762         return false;
   2763     }
   2764 
   2765     //
   2766     // One more check for assignment.
   2767     //
   2768     switch (op) {
   2769     // The resulting type has to match the left operand.
   2770     case EOpAssign:
   2771     case EOpAddAssign:
   2772     case EOpSubAssign:
   2773     case EOpMulAssign:
   2774     case EOpDivAssign:
   2775     case EOpModAssign:
   2776     case EOpAndAssign:
   2777     case EOpInclusiveOrAssign:
   2778     case EOpExclusiveOrAssign:
   2779     case EOpLeftShiftAssign:
   2780     case EOpRightShiftAssign:
   2781         if (node.getType() != left->getType())
   2782             return false;
   2783         break;
   2784     default:
   2785         break;
   2786     }
   2787 
   2788     return true;
   2789 }
   2790 
   2791 //
   2792 // See TIntermediate::promote
   2793 //
   2794 bool TIntermediate::promoteAggregate(TIntermAggregate& node)
   2795 {
   2796     TOperator op = node.getOp();
   2797     TIntermSequence& args = node.getSequence();
   2798     const int numArgs = static_cast<int>(args.size());
   2799 
   2800     // Presently, only hlsl does intrinsic promotions.
   2801     if (getSource() != EShSourceHlsl)
   2802         return true;
   2803 
   2804     // set of opcodes that can be promoted in this manner.
   2805     switch (op) {
   2806     case EOpAtan:
   2807     case EOpClamp:
   2808     case EOpCross:
   2809     case EOpDistance:
   2810     case EOpDot:
   2811     case EOpDst:
   2812     case EOpFaceForward:
   2813     // case EOpFindMSB: TODO:
   2814     // case EOpFindLSB: TODO:
   2815     case EOpFma:
   2816     case EOpMod:
   2817     case EOpFrexp:
   2818     case EOpLdexp:
   2819     case EOpMix:
   2820     case EOpLit:
   2821     case EOpMax:
   2822     case EOpMin:
   2823     case EOpModf:
   2824     // case EOpGenMul: TODO:
   2825     case EOpPow:
   2826     case EOpReflect:
   2827     case EOpRefract:
   2828     // case EOpSinCos: TODO:
   2829     case EOpSmoothStep:
   2830     case EOpStep:
   2831         break;
   2832     default:
   2833         return true;
   2834     }
   2835 
   2836     // TODO: array and struct behavior
   2837 
   2838     // Try converting all nodes to the given node's type
   2839     TIntermSequence convertedArgs(numArgs, nullptr);
   2840 
   2841     // Try to convert all types to the nonConvArg type.
   2842     for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) {
   2843         // Try converting all args to this arg's type
   2844         for (int convArg = 0; convArg < numArgs; ++convArg) {
   2845             convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(),
   2846                                                    args[convArg]->getAsTyped());
   2847         }
   2848 
   2849         // If we successfully converted all the args, use the result.
   2850         if (std::all_of(convertedArgs.begin(), convertedArgs.end(),
   2851                         [](const TIntermNode* node) { return node != nullptr; })) {
   2852 
   2853             std::swap(args, convertedArgs);
   2854             return true;
   2855         }
   2856     }
   2857 
   2858     return false;
   2859 }
   2860 
   2861 void TIntermBinary::updatePrecision()
   2862 {
   2863 #ifdef AMD_EXTENSIONS
   2864     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
   2865 #else
   2866     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
   2867 #endif
   2868         getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
   2869         if (getQualifier().precision != EpqNone) {
   2870             left->propagatePrecision(getQualifier().precision);
   2871             right->propagatePrecision(getQualifier().precision);
   2872         }
   2873     }
   2874 }
   2875 
   2876 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
   2877 {
   2878 #ifdef AMD_EXTENSIONS
   2879     if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
   2880 #else
   2881     if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat))
   2882 #endif
   2883         return;
   2884 
   2885     getQualifier().precision = newPrecision;
   2886 
   2887     TIntermBinary* binaryNode = getAsBinaryNode();
   2888     if (binaryNode) {
   2889         binaryNode->getLeft()->propagatePrecision(newPrecision);
   2890         binaryNode->getRight()->propagatePrecision(newPrecision);
   2891 
   2892         return;
   2893     }
   2894 
   2895     TIntermUnary* unaryNode = getAsUnaryNode();
   2896     if (unaryNode) {
   2897         unaryNode->getOperand()->propagatePrecision(newPrecision);
   2898 
   2899         return;
   2900     }
   2901 
   2902     TIntermAggregate* aggregateNode = getAsAggregate();
   2903     if (aggregateNode) {
   2904         TIntermSequence operands = aggregateNode->getSequence();
   2905         for (unsigned int i = 0; i < operands.size(); ++i) {
   2906             TIntermTyped* typedNode = operands[i]->getAsTyped();
   2907             if (! typedNode)
   2908                 break;
   2909             typedNode->propagatePrecision(newPrecision);
   2910         }
   2911 
   2912         return;
   2913     }
   2914 
   2915     TIntermSelection* selectionNode = getAsSelectionNode();
   2916     if (selectionNode) {
   2917         TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
   2918         if (typedNode) {
   2919             typedNode->propagatePrecision(newPrecision);
   2920             typedNode = selectionNode->getFalseBlock()->getAsTyped();
   2921             if (typedNode)
   2922                 typedNode->propagatePrecision(newPrecision);
   2923         }
   2924 
   2925         return;
   2926     }
   2927 }
   2928 
   2929 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
   2930 {
   2931     const TConstUnionArray& rightUnionArray = node->getConstArray();
   2932     int size = node->getType().computeNumComponents();
   2933 
   2934     TConstUnionArray leftUnionArray(size);
   2935 
   2936     for (int i=0; i < size; i++) {
   2937         switch (promoteTo) {
   2938         case EbtFloat:
   2939             switch (node->getType().getBasicType()) {
   2940             case EbtInt:
   2941                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
   2942                 break;
   2943             case EbtUint:
   2944                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
   2945                 break;
   2946             case EbtInt64:
   2947                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const()));
   2948                 break;
   2949             case EbtUint64:
   2950                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const()));
   2951                 break;
   2952             case EbtBool:
   2953                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
   2954                 break;
   2955             case EbtFloat:
   2956             case EbtDouble:
   2957 #ifdef AMD_EXTENSIONS
   2958             case EbtFloat16:
   2959 #endif
   2960                 leftUnionArray[i] = rightUnionArray[i];
   2961                 break;
   2962             default:
   2963                 return node;
   2964             }
   2965             break;
   2966         case EbtDouble:
   2967             switch (node->getType().getBasicType()) {
   2968             case EbtInt:
   2969                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
   2970                 break;
   2971             case EbtUint:
   2972                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
   2973                 break;
   2974             case EbtInt64:
   2975                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const()));
   2976                 break;
   2977             case EbtUint64:
   2978                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const()));
   2979                 break;
   2980             case EbtBool:
   2981                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
   2982                 break;
   2983             case EbtFloat:
   2984             case EbtDouble:
   2985 #ifdef AMD_EXTENSIONS
   2986             case EbtFloat16:
   2987 #endif
   2988                 leftUnionArray[i] = rightUnionArray[i];
   2989                 break;
   2990             default:
   2991                 return node;
   2992             }
   2993             break;
   2994 #ifdef AMD_EXTENSIONS
   2995         case EbtFloat16:
   2996             switch (node->getType().getBasicType()) {
   2997             case EbtInt:
   2998                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
   2999                 break;
   3000             case EbtUint:
   3001                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
   3002                 break;
   3003             case EbtInt64:
   3004                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const()));
   3005                 break;
   3006             case EbtUint64:
   3007                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const()));
   3008                 break;
   3009             case EbtBool:
   3010                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
   3011                 break;
   3012             case EbtFloat:
   3013             case EbtDouble:
   3014             case EbtFloat16:
   3015                 leftUnionArray[i] = rightUnionArray[i];
   3016                 break;
   3017             default:
   3018                 return node;
   3019             }
   3020             break;
   3021 #endif
   3022         case EbtInt:
   3023             switch (node->getType().getBasicType()) {
   3024             case EbtInt:
   3025                 leftUnionArray[i] = rightUnionArray[i];
   3026                 break;
   3027             case EbtUint:
   3028                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst()));
   3029                 break;
   3030             case EbtInt64:
   3031                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getI64Const()));
   3032                 break;
   3033             case EbtUint64:
   3034                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getU64Const()));
   3035                 break;
   3036             case EbtBool:
   3037                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
   3038                 break;
   3039             case EbtFloat:
   3040             case EbtDouble:
   3041 #ifdef AMD_EXTENSIONS
   3042             case EbtFloat16:
   3043 #endif
   3044                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
   3045                 break;
   3046             default:
   3047                 return node;
   3048             }
   3049             break;
   3050         case EbtUint:
   3051             switch (node->getType().getBasicType()) {
   3052             case EbtInt:
   3053                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst()));
   3054                 break;
   3055             case EbtUint:
   3056                 leftUnionArray[i] = rightUnionArray[i];
   3057                 break;
   3058             case EbtInt64:
   3059                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getI64Const()));
   3060                 break;
   3061             case EbtUint64:
   3062                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getU64Const()));
   3063                 break;
   3064             case EbtBool:
   3065                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst()));
   3066                 break;
   3067             case EbtFloat:
   3068             case EbtDouble:
   3069 #ifdef AMD_EXTENSIONS
   3070             case EbtFloat16:
   3071 #endif
   3072                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
   3073                 break;
   3074             default:
   3075                 return node;
   3076             }
   3077             break;
   3078         case EbtBool:
   3079             switch (node->getType().getBasicType()) {
   3080             case EbtInt:
   3081                 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
   3082                 break;
   3083             case EbtUint:
   3084                 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0);
   3085                 break;
   3086             case EbtInt64:
   3087                 leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0);
   3088                 break;
   3089             case EbtUint64:
   3090                 leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0);
   3091                 break;
   3092             case EbtBool:
   3093                 leftUnionArray[i] = rightUnionArray[i];
   3094                 break;
   3095             case EbtFloat:
   3096             case EbtDouble:
   3097 #ifdef AMD_EXTENSIONS
   3098             case EbtFloat16:
   3099 #endif
   3100                 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
   3101                 break;
   3102             default:
   3103                 return node;
   3104             }
   3105             break;
   3106         case EbtInt64:
   3107             switch (node->getType().getBasicType()) {
   3108             case EbtInt:
   3109                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getIConst()));
   3110                 break;
   3111             case EbtUint:
   3112                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getUConst()));
   3113                 break;
   3114             case EbtInt64:
   3115                 leftUnionArray[i] = rightUnionArray[i];
   3116                 break;
   3117             case EbtUint64:
   3118                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getU64Const()));
   3119                 break;
   3120             case EbtBool:
   3121                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getBConst()));
   3122                 break;
   3123             case EbtFloat:
   3124             case EbtDouble:
   3125 #ifdef AMD_EXTENSIONS
   3126             case EbtFloat16:
   3127 #endif
   3128                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getDConst()));
   3129                 break;
   3130             default:
   3131                 return node;
   3132             }
   3133             break;
   3134         case EbtUint64:
   3135             switch (node->getType().getBasicType()) {
   3136             case EbtInt:
   3137                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getIConst()));
   3138                 break;
   3139             case EbtUint:
   3140                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getUConst()));
   3141                 break;
   3142             case EbtInt64:
   3143                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getI64Const()));
   3144                 break;
   3145             case EbtUint64:
   3146                 leftUnionArray[i] = rightUnionArray[i];
   3147                 break;
   3148             case EbtBool:
   3149                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getBConst()));
   3150                 break;
   3151             case EbtFloat:
   3152             case EbtDouble:
   3153 #ifdef AMD_EXTENSIONS
   3154             case EbtFloat16:
   3155 #endif
   3156                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getDConst()));
   3157                 break;
   3158             default:
   3159                 return node;
   3160             }
   3161             break;
   3162         default:
   3163             return node;
   3164         }
   3165     }
   3166 
   3167     const TType& t = node->getType();
   3168 
   3169     return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
   3170                             node->getLoc());
   3171 }
   3172 
   3173 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
   3174 {
   3175     assert(!pragmaTable);
   3176     pragmaTable = new TPragmaTable();
   3177     *pragmaTable = pTable;
   3178 }
   3179 
   3180 // If either node is a specialization constant, while the other is
   3181 // a constant (or specialization constant), the result is still
   3182 // a specialization constant.
   3183 bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
   3184 {
   3185     return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
   3186            (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
   3187 }
   3188 
   3189 struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
   3190     void visitSymbol(TIntermSymbol* symbol) override {
   3191         if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
   3192             symbol->getWritableType().getSampler().combined = true;
   3193         }
   3194     }
   3195     bool visitAggregate(TVisit, TIntermAggregate* ag) override {
   3196         using namespace std;
   3197         TIntermSequence& seq = ag->getSequence();
   3198         // remove pure sampler variables
   3199         TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
   3200             TIntermSymbol* symbol = node->getAsSymbolNode();
   3201             if (!symbol)
   3202                 return false;
   3203 
   3204             return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
   3205         });
   3206         seq.erase(newEnd, seq.end());
   3207         // replace constructors with sampler/textures
   3208         for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
   3209             TIntermAggregate *constructor = node->getAsAggregate();
   3210             if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
   3211                 if (!constructor->getSequence().empty())
   3212                     node = constructor->getSequence()[0];
   3213             }
   3214         });
   3215         return true;
   3216     }
   3217 };
   3218 
   3219 void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
   3220 {
   3221     TextureUpgradeAndSamplerRemovalTransform transform;
   3222     root->traverse(&transform);
   3223 }
   3224 
   3225 } // end namespace glslang
   3226