src/hotspot/share/opto/mathexactnode.cpp
changeset 48809 a81c930a8838
parent 47216 71c04702a3d5
equal deleted inserted replaced
48808:2b0b7f222800 48809:a81c930a8838
     1 /*
     1 /*
     2  * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   115 
   115 
   116 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
   116 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
   117   return SubHelper<OverflowSubLNode>::will_overflow(v1, v2);
   117   return SubHelper<OverflowSubLNode>::will_overflow(v1, v2);
   118 }
   118 }
   119 
   119 
   120 bool OverflowMulLNode::will_overflow(jlong val1, jlong val2) const {
   120 bool OverflowMulLNode::is_overflow(jlong val1, jlong val2) {
   121     jlong result = val1 * val2;
   121     // x * { 0, 1 } will never overflow. Even for x = min_jlong
   122     jlong ax = (val1 < 0 ? -val1 : val1);
   122     if (val1 == 0 || val2 == 0 || val1 == 1 || val2 == 1) {
   123     jlong ay = (val2 < 0 ? -val2 : val2);
   123       return false;
   124 
   124     }
   125     bool overflow = false;
   125 
   126     if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
   126     // x * min_jlong for x not in { 0, 1 } overflows
   127       // potential overflow if any bit in upper 32 bits are set
   127     // even -1 as -1 * min_jlong is an overflow
   128       if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
   128     if (val1 == min_jlong || val2 == min_jlong) {
   129         // -1 * Long.MIN_VALUE will overflow
   129       return true;
   130         overflow = true;
   130     }
   131       } else if (val2 != 0 && (result / val2 != val1)) {
   131 
   132         overflow = true;
   132     // if (x * y) / y == x there is no overflow
   133       }
   133     //
   134     }
   134     // the multiplication here is done as unsigned to avoid undefined behaviour which
   135 
   135     // can be used by the compiler to assume that the check further down (result / val2 != val1)
   136     return overflow;
   136     // is always false and breaks 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;
   137 }
   147 }
   138 
   148 
   139 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
   149 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
   140   return AddHelper<OverflowAddINode>::can_overflow(t1, t2);
   150   return AddHelper<OverflowAddINode>::can_overflow(t1, t2);
   141 }
   151 }