changeset 404:78c058bc5cdc

6717150: improper constant folding of subnormal strictfp multiplications and divides Summary: suppress constant folding of double divides and multiplications on ia32 Reviewed-by: never
author rasbold
date Tue, 14 Oct 2008 06:58:58 -0700
parents b744678d4d71
children 2649e5276dd7
files src/share/vm/opto/divnode.cpp src/share/vm/opto/mulnode.cpp
diffstat 2 files changed, 21 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/divnode.cpp	Fri Oct 10 09:47:56 2008 -0700
+++ b/src/share/vm/opto/divnode.cpp	Tue Oct 14 06:58:58 2008 -0700
@@ -710,11 +710,18 @@
   if( t2 == TypeD::ONE )
     return t1;
 
-  // If divisor is a constant and not zero, divide them numbers
-  if( t1->base() == Type::DoubleCon &&
-      t2->base() == Type::DoubleCon &&
-      t2->getd() != 0.0 ) // could be negative zero
-    return TypeD::make( t1->getd()/t2->getd() );
+#if defined(IA32)
+  if (!phase->C->method()->is_strict())
+    // Can't trust native compilers to properly fold strict double
+    // division with round-to-zero on this platform.
+#endif
+    {
+      // If divisor is a constant and not zero, divide them numbers
+      if( t1->base() == Type::DoubleCon &&
+          t2->base() == Type::DoubleCon &&
+          t2->getd() != 0.0 ) // could be negative zero
+        return TypeD::make( t1->getd()/t2->getd() );
+    }
 
   // If the dividend is a constant zero
   // Note: if t1 and t2 are zero then result is NaN (JVMS page 213)
--- a/src/share/vm/opto/mulnode.cpp	Fri Oct 10 09:47:56 2008 -0700
+++ b/src/share/vm/opto/mulnode.cpp	Tue Oct 14 06:58:58 2008 -0700
@@ -152,6 +152,14 @@
   if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
     return bottom_type();
 
+#if defined(IA32)
+  // Can't trust native compilers to properly fold strict double
+  // multiplication with round-to-zero on this platform.
+  if (op == Op_MulD && phase->C->method()->is_strict()) {
+    return TypeD::DOUBLE;
+  }
+#endif
+
   return mul_ring(t1,t2);            // Local flavor of type multiplication
 }
 
@@ -360,7 +368,7 @@
 // Compute the product type of two double ranges into this node.
 const Type *MulDNode::mul_ring(const Type *t0, const Type *t1) const {
   if( t0 == Type::DOUBLE || t1 == Type::DOUBLE ) return Type::DOUBLE;
-  // We must be adding 2 double constants.
+  // We must be multiplying 2 double constants.
   return TypeD::make( t0->getd() * t1->getd() );
 }