1 /*
2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
100 bool OverflowSubINode::will_overflow(jint v1, jint v2) const {
101 return SubHelper<OverflowSubINode>::will_overflow(v1, v2);
102 }
103
104 bool OverflowMulINode::will_overflow(jint v1, jint v2) const {
105 jlong result = (jlong) v1 * (jlong) v2;
106 if ((jint) result == result) {
107 return false;
108 }
109 return true;
110 }
111
112 bool OverflowAddLNode::will_overflow(jlong v1, jlong v2) const {
113 return AddHelper<OverflowAddLNode>::will_overflow(v1, v2);
114 }
115
116 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
117 return SubHelper<OverflowSubLNode>::will_overflow(v1, v2);
118 }
119
120 bool OverflowMulLNode::will_overflow(jlong val1, jlong val2) const {
121 jlong result = val1 * val2;
122 jlong ax = (val1 < 0 ? -val1 : val1);
123 jlong ay = (val2 < 0 ? -val2 : val2);
124
125 bool overflow = false;
126 if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
127 // potential overflow if any bit in upper 32 bits are set
128 if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
129 // -1 * Long.MIN_VALUE will overflow
130 overflow = true;
131 } else if (val2 != 0 && (result / val2 != val1)) {
132 overflow = true;
133 }
134 }
135
136 return overflow;
137 }
138
139 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
140 return AddHelper<OverflowAddINode>::can_overflow(t1, t2);
141 }
142
143 bool OverflowSubINode::can_overflow(const Type* t1, const Type* t2) const {
144 if (in(1) == in(2)) {
145 return false;
146 }
147 return SubHelper<OverflowSubINode>::can_overflow(t1, t2);
148 }
149
150 bool OverflowMulINode::can_overflow(const Type* t1, const Type* t2) const {
151 return MulHelper<OverflowMulINode>::can_overflow(t1, t2);
152 }
153
154 bool OverflowAddLNode::can_overflow(const Type* t1, const Type* t2) const {
155 return AddHelper<OverflowAddLNode>::can_overflow(t1, t2);
156 }
|
1 /*
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
100 bool OverflowSubINode::will_overflow(jint v1, jint v2) const {
101 return SubHelper<OverflowSubINode>::will_overflow(v1, v2);
102 }
103
104 bool OverflowMulINode::will_overflow(jint v1, jint v2) const {
105 jlong result = (jlong) v1 * (jlong) v2;
106 if ((jint) result == result) {
107 return false;
108 }
109 return true;
110 }
111
112 bool OverflowAddLNode::will_overflow(jlong v1, jlong v2) const {
113 return AddHelper<OverflowAddLNode>::will_overflow(v1, v2);
114 }
115
116 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
117 return SubHelper<OverflowSubLNode>::will_overflow(v1, v2);
118 }
119
120 bool OverflowMulLNode::is_overflow(jlong val1, jlong val2) {
121 // x * { 0, 1 } will never overflow. Even for x = min_jlong
122 if (val1 == 0 || val2 == 0 || val1 == 1 || val2 == 1) {
123 return false;
124 }
125
126 // x * min_jlong for x not in { 0, 1 } overflows
127 // even -1 as -1 * min_jlong is an overflow
128 if (val1 == min_jlong || val2 == min_jlong) {
129 return true;
130 }
131
132 // if (x * y) / y == x there is no overflow
133 //
134 // the multiplication here is done as unsigned to avoid undefined behaviour which
135 // can be used by the compiler to assume that the check further down (result / val2 != val1)
136 // is always false and break the overflow check
137 julong v1 = (julong) val1;
138 julong v2 = (julong) val2;
139 julong tmp = v1 * v2;
140 jlong result = (jlong) tmp;
141
142 if (result / val2 != val1) {
143 return true;
144 }
145
146 return false;
147 }
148
149 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
150 return AddHelper<OverflowAddINode>::can_overflow(t1, t2);
151 }
152
153 bool OverflowSubINode::can_overflow(const Type* t1, const Type* t2) const {
154 if (in(1) == in(2)) {
155 return false;
156 }
157 return SubHelper<OverflowSubINode>::can_overflow(t1, t2);
158 }
159
160 bool OverflowMulINode::can_overflow(const Type* t1, const Type* t2) const {
161 return MulHelper<OverflowMulINode>::can_overflow(t1, t2);
162 }
163
164 bool OverflowAddLNode::can_overflow(const Type* t1, const Type* t2) const {
165 return AddHelper<OverflowAddLNode>::can_overflow(t1, t2);
166 }
|