@@ -526,8 +526,8 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
526526#ifdef TARGET_ARM64
527527if (binOp->OperIs (GT_AND, GT_OR))
528528 {
529- GenTree* next = TryLowerAndOrToCCMP (binOp) ;
530- if (next != nullptr )
529+ GenTree* next;
530+ if (TryLowerAndOrToCCMP (binOp, &next) )
531531 {
532532return next;
533533 }
@@ -536,8 +536,8 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
536536if (binOp->OperIs (GT_SUB))
537537 {
538538// Attempt to optimize for umsubl/smsubl.
539- GenTree* next = TryLowerAddSubToMulLongOp (binOp) ;
540- if (next != nullptr )
539+ GenTree* next;
540+ if (TryLowerAddSubToMulLongOp (binOp, &next) )
541541 {
542542return next;
543543 }
@@ -957,25 +957,29 @@ void Lowering::LowerModPow2(GenTree* node)
957957//
958958// Arguments:
959959// node - the node to lower
960+ // next - [out] Next node to lower if this function returns true
960961//
961- GenTree*Lowering::LowerAddForPossibleContainment (GenTreeOp* node)
962+ // Return Value:
963+ // false if no changes were made
964+ //
965+ bool Lowering::TryLowerAddForPossibleContainment (GenTreeOp* node, GenTree** next)
962966{
963967assert (node->OperIs (GT_ADD));
964968
965969if (!comp->opts .OptimizationEnabled ())
966- return nullptr ;
970+ return false ;
967971
968972if (node->isContained ())
969- return nullptr ;
973+ return false ;
970974
971975if (!varTypeIsIntegral (node))
972- return nullptr ;
976+ return false ;
973977
974978if (node->gtFlags & GTF_SET_FLAGS)
975- return nullptr ;
979+ return false ;
976980
977981if (node->gtOverflow ())
978- return nullptr ;
982+ return false ;
979983
980984 GenTree* op1 = node->gtGetOp1 ();
981985 GenTree* op2 = node->gtGetOp2 ();
@@ -984,7 +988,7 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
984988// then we do not want to risk moving it around
985989// in this transformation.
986990if (IsContainableImmed (node, op2))
987- return nullptr ;
991+ return false ;
988992
989993 GenTree* mul =nullptr ;
990994 GenTree* c =nullptr ;
@@ -1018,7 +1022,8 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
10181022
10191023ContainCheckNode (node);
10201024
1021- return node->gtNext ;
1025+ *next = node->gtNext ;
1026+ return true ;
10221027 }
10231028// Transform "a * -b + c" to "c - a * b"
10241029else if (b->OperIs (GT_NEG) && !(b->gtFlags & GTF_SET_FLAGS) && !a->OperIs (GT_NEG) && !b->isContained () &&
@@ -1032,7 +1037,8 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
10321037
10331038ContainCheckNode (node);
10341039
1035- return node->gtNext ;
1040+ *next = node->gtNext ;
1041+ return true ;
10361042 }
10371043// Transform "a * b + c" to "c + a * b"
10381044else if (op1->OperIs (GT_MUL))
@@ -1042,11 +1048,12 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
10421048
10431049ContainCheckNode (node);
10441050
1045- return node->gtNext ;
1051+ *next = node->gtNext ;
1052+ return true ;
10461053 }
10471054 }
10481055
1049- return nullptr ;
1056+ return false ;
10501057}
10511058#endif
10521059
@@ -2349,14 +2356,18 @@ void Lowering::ContainCheckCompare(GenTreeOp* cmp)
23492356//
23502357// Arguments:
23512358// tree - pointer to the node
2359+ // next - [out] Next node to lower if this function returns true
2360+ //
2361+ // Return Value:
2362+ // false if no changes were made
23522363//
2353- GenTree* Lowering::TryLowerAndOrToCCMP (GenTreeOp* tree)
2364+ bool Lowering::TryLowerAndOrToCCMP (GenTreeOp* tree, GenTree** next )
23542365{
23552366assert (tree->OperIs (GT_AND, GT_OR));
23562367
23572368if (!comp->opts .OptimizationEnabled ())
23582369 {
2359- return nullptr ;
2370+ return false ;
23602371 }
23612372
23622373 GenTree* op1 = tree->gtGetOp1 ();
@@ -2395,7 +2406,7 @@ GenTree* Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree)
23952406 {
23962407JITDUMP (" ..could not turn [%06u] or [%06u] into a def of flags, bailing\n " ,Compiler::dspTreeID (op1),
23972408Compiler::dspTreeID (op2));
2398- return nullptr ;
2409+ return false ;
23992410 }
24002411
24012412BlockRange ().Remove (op2);
@@ -2437,7 +2448,8 @@ GenTree* Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree)
24372448DISPTREERANGE (BlockRange (), tree);
24382449JITDUMP (" \n " );
24392450
2440- return tree->gtNext ;
2451+ *next = tree->gtNext ;
2452+ return true ;
24412453}
24422454
24432455// ------------------------------------------------------------------------
@@ -2781,32 +2793,33 @@ void Lowering::TryLowerCnsIntCselToCinc(GenTreeOp* select, GenTree* cond)
27812793// - One op is a MUL_LONG containing two integer operands, and the other is a long.
27822794//
27832795// Arguments:
2784- // op - The ADD or SUB node to attempt an optimisation on.
2796+ // op - The ADD or SUB node to attempt an optimisation on.
2797+ // next - [out] Next node to lower if this function returns true
27852798//
2786- // Returns :
2787- // A pointer to the next node to evaluate. On nooperation, returns nullptr.
2799+ // Return Value :
2800+ // false if nochanges were made
27882801//
2789- GenTree* Lowering::TryLowerAddSubToMulLongOp (GenTreeOp* op)
2802+ bool Lowering::TryLowerAddSubToMulLongOp (GenTreeOp* op, GenTree** next )
27902803{
27912804assert (op->OperIs (GT_ADD, GT_SUB));
27922805
27932806if (!comp->opts .OptimizationEnabled ())
2794- return nullptr ;
2807+ return false ;
27952808
27962809if (!comp->compOpportunisticallyDependsOn (InstructionSet_ArmBase_Arm64))
2797- return nullptr ;
2810+ return false ;
27982811
27992812if (op->isContained ())
2800- return nullptr ;
2813+ return false ;
28012814
28022815if (!varTypeIsIntegral (op))
2803- return nullptr ;
2816+ return false ;
28042817
28052818if ((op->gtFlags & GTF_SET_FLAGS) !=0 )
2806- return nullptr ;
2819+ return false ;
28072820
28082821if (op->gtOverflow ())
2809- return nullptr ;
2822+ return false ;
28102823
28112824 GenTree* op1 = op->gtGetOp1 ();
28122825 GenTree* op2 = op->gtGetOp2 ();
@@ -2820,7 +2833,7 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
28202833// addValue - (mulValue1 * mulValue2)
28212834if (op->OperIs (GT_SUB))
28222835 {
2823- return nullptr ;
2836+ return false ;
28242837 }
28252838
28262839 mul = op1->AsOp ();
@@ -2834,20 +2847,20 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
28342847else
28352848 {
28362849// Exit if neither operation are GT_MUL_LONG.
2837- return nullptr ;
2850+ return false ;
28382851 }
28392852
28402853// Additional value must be of long size.
28412854if (!addVal->TypeIs (TYP_LONG))
2842- return nullptr ;
2855+ return false ;
28432856
28442857// Mul values must both be integers.
28452858if (!genActualTypeIsInt (mul->gtOp1 ) || !genActualTypeIsInt (mul->gtOp2 ))
2846- return nullptr ;
2859+ return false ;
28472860
28482861// The multiply must evaluate to the same thing if moved.
28492862if (!IsInvariantInRange (mul, op))
2850- return nullptr ;
2863+ return false ;
28512864
28522865// Create the new node and replace the original.
28532866 NamedIntrinsic intrinsicId =
@@ -2870,14 +2883,13 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
28702883BlockRange ().Remove (mul);
28712884BlockRange ().Remove (op);
28722885
2873- #ifdef DEBUG
28742886JITDUMP (" Converted to HW_INTRINSIC 'NI_ArmBase_Arm64_MultiplyLong[Add/Sub]'.\n " );
28752887JITDUMP (" :\n " );
28762888DISPTREERANGE (BlockRange (), outOp);
28772889JITDUMP (" \n " );
2878- #endif
28792890
2880- return outOp;
2891+ *next = outOp;
2892+ return true ;
28812893}
28822894
28832895// ----------------------------------------------------------------------------------------------
@@ -2887,44 +2899,45 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
28872899// - op1 is a MUL_LONG containing two integer operands.
28882900//
28892901// Arguments:
2890- // op - The NEG node to attempt an optimisation on.
2902+ // op - The NEG node to attempt an optimisation on.
2903+ // next - [out] Next node to lower if this function returns true
28912904//
2892- // Returns :
2893- // A pointer to the next node to evaluate. On nooperation, returns nullptr.
2905+ // Return Value :
2906+ // false if nochanges were made
28942907//
2895- GenTree* Lowering::TryLowerNegToMulLongOp (GenTreeOp* op)
2908+ bool Lowering::TryLowerNegToMulLongOp (GenTreeOp* op, GenTree** next )
28962909{
28972910assert (op->OperIs (GT_NEG));
28982911
28992912if (!comp->opts .OptimizationEnabled ())
2900- return nullptr ;
2913+ return false ;
29012914
29022915if (!comp->compOpportunisticallyDependsOn (InstructionSet_ArmBase_Arm64))
2903- return nullptr ;
2916+ return false ;
29042917
29052918if (op->isContained ())
2906- return nullptr ;
2919+ return false ;
29072920
29082921if (!varTypeIsIntegral (op))
2909- return nullptr ;
2922+ return false ;
29102923
29112924if ((op->gtFlags & GTF_SET_FLAGS) !=0 )
2912- return nullptr ;
2925+ return false ;
29132926
29142927 GenTree* op1 = op->gtGetOp1 ();
29152928
29162929// Ensure the negated operand is a MUL_LONG.
29172930if (!op1->OperIs (GT_MUL_LONG))
2918- return nullptr ;
2931+ return false ;
29192932
29202933// Ensure the MUL_LONG contains two integer parameters.
29212934 GenTreeOp* mul = op1->AsOp ();
29222935if (!genActualTypeIsInt (mul->gtOp1 ) || !genActualTypeIsInt (mul->gtOp2 ))
2923- return nullptr ;
2936+ return false ;
29242937
29252938// The multiply must evaluate to the same thing if evaluated at 'op'.
29262939if (!IsInvariantInRange (mul, op))
2927- return nullptr ;
2940+ return false ;
29282941
29292942// Able to optimise, create the new node and replace the original.
29302943 GenTreeHWIntrinsic* outOp =
@@ -2953,7 +2966,8 @@ GenTree* Lowering::TryLowerNegToMulLongOp(GenTreeOp* op)
29532966JITDUMP (" \n " );
29542967#endif
29552968
2956- return outOp;
2969+ *next = outOp;
2970+ return true ;
29572971}
29582972#endif // TARGET_ARM64
29592973