@@ -526,8 +526,8 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
526
526
#ifdef TARGET_ARM64
527
527
if (binOp->OperIs (GT_AND, GT_OR))
528
528
{
529
- GenTree* next = TryLowerAndOrToCCMP (binOp) ;
530
- if (next != nullptr )
529
+ GenTree* next;
530
+ if (TryLowerAndOrToCCMP (binOp, &next) )
531
531
{
532
532
return next;
533
533
}
@@ -536,8 +536,8 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
536
536
if (binOp->OperIs (GT_SUB))
537
537
{
538
538
// Attempt to optimize for umsubl/smsubl.
539
- GenTree* next = TryLowerAddSubToMulLongOp (binOp) ;
540
- if (next != nullptr )
539
+ GenTree* next;
540
+ if (TryLowerAddSubToMulLongOp (binOp, &next) )
541
541
{
542
542
return next;
543
543
}
@@ -957,25 +957,29 @@ void Lowering::LowerModPow2(GenTree* node)
957
957
//
958
958
// Arguments:
959
959
// node - the node to lower
960
+ // next - [out] Next node to lower if this function returns true
960
961
//
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)
962
966
{
963
967
assert (node->OperIs (GT_ADD));
964
968
965
969
if (!comp->opts .OptimizationEnabled ())
966
- return nullptr ;
970
+ return false ;
967
971
968
972
if (node->isContained ())
969
- return nullptr ;
973
+ return false ;
970
974
971
975
if (!varTypeIsIntegral (node))
972
- return nullptr ;
976
+ return false ;
973
977
974
978
if (node->gtFlags & GTF_SET_FLAGS)
975
- return nullptr ;
979
+ return false ;
976
980
977
981
if (node->gtOverflow ())
978
- return nullptr ;
982
+ return false ;
979
983
980
984
GenTree* op1 = node->gtGetOp1 ();
981
985
GenTree* op2 = node->gtGetOp2 ();
@@ -984,7 +988,7 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
984
988
// then we do not want to risk moving it around
985
989
// in this transformation.
986
990
if (IsContainableImmed (node, op2))
987
- return nullptr ;
991
+ return false ;
988
992
989
993
GenTree* mul = nullptr ;
990
994
GenTree* c = nullptr ;
@@ -1018,7 +1022,8 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
1018
1022
1019
1023
ContainCheckNode (node);
1020
1024
1021
- return node->gtNext ;
1025
+ *next = node->gtNext ;
1026
+ return true ;
1022
1027
}
1023
1028
// Transform "a * -b + c" to "c - a * b"
1024
1029
else 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)
1032
1037
1033
1038
ContainCheckNode (node);
1034
1039
1035
- return node->gtNext ;
1040
+ *next = node->gtNext ;
1041
+ return true ;
1036
1042
}
1037
1043
// Transform "a * b + c" to "c + a * b"
1038
1044
else if (op1->OperIs (GT_MUL))
@@ -1042,11 +1048,12 @@ GenTree* Lowering::LowerAddForPossibleContainment(GenTreeOp* node)
1042
1048
1043
1049
ContainCheckNode (node);
1044
1050
1045
- return node->gtNext ;
1051
+ *next = node->gtNext ;
1052
+ return true ;
1046
1053
}
1047
1054
}
1048
1055
1049
- return nullptr ;
1056
+ return false ;
1050
1057
}
1051
1058
#endif
1052
1059
@@ -2349,14 +2356,18 @@ void Lowering::ContainCheckCompare(GenTreeOp* cmp)
2349
2356
//
2350
2357
// Arguments:
2351
2358
// 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
2352
2363
//
2353
- GenTree* Lowering::TryLowerAndOrToCCMP (GenTreeOp* tree)
2364
+ bool Lowering::TryLowerAndOrToCCMP (GenTreeOp* tree, GenTree** next )
2354
2365
{
2355
2366
assert (tree->OperIs (GT_AND, GT_OR));
2356
2367
2357
2368
if (!comp->opts .OptimizationEnabled ())
2358
2369
{
2359
- return nullptr ;
2370
+ return false ;
2360
2371
}
2361
2372
2362
2373
GenTree* op1 = tree->gtGetOp1 ();
@@ -2395,7 +2406,7 @@ GenTree* Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree)
2395
2406
{
2396
2407
JITDUMP (" ..could not turn [%06u] or [%06u] into a def of flags, bailing\n " , Compiler::dspTreeID (op1),
2397
2408
Compiler::dspTreeID (op2));
2398
- return nullptr ;
2409
+ return false ;
2399
2410
}
2400
2411
2401
2412
BlockRange ().Remove (op2);
@@ -2437,7 +2448,8 @@ GenTree* Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree)
2437
2448
DISPTREERANGE (BlockRange (), tree);
2438
2449
JITDUMP (" \n " );
2439
2450
2440
- return tree->gtNext ;
2451
+ *next = tree->gtNext ;
2452
+ return true ;
2441
2453
}
2442
2454
2443
2455
// ------------------------------------------------------------------------
@@ -2781,32 +2793,33 @@ void Lowering::TryLowerCnsIntCselToCinc(GenTreeOp* select, GenTree* cond)
2781
2793
// - One op is a MUL_LONG containing two integer operands, and the other is a long.
2782
2794
//
2783
2795
// 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
2785
2798
//
2786
- // Returns :
2787
- // A pointer to the next node to evaluate. On no operation, returns nullptr.
2799
+ // Return Value :
2800
+ // false if no changes were made
2788
2801
//
2789
- GenTree* Lowering::TryLowerAddSubToMulLongOp (GenTreeOp* op)
2802
+ bool Lowering::TryLowerAddSubToMulLongOp (GenTreeOp* op, GenTree** next )
2790
2803
{
2791
2804
assert (op->OperIs (GT_ADD, GT_SUB));
2792
2805
2793
2806
if (!comp->opts .OptimizationEnabled ())
2794
- return nullptr ;
2807
+ return false ;
2795
2808
2796
2809
if (!comp->compOpportunisticallyDependsOn (InstructionSet_ArmBase_Arm64))
2797
- return nullptr ;
2810
+ return false ;
2798
2811
2799
2812
if (op->isContained ())
2800
- return nullptr ;
2813
+ return false ;
2801
2814
2802
2815
if (!varTypeIsIntegral (op))
2803
- return nullptr ;
2816
+ return false ;
2804
2817
2805
2818
if ((op->gtFlags & GTF_SET_FLAGS) != 0 )
2806
- return nullptr ;
2819
+ return false ;
2807
2820
2808
2821
if (op->gtOverflow ())
2809
- return nullptr ;
2822
+ return false ;
2810
2823
2811
2824
GenTree* op1 = op->gtGetOp1 ();
2812
2825
GenTree* op2 = op->gtGetOp2 ();
@@ -2820,7 +2833,7 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
2820
2833
// addValue - (mulValue1 * mulValue2)
2821
2834
if (op->OperIs (GT_SUB))
2822
2835
{
2823
- return nullptr ;
2836
+ return false ;
2824
2837
}
2825
2838
2826
2839
mul = op1->AsOp ();
@@ -2834,20 +2847,20 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
2834
2847
else
2835
2848
{
2836
2849
// Exit if neither operation are GT_MUL_LONG.
2837
- return nullptr ;
2850
+ return false ;
2838
2851
}
2839
2852
2840
2853
// Additional value must be of long size.
2841
2854
if (!addVal->TypeIs (TYP_LONG))
2842
- return nullptr ;
2855
+ return false ;
2843
2856
2844
2857
// Mul values must both be integers.
2845
2858
if (!genActualTypeIsInt (mul->gtOp1 ) || !genActualTypeIsInt (mul->gtOp2 ))
2846
- return nullptr ;
2859
+ return false ;
2847
2860
2848
2861
// The multiply must evaluate to the same thing if moved.
2849
2862
if (!IsInvariantInRange (mul, op))
2850
- return nullptr ;
2863
+ return false ;
2851
2864
2852
2865
// Create the new node and replace the original.
2853
2866
NamedIntrinsic intrinsicId =
@@ -2870,14 +2883,13 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
2870
2883
BlockRange ().Remove (mul);
2871
2884
BlockRange ().Remove (op);
2872
2885
2873
- #ifdef DEBUG
2874
2886
JITDUMP (" Converted to HW_INTRINSIC 'NI_ArmBase_Arm64_MultiplyLong[Add/Sub]'.\n " );
2875
2887
JITDUMP (" :\n " );
2876
2888
DISPTREERANGE (BlockRange (), outOp);
2877
2889
JITDUMP (" \n " );
2878
- #endif
2879
2890
2880
- return outOp;
2891
+ *next = outOp;
2892
+ return true ;
2881
2893
}
2882
2894
2883
2895
// ----------------------------------------------------------------------------------------------
@@ -2887,44 +2899,45 @@ GenTree* Lowering::TryLowerAddSubToMulLongOp(GenTreeOp* op)
2887
2899
// - op1 is a MUL_LONG containing two integer operands.
2888
2900
//
2889
2901
// 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
2891
2904
//
2892
- // Returns :
2893
- // A pointer to the next node to evaluate. On no operation, returns nullptr.
2905
+ // Return Value :
2906
+ // false if no changes were made
2894
2907
//
2895
- GenTree* Lowering::TryLowerNegToMulLongOp (GenTreeOp* op)
2908
+ bool Lowering::TryLowerNegToMulLongOp (GenTreeOp* op, GenTree** next )
2896
2909
{
2897
2910
assert (op->OperIs (GT_NEG));
2898
2911
2899
2912
if (!comp->opts .OptimizationEnabled ())
2900
- return nullptr ;
2913
+ return false ;
2901
2914
2902
2915
if (!comp->compOpportunisticallyDependsOn (InstructionSet_ArmBase_Arm64))
2903
- return nullptr ;
2916
+ return false ;
2904
2917
2905
2918
if (op->isContained ())
2906
- return nullptr ;
2919
+ return false ;
2907
2920
2908
2921
if (!varTypeIsIntegral (op))
2909
- return nullptr ;
2922
+ return false ;
2910
2923
2911
2924
if ((op->gtFlags & GTF_SET_FLAGS) != 0 )
2912
- return nullptr ;
2925
+ return false ;
2913
2926
2914
2927
GenTree* op1 = op->gtGetOp1 ();
2915
2928
2916
2929
// Ensure the negated operand is a MUL_LONG.
2917
2930
if (!op1->OperIs (GT_MUL_LONG))
2918
- return nullptr ;
2931
+ return false ;
2919
2932
2920
2933
// Ensure the MUL_LONG contains two integer parameters.
2921
2934
GenTreeOp* mul = op1->AsOp ();
2922
2935
if (!genActualTypeIsInt (mul->gtOp1 ) || !genActualTypeIsInt (mul->gtOp2 ))
2923
- return nullptr ;
2936
+ return false ;
2924
2937
2925
2938
// The multiply must evaluate to the same thing if evaluated at 'op'.
2926
2939
if (!IsInvariantInRange (mul, op))
2927
- return nullptr ;
2940
+ return false ;
2928
2941
2929
2942
// Able to optimise, create the new node and replace the original.
2930
2943
GenTreeHWIntrinsic* outOp =
@@ -2953,7 +2966,8 @@ GenTree* Lowering::TryLowerNegToMulLongOp(GenTreeOp* op)
2953
2966
JITDUMP (" \n " );
2954
2967
#endif
2955
2968
2956
- return outOp;
2969
+ *next = outOp;
2970
+ return true ;
2957
2971
}
2958
2972
#endif // TARGET_ARM64
2959
2973
0 commit comments