6717150: improper constant folding of subnormal strictfp multiplications and divides
Summary: suppress constant folding of double divides and multiplications on ia32
Reviewed-by: never
--- a/hotspot/src/share/vm/opto/divnode.cpp Fri Oct 10 09:47:56 2008 -0700
+++ b/hotspot/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/hotspot/src/share/vm/opto/mulnode.cpp Fri Oct 10 09:47:56 2008 -0700
+++ b/hotspot/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() );
}