1 /*
   2  * Copyright (c) 2013, 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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/cfgnode.hpp"
  29 #include "opto/machnode.hpp"
  30 #include "opto/matcher.hpp"
  31 #include "opto/mathexactnode.hpp"
  32 #include "opto/subnode.hpp"
  33 
  34 OverflowNode::OverflowNode(Node* in1) : CmpNode(in1, in1) {
  35 }
  36 
  37 OverflowNode::OverflowNode(Node* in1, Node* in2) : CmpNode(in1, in2) {
  38 }
  39 
  40 bool OverflowINode::will_overflow(jint v1, jint v2) const {
  41   ShouldNotReachHere();
  42   return true;
  43 }
  44 
  45 bool OverflowLNode::will_overflow(jlong v1, jlong v2) const {
  46   ShouldNotReachHere();
  47   return true;
  48 }
  49 
  50 bool OverflowINode::can_overflow(const Type* t1, const Type* t2) const {
  51   ShouldNotReachHere();
  52   return true;
  53 }
  54 
  55 bool OverflowLNode::can_overflow(const Type* t1, const Type* t2) const {
  56   ShouldNotReachHere();
  57   return true;
  58 }
  59 
  60 bool OverflowAddINode::will_overflow(jint v1, jint v2) const {
  61     jint result = v1 + v2;
  62     // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
  63     if ( (((v1 ^ result) & (v2 ^ result)) >= 0)) {
  64       return false;
  65     }
  66     return true;
  67 }
  68 
  69 bool OverflowSubINode::will_overflow(jint v1, jint v2) const {
  70     jint result = v1 - v2;
  71     // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
  72     // the sign of the result is different than the sign of arg1
  73     if (((v1 ^ v2) & (v1 ^ result)) >= 0) {
  74       return false;
  75     }
  76     return true;
  77 }
  78 
  79 bool OverflowMulINode::will_overflow(jint v1, jint v2) const {
  80     jlong result = (jlong) v1 * (jlong) v2;
  81     if ((jint) result == result) {
  82       return false;
  83     }
  84     return true;
  85 }
  86 
  87 bool OverflowAddLNode::will_overflow(jlong v1, jlong v2) const {
  88     jlong result = v1 + v2;
  89     // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
  90     if ( (((v1 ^ result) & (v2 ^ result)) >= 0)) {
  91       return false;
  92     }
  93     return true;
  94 }
  95 
  96 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
  97     jlong result = v1 - v2;
  98     // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
  99     // the sign of the result is different than the sign of arg1
 100     if (((v1 ^ v2) & (v1 ^ result)) >= 0) {
 101       return false;
 102     }
 103     return true;
 104 }
 105 
 106 bool OverflowMulLNode::will_overflow(jlong val1, jlong val2) const {
 107     jlong result = val1 * val2;
 108     jlong ax = (val1 < 0 ? -val1 : val1);
 109     jlong ay = (val2 < 0 ? -val2 : val2);
 110 
 111     bool overflow = false;
 112     if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
 113       // potential overflow if any bit in upper 32 bits are set
 114       if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
 115         // -1 * Long.MIN_VALUE will overflow
 116         overflow = true;
 117       } else if (val2 != 0 && (result / val2 != val1)) {
 118         overflow = true;
 119       }
 120     }
 121 
 122     return overflow;
 123 }
 124 
 125 Node* OverflowINode::Ideal(PhaseGVN* phase, bool can_reshape) {
 126   Node* arg1 = in(1);
 127   Node* arg2 = in(2);
 128 
 129   const Type* type1 = phase->type(arg1);
 130   const Type* type2 = phase->type(arg2);
 131 
 132   if (type1 != Type::TOP && type1->singleton() &&
 133       type2 != Type::TOP && type2->singleton()) {
 134     jint val1 = arg1->get_int();
 135     jint val2 = arg2->get_int();
 136     if (will_overflow(val1, val2) == false) {
 137       Node* con_result = ConINode::make(phase->C, 0);
 138       return con_result;
 139     }
 140     return NULL;
 141   }
 142   return NULL;
 143 }
 144 
 145 Node* OverflowLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
 146   Node* arg1 = in(1);
 147   Node* arg2 = in(2);
 148 
 149   const Type* type1 = phase->type(arg1);
 150   const Type* type2 = phase->type(arg2);
 151 
 152   if (type1 != Type::TOP && type1->singleton() &&
 153       type2 != Type::TOP && type2->singleton()) {
 154     jlong val1 = arg1->get_long();
 155     jlong val2 = arg2->get_long();
 156     if (will_overflow(val1, val2) == false) {
 157       Node* con_result = ConINode::make(phase->C, 0);
 158       return con_result;
 159     }
 160     return NULL;
 161   }
 162 
 163   return NULL;
 164 }
 165 
 166 const Type* OverflowINode::Value(PhaseTransform* phase) const {
 167   const Type *t1 = phase->type( in(1) );
 168   const Type *t2 = phase->type( in(2) );
 169   if( t1 == Type::TOP ) return Type::TOP;
 170   if( t2 == Type::TOP ) return Type::TOP;
 171 
 172   const TypeInt *i1 = t1->isa_int();
 173   const TypeInt *i2 = t2->isa_int();
 174 
 175   if (t1->singleton() && t2->singleton()) {
 176     if (i1 == NULL || i2 == NULL) {
 177       return TypeInt::CC;
 178     }
 179 
 180     jint val1 = i1->get_con();
 181     jint val2 = i2->get_con();
 182     if (will_overflow(val1, val2)) {
 183       return TypeInt::CC;
 184     }
 185     return TypeInt::ZERO;
 186   } else if (i1 != TypeInt::INT && i2 != TypeInt::INT) {
 187     if (will_overflow(i1->_lo, i2->_lo)) {
 188       return TypeInt::CC;
 189     } else if (will_overflow(i1->_lo, i2->_hi)) {
 190       return TypeInt::CC;
 191     } else if (will_overflow(i1->_hi, i2->_lo)) {
 192       return TypeInt::CC;
 193     } else if (will_overflow(i1->_hi, i2->_hi)) {
 194       return TypeInt::CC;
 195     }
 196     return TypeInt::ZERO;
 197   }
 198 
 199   if (!can_overflow(t1, t2)) {
 200     return TypeInt::ZERO;
 201   }
 202   return TypeInt::CC;
 203 }
 204 
 205 const Type* OverflowLNode::Value(PhaseTransform* phase) const {
 206   const Type *t1 = phase->type( in(1) );
 207   const Type *t2 = phase->type( in(2) );
 208   if( t1 == Type::TOP ) return Type::TOP;
 209   if( t2 == Type::TOP ) return Type::TOP;
 210 
 211   const TypeLong *i1 = t1->isa_long();
 212   const TypeLong *i2 = t2->isa_long();
 213 
 214   if (t1->singleton() && t2->singleton()) {
 215     if (i1 == NULL || i2 == NULL) {
 216       return TypeInt::CC;
 217     }
 218 
 219     jlong val1 = i1->get_con();
 220     jlong val2 = i2->get_con();
 221     if (will_overflow(val1, val2)) {
 222       return TypeInt::CC;
 223     }
 224     return TypeInt::ZERO;
 225   } else if (i1 != TypeLong::LONG && i2 != TypeLong::LONG) {
 226     if (will_overflow(i1->_lo, i2->_lo)) {
 227       return TypeInt::CC;
 228     } else if (will_overflow(i1->_lo, i2->_hi)) {
 229       return TypeInt::CC;
 230     } else if (will_overflow(i1->_hi, i2->_lo)) {
 231       return TypeInt::CC;
 232     } else if (will_overflow(i1->_hi, i2->_hi)) {
 233       return TypeInt::CC;
 234     }
 235     return TypeInt::ZERO;
 236   }
 237   if (!can_overflow(t1, t2)) {
 238     return TypeInt::ZERO;
 239   }
 240   return TypeInt::CC;
 241 }
 242 
 243 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
 244   if (t1 == TypeInt::ZERO || t2 == TypeInt::ZERO) {
 245     return false;
 246   }
 247   return true;
 248 }
 249 
 250 bool OverflowSubINode::can_overflow(const Type* t1, const Type* t2) const {
 251   if (in(1) == in(2)) {
 252     return false;
 253   }
 254 
 255   if (t2 == TypeInt::ZERO) {
 256     return false;
 257   }
 258   return true;
 259 }
 260 
 261 bool OverflowMulINode::can_overflow(const Type* t1, const Type* t2) const {
 262   if (t1 == TypeInt::ZERO || t2 == TypeInt::ZERO) {
 263     return false;
 264   } else if (t1 == TypeInt::ONE || t2 == TypeInt::ONE) {
 265     return false;
 266   }
 267   return true;
 268 }
 269 
 270 bool OverflowAddLNode::can_overflow(const Type* t1, const Type* t2) const {
 271   if (t1 == TypeLong::ZERO || t2 == TypeLong::ZERO) {
 272     return false;
 273   }
 274   return true;
 275 }
 276 
 277 bool OverflowSubLNode::can_overflow(const Type* t1, const Type* t2) const {
 278   if (in(1) == in(2)) {
 279     return false;
 280   }
 281 
 282   if (t2 == TypeLong::ZERO) {
 283     return false;
 284   }
 285   return true;
 286 }
 287 
 288 bool OverflowMulLNode::can_overflow(const Type* t1, const Type* t2) const {
 289   if (t1 == TypeLong::ZERO || t2 == TypeLong::ZERO) {
 290     return false;
 291   } else if (t1 == TypeLong::ONE || t2 == TypeLong::ONE) {
 292     return false;
 293   }
 294   return true;
 295 }
 296 
 297 const Type* OverflowINode::sub(const Type* t1, const Type* t2) const {
 298   ShouldNotReachHere();
 299   return TypeInt::CC;
 300 }
 301 
 302 const Type* OverflowLNode::sub(const Type* t1, const Type* t2) const {
 303   ShouldNotReachHere();
 304   return TypeInt::CC;
 305 }