Skip to content

Commit 2f683fd

Browse files
author
Jatin Bhateja
committed
8361037: [ubsan] compiler/c2/irTests/TestFloat16ScalarOperations division by 0
Reviewed-by: mhaessig, sviswanathan
1 parent c75df63 commit 2f683fd

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/hotspot/share/opto/divnode.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,29 @@ const Type* DivHFNode::Value(PhaseGVN* phase) const {
825825

826826
if (t1->base() == Type::HalfFloatCon &&
827827
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+
828851
return TypeH::make(t1->getf() / t2->getf());
829852
}
830853

0 commit comments

Comments
 (0)