@@ -2735,10 +2735,30 @@ bool SWPointer::scaled_iv_plus_offset(Node* n) {
27352735 }
27362736 } else if (opc == Op_SubI) {
27372737 if (scaled_iv (n->in (1 )) && offset_plus_k (n->in (2 ), true )) {
2738+ // (scale * iv) - (offset1 + invar1)
2739+ // Subtraction handled via "negate" flag of "offset_plus_k".
27382740 return true ;
27392741 }
2740- if (scaled_iv (n->in (2 )) && offset_plus_k (n->in (1 ))) {
2741- _scale *= -1 ;
2742+ SWPointer tmp (this );
2743+ if (tmp.scaled_iv (n->in (2 )) && offset_plus_k (n->in (1 ))) {
2744+ // (offset1 + invar1) - (scale * iv)
2745+ // Subtraction handled explicitly below.
2746+ assert (_scale == 0 , " shouldn't be set yet" );
2747+ // _scale = -tmp._scale
2748+ if (!try_MulI_no_overflow (-1 , tmp._scale , _scale)) {
2749+ return false ; // mul overflow.
2750+ }
2751+ // _offset -= tmp._offset
2752+ if (!try_SubI_no_overflow (_offset, tmp._offset , _offset)) {
2753+ return false ; // sub overflow.
2754+ }
2755+
2756+ // SWPointer tmp does not have an integer part to be forwarded
2757+ // (tmp._has_int_index_after_convI2L is false) because n is a SubI, all
2758+ // nodes above must also be of integer type (ConvL2I is not handled
2759+ // to allow a long) and ConvI2L (the only node that can add an integer
2760+ // part) won't be present.
2761+
27422762 return true ;
27432763 }
27442764 }
@@ -2766,7 +2786,9 @@ bool SWPointer::scaled_iv(Node* n) {
27662786 }
27672787 } else if (opc == Op_LShiftI) {
27682788 if (n->in (1 ) == iv () && n->in (2 )->is_Con ()) {
2769- _scale = 1 << n->in (2 )->get_int ();
2789+ if (!try_LShiftI_no_overflow (1 , n->in (2 )->get_int (), _scale)) {
2790+ return false ; // shift overflow.
2791+ }
27702792 return true ;
27712793 }
27722794 } else if (opc == Op_ConvI2L && !has_iv ()) {
@@ -2792,15 +2814,28 @@ bool SWPointer::scaled_iv(Node* n) {
27922814 if (tmp.scaled_iv_plus_offset (n->in (1 )) && tmp.has_iv ()) {
27932815 // We successfully matched an integer index, of the form:
27942816 // int_index = int_offset + int_invar + int_scale * iv
2817+ // Forward scale.
2818+ assert (_scale == 0 && tmp._scale != 0 , " iv only found just now" );
2819+ _scale = tmp._scale ;
2820+ // Accumulate offset.
2821+ if (!try_AddI_no_overflow (_offset, tmp._offset , _offset)) {
2822+ return false ; // add overflow.
2823+ }
2824+ // Forward invariant if not already found.
2825+ if (tmp._invar != NULL ) {
2826+ if (_invar != NULL ) {
2827+ return false ;
2828+ }
2829+ _invar = tmp._invar ;
2830+ _negate_invar = tmp._negate_invar ;
2831+ }
2832+ // Set info about the int_index:
2833+ assert (!_has_int_index_after_convI2L, " no previous int_index discovered" );
27952834 _has_int_index_after_convI2L = true ;
27962835 _int_index_after_convI2L_offset = tmp._offset ;
27972836 _int_index_after_convI2L_invar = tmp._invar ;
27982837 _int_index_after_convI2L_scale = tmp._scale ;
2799- }
28002838
2801- // Now parse it again for the real SWPointer. This makes sure that the int_offset, int_invar,
2802- // and int_scale are properly added to the final SWPointer's offset, invar, and scale.
2803- if (scaled_iv_plus_offset (n->in (1 ))) {
28042839 return true ;
28052840 }
28062841 } else if (opc == Op_LShiftL) {
@@ -2811,20 +2846,22 @@ bool SWPointer::scaled_iv(Node* n) {
28112846 SWPointer tmp (this );
28122847 if (tmp.scaled_iv_plus_offset (n->in (1 ))) {
28132848 if (tmp._invar == NULL ) {
2814- int scale = (int )(n->in (2 )->get_int ());
2815- int mult = 1 << scale;
2849+ int shift = (int )(n->in (2 )->get_int ());
28162850 // Accumulate scale.
2817- _scale = tmp._scale * ((jint)mult);
2851+ if (!try_LShiftI_no_overflow (tmp._scale , shift, _scale)) {
2852+ return false ; // shift overflow.
2853+ }
28182854 // Accumulate offset.
28192855 jint shifted_offset = 0 ;
2820- if (!try_LShiftI_no_overflow (tmp._offset , scale , shifted_offset)) {
2856+ if (!try_LShiftI_no_overflow (tmp._offset , shift , shifted_offset)) {
28212857 return false ; // shift overflow.
28222858 }
28232859 if (!try_AddI_no_overflow (_offset, shifted_offset, _offset)) {
28242860 return false ; // add overflow.
28252861 }
28262862
28272863 // Forward info about the int_index:
2864+ assert (!_has_int_index_after_convI2L, " no previous int_index discovered" );
28282865 _has_int_index_after_convI2L = tmp._has_int_index_after_convI2L ;
28292866 _int_index_after_convI2L_offset = tmp._int_index_after_convI2L_offset ;
28302867 _int_index_after_convI2L_invar = tmp._int_index_after_convI2L_invar ;
@@ -2933,6 +2970,9 @@ bool SWPointer::try_AddSubI_no_overflow(jint offset1, jint offset2, bool is_sub,
29332970}
29342971
29352972bool SWPointer::try_LShiftI_no_overflow (jint offset, int shift, jint& result) {
2973+ if (shift < 0 || shift > 31 ) {
2974+ return false ;
2975+ }
29362976 jlong long_offset = java_shift_left ((jlong)(offset), (julong)((jlong)(shift)));
29372977 jint int_offset = java_shift_left ( offset, (juint)((jint)(shift)));
29382978 if (long_offset != int_offset) {
@@ -2942,6 +2982,16 @@ bool SWPointer::try_LShiftI_no_overflow(jint offset, int shift, jint& result) {
29422982 return true ;
29432983}
29442984
2985+ bool SWPointer::try_MulI_no_overflow (jint offset1, jint offset2, jint& result) {
2986+ jlong long_offset = java_multiply ((jlong)(offset1), (jlong)(offset2));
2987+ jint int_offset = java_multiply ( offset1, offset2);
2988+ if (long_offset != int_offset) {
2989+ return false ;
2990+ }
2991+ result = int_offset;
2992+ return true ;
2993+ }
2994+
29452995// ----------------------------print------------------------
29462996void SWPointer::print () {
29472997#ifndef PRODUCT
0 commit comments