@@ -1004,6 +1004,14 @@ const Type *MaxINode::add_ring( const Type *t0, const Type *t1 ) const {
1004
1004
return TypeInt::make ( MAX2 (r0->_lo ,r1->_lo ), MAX2 (r0->_hi ,r1->_hi ), MAX2 (r0->_widen ,r1->_widen ) );
1005
1005
}
1006
1006
1007
+ // Check if addition of an integer with type 't' and a constant 'c' can overflow
1008
+ static bool can_overflow (const TypeInt* t, jint c) {
1009
+ jint t_lo = t->_lo ;
1010
+ jint t_hi = t->_hi ;
1011
+ return ((c < 0 && (java_add (t_lo, c) > t_lo)) ||
1012
+ (c > 0 && (java_add (t_hi, c) < t_hi)));
1013
+ }
1014
+
1007
1015
// =============================================================================
1008
1016
// ------------------------------Idealize---------------------------------------
1009
1017
// MINs show up in range-check loop limit calculations. Look for
@@ -1026,7 +1034,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1026
1034
1027
1035
// Get left input & constant
1028
1036
Node *x = l;
1029
- int x_off = 0 ;
1037
+ jint x_off = 0 ;
1030
1038
if ( x->Opcode () == Op_AddI && // Check for "x+c0" and collect constant
1031
1039
x->in (2 )->is_Con () ) {
1032
1040
const Type *t = x->in (2 )->bottom_type ();
@@ -1037,7 +1045,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1037
1045
1038
1046
// Scan a right-spline-tree for MINs
1039
1047
Node *y = r;
1040
- int y_off = 0 ;
1048
+ jint y_off = 0 ;
1041
1049
// Check final part of MIN tree
1042
1050
if ( y->Opcode () == Op_AddI && // Check for "y+c1" and collect constant
1043
1051
y->in (2 )->is_Con () ) {
@@ -1051,6 +1059,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1051
1059
return this ;
1052
1060
}
1053
1061
1062
+ const TypeInt* tx = phase->type (x)->isa_int ();
1054
1063
1055
1064
if ( r->Opcode () == Op_MinI ) {
1056
1065
assert ( r != r->in (2 ), " dead loop in MinINode::Ideal" );
@@ -1067,18 +1076,23 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1067
1076
if ( x->_idx > y->_idx )
1068
1077
return new MinINode (r->in (1 ),phase->transform (new MinINode (l,r->in (2 ))));
1069
1078
1070
- // See if covers: MIN2(x+c0,MIN2(y+c1,z))
1071
- if ( !phase->eqv (x,y) ) return NULL ;
1072
- // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
1073
- // MIN2(x+c0 or x+c1 which less, z).
1074
- return new MinINode (phase->transform (new AddINode (x,phase->intcon (MIN2 (x_off,y_off)))),r->in (2 ));
1079
+ // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z)
1080
+ // if x == y and the additions can't overflow.
1081
+ if (phase->eqv (x,y) &&
1082
+ !can_overflow (tx, x_off) &&
1083
+ !can_overflow (tx, y_off)) {
1084
+ return new MinINode (phase->transform (new AddINode (x, phase->intcon (MIN2 (x_off, y_off)))), r->in (2 ));
1085
+ }
1075
1086
} else {
1076
- // See if covers: MIN2(x+c0,y+c1)
1077
- if ( !phase->eqv (x,y) ) return NULL ;
1078
- // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
1079
- return new AddINode (x,phase->intcon (MIN2 (x_off,y_off)));
1087
+ // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1)
1088
+ // if x == y and the additions can't overflow.
1089
+ if (phase->eqv (x,y) &&
1090
+ !can_overflow (tx, x_off) &&
1091
+ !can_overflow (tx, y_off)) {
1092
+ return new AddINode (x,phase->intcon (MIN2 (x_off,y_off)));
1093
+ }
1080
1094
}
1081
-
1095
+ return NULL ;
1082
1096
}
1083
1097
1084
1098
// ------------------------------add_ring---------------------------------------
0 commit comments