@@ -219,7 +219,7 @@ void DecomposeLongs::DecomposeNode(GenTree** ppTree, Compiler::fgWalkData* data)
219219 break ;
220220
221221 case GT_NEG:
222- NYI ( " GT_NEG of TYP_LONG " );
222+ DecomposeNeg (ppTree, data );
223223 break ;
224224
225225 // Binary operators. Those that require different computation for upper and lower half are
@@ -905,6 +905,56 @@ void DecomposeLongs::DecomposeNot(GenTree** ppTree, Compiler::fgWalkData* data)
905905 FinalizeDecomposition (ppTree, data, loResult, hiResult);
906906}
907907
908+ // ------------------------------------------------------------------------
909+ // DecomposeNeg: Decompose GT_NEG.
910+ //
911+ // Arguments:
912+ // ppTree - the tree to decompose
913+ // data - tree walk context
914+ //
915+ // Return Value:
916+ // None.
917+ //
918+ void DecomposeLongs::DecomposeNeg (GenTree** ppTree, Compiler::fgWalkData* data)
919+ {
920+ assert (ppTree != nullptr );
921+ assert (*ppTree != nullptr );
922+ assert (data != nullptr );
923+ assert ((*ppTree)->OperGet () == GT_NEG);
924+ assert (m_compiler->compCurStmt != nullptr );
925+
926+ GenTreeStmt* curStmt = m_compiler->compCurStmt ->AsStmt ();
927+ GenTree* tree = *ppTree;
928+ GenTree* op1 = tree->gtGetOp1 ();
929+ noway_assert (op1->OperGet () == GT_LONG);
930+
931+ CreateTemporary (&(op1->gtOp .gtOp1 ));
932+ CreateTemporary (&(op1->gtOp .gtOp2 ));
933+ // Neither GT_NEG nor the introduced temporaries have side effects.
934+ tree->gtFlags &= ~GTF_ALL_EFFECT;
935+ GenTree* loOp1 = op1->gtGetOp1 ();
936+ GenTree* hiOp1 = op1->gtGetOp2 ();
937+ Compiler::fgSnipNode (curStmt, op1);
938+
939+ GenTree* loResult = tree;
940+ loResult->gtType = TYP_INT;
941+ loResult->gtOp .gtOp1 = loOp1;
942+
943+ GenTree* zero = m_compiler->gtNewZeroConNode (TYP_INT);
944+ GenTree* hiAdjust = m_compiler->gtNewOperNode (GT_ADD_HI, TYP_INT, hiOp1, zero);
945+ GenTree* hiResult = m_compiler->gtNewOperNode (GT_NEG, TYP_INT, hiAdjust);
946+ hiResult->gtFlags = tree->gtFlags ;
947+
948+ Compiler::fgSnipNode (curStmt, hiOp1);
949+ // fgSnipNode doesn't clear gtNext/gtPrev...
950+ hiOp1->gtNext = nullptr ;
951+ hiOp1->gtPrev = nullptr ;
952+ SimpleLinkNodeAfter (hiOp1, zero);
953+ SimpleLinkNodeAfter (zero, hiAdjust);
954+ SimpleLinkNodeAfter (hiAdjust, hiResult);
955+
956+ FinalizeDecomposition (ppTree, data, loResult, hiResult);
957+ }
908958
909959// ------------------------------------------------------------------------
910960// DecomposeArith: Decompose GT_ADD, GT_SUB, GT_OR, GT_XOR, GT_AND.
0 commit comments