8226627: assert(t->singleton()) failed: must be a constant
Summary: Implemented constant folding for MaxFD, MinFD.
Reviewed-by: thartmann, bsrbnd, pli
--- a/src/hotspot/share/opto/addnode.cpp Mon Jun 10 13:04:12 2019 +0200
+++ b/src/hotspot/share/opto/addnode.cpp Fri Jul 05 00:24:54 2019 -0700
@@ -929,3 +929,91 @@
// Otherwise just MIN them bits.
return TypeInt::make( MIN2(r0->_lo,r1->_lo), MIN2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) );
}
+
+//------------------------------add_ring---------------------------------------
+const Type *MinFNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeF *r0 = t0->is_float_constant();
+ const TypeF *r1 = t1->is_float_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ float f0 = r0->getf();
+ float f1 = r1->getf();
+ if (f0 != 0.0f || f1 != 0.0f) {
+ return f0 < f1 ? r0 : r1;
+ }
+
+ // handle min of 0.0, -0.0 case.
+ return (jint_cast(f0) < jint_cast(f1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MinDNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeD *r0 = t0->is_double_constant();
+ const TypeD *r1 = t1->is_double_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ double d0 = r0->getd();
+ double d1 = r1->getd();
+ if (d0 != 0.0 || d1 != 0.0) {
+ return d0 < d1 ? r0 : r1;
+ }
+
+ // handle min of 0.0, -0.0 case.
+ return (jlong_cast(d0) < jlong_cast(d1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MaxFNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeF *r0 = t0->is_float_constant();
+ const TypeF *r1 = t1->is_float_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ float f0 = r0->getf();
+ float f1 = r1->getf();
+ if (f0 != 0.0f || f1 != 0.0f) {
+ return f0 > f1 ? r0 : r1;
+ }
+
+ // handle max of 0.0,-0.0 case.
+ return (jint_cast(f0) > jint_cast(f1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MaxDNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeD *r0 = t0->is_double_constant();
+ const TypeD *r1 = t1->is_double_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ double d0 = r0->getd();
+ double d1 = r1->getd();
+ if (d0 != 0.0 || d1 != 0.0) {
+ return d0 > d1 ? r0 : r1;
+ }
+
+ // handle max of 0.0, -0.0 case.
+ return (jlong_cast(d0) > jlong_cast(d1)) ? r0 : r1;
+}
--- a/src/hotspot/share/opto/addnode.hpp Mon Jun 10 13:04:12 2019 +0200
+++ b/src/hotspot/share/opto/addnode.hpp Fri Jul 05 00:24:54 2019 -0700
@@ -255,7 +255,7 @@
public:
MaxFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::FLOAT; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeF::NEG_INF; }
virtual const Type *bottom_type() const { return Type::FLOAT; }
virtual uint ideal_reg() const { return Op_RegF; }
@@ -267,7 +267,7 @@
public:
MinFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::FLOAT; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeF::POS_INF; }
virtual const Type *bottom_type() const { return Type::FLOAT; }
virtual uint ideal_reg() const { return Op_RegF; }
@@ -279,7 +279,7 @@
public:
MaxDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::DOUBLE; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeD::NEG_INF; }
virtual const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -291,7 +291,7 @@
public:
MinDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::DOUBLE; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeD::POS_INF; }
virtual const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
--- a/src/hotspot/share/opto/library_call.cpp Mon Jun 10 13:04:12 2019 +0200
+++ b/src/hotspot/share/opto/library_call.cpp Fri Jul 05 00:24:54 2019 -0700
@@ -6696,9 +6696,6 @@
fatal_unexpected_iid(id);
break;
}
- if (a->is_Con() || b->is_Con()) {
- return false;
- }
switch (id) {
case vmIntrinsics::_maxF: n = new MaxFNode(a, b); break;
case vmIntrinsics::_minF: n = new MinFNode(a, b); break;
--- a/src/hotspot/share/opto/type.cpp Mon Jun 10 13:04:12 2019 +0200
+++ b/src/hotspot/share/opto/type.cpp Fri Jul 05 00:24:54 2019 -0700
@@ -411,18 +411,8 @@
}
#define SMALLINT ((juint)3) // a value too insignificant to consider widening
-
-static double pos_dinf() {
- union { int64_t i; double d; } v;
- v.i = CONST64(0x7ff0000000000000);
- return v.d;
-}
-
-static float pos_finf() {
- union { int32_t i; float f; } v;
- v.i = 0x7f800000;
- return v.f;
-}
+#define POSITIVE_INFINITE_F 0x7f800000 // hex representation for IEEE 754 single precision positive infinite
+#define POSITIVE_INFINITE_D 0x7ff0000000000000 // hex representation for IEEE 754 double precision positive infinite
//--------------------------Initialize_shared----------------------------------
void Type::Initialize_shared(Compile* current) {
@@ -453,13 +443,13 @@
TypeF::ZERO = TypeF::make(0.0); // Float 0 (positive zero)
TypeF::ONE = TypeF::make(1.0); // Float 1
- TypeF::POS_INF = TypeF::make(pos_finf());
- TypeF::NEG_INF = TypeF::make(-pos_finf());
+ TypeF::POS_INF = TypeF::make(jfloat_cast(POSITIVE_INFINITE_F));
+ TypeF::NEG_INF = TypeF::make(-jfloat_cast(POSITIVE_INFINITE_F));
TypeD::ZERO = TypeD::make(0.0); // Double 0 (positive zero)
TypeD::ONE = TypeD::make(1.0); // Double 1
- TypeD::POS_INF = TypeD::make(pos_dinf());
- TypeD::NEG_INF = TypeD::make(-pos_dinf());
+ TypeD::POS_INF = TypeD::make(jdouble_cast(POSITIVE_INFINITE_D));
+ TypeD::NEG_INF = TypeD::make(-jdouble_cast(POSITIVE_INFINITE_D));
TypeInt::MINUS_1 = TypeInt::make(-1); // -1
TypeInt::ZERO = TypeInt::make( 0); // 0