From 2f683fdc4a8f9c227e878b0d7fca645fc8abe1b6 Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Thu, 3 Jul 2025 08:03:55 +0000 Subject: [PATCH] 8361037: [ubsan] compiler/c2/irTests/TestFloat16ScalarOperations division by 0 Reviewed-by: mhaessig, sviswanathan --- src/hotspot/share/opto/divnode.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp index b3ac0a4a1b0..d4e76950503 100644 --- a/src/hotspot/share/opto/divnode.cpp +++ b/src/hotspot/share/opto/divnode.cpp @@ -825,6 +825,29 @@ const Type* DivHFNode::Value(PhaseGVN* phase) const { if (t1->base() == Type::HalfFloatCon && t2->base() == Type::HalfFloatCon) { + // IEEE 754 floating point comparison treats 0.0 and -0.0 as equals. + + // Division of a zero by a zero results in NaN. + if (t1->getf() == 0.0f && t2->getf() == 0.0f) { + return TypeH::make(NAN); + } + + // As per C++ standard section 7.6.5 (expr.mul), behavior is undefined only if + // the second operand is 0.0. In all other situations, we can expect a standard-compliant + // C++ compiler to generate code following IEEE 754 semantics. + if (t2->getf() == 0.0) { + // If either operand is NaN, the result is NaN + if (g_isnan(t1->getf())) { + return TypeH::make(NAN); + } else { + // Division of a nonzero finite value by a zero results in a signed infinity. Also, + // division of an infinity by a finite value results in a signed infinity. + bool res_sign_neg = (jint_cast(t1->getf()) < 0) ^ (jint_cast(t2->getf()) < 0); + const TypeF* res = res_sign_neg ? TypeF::NEG_INF : TypeF::POS_INF; + return TypeH::make(res->getf()); + } + } + return TypeH::make(t1->getf() / t2->getf()); }