File tree Expand file tree Collapse file tree 1 file changed +23
-0
lines changed Expand file tree Collapse file tree 1 file changed +23
-0
lines changed Original file line number Diff line number Diff line change @@ -825,6 +825,29 @@ const Type* DivHFNode::Value(PhaseGVN* phase) const {
825
825
826
826
if (t1->base () == Type::HalfFloatCon &&
827
827
t2->base () == Type::HalfFloatCon) {
828
+ // IEEE 754 floating point comparison treats 0.0 and -0.0 as equals.
829
+
830
+ // Division of a zero by a zero results in NaN.
831
+ if (t1->getf () == 0 .0f && t2->getf () == 0 .0f ) {
832
+ return TypeH::make (NAN);
833
+ }
834
+
835
+ // As per C++ standard section 7.6.5 (expr.mul), behavior is undefined only if
836
+ // the second operand is 0.0. In all other situations, we can expect a standard-compliant
837
+ // C++ compiler to generate code following IEEE 754 semantics.
838
+ if (t2->getf () == 0.0 ) {
839
+ // If either operand is NaN, the result is NaN
840
+ if (g_isnan (t1->getf ())) {
841
+ return TypeH::make (NAN);
842
+ } else {
843
+ // Division of a nonzero finite value by a zero results in a signed infinity. Also,
844
+ // division of an infinity by a finite value results in a signed infinity.
845
+ bool res_sign_neg = (jint_cast (t1->getf ()) < 0 ) ^ (jint_cast (t2->getf ()) < 0 );
846
+ const TypeF* res = res_sign_neg ? TypeF::NEG_INF : TypeF::POS_INF;
847
+ return TypeH::make (res->getf ());
848
+ }
849
+ }
850
+
828
851
return TypeH::make (t1->getf () / t2->getf ());
829
852
}
830
853
You can’t perform that action at this time.
0 commit comments