Author: Matt Arsenault Date: 2026-03-12T06:43:18Z New Revision: 3da14eeacb90b5298805197b96f92551b7759a1d
URL: https://github.com/llvm/llvm-project/commit/3da14eeacb90b5298805197b96f92551b7759a1d DIFF: https://github.com/llvm/llvm-project/commit/3da14eeacb90b5298805197b96f92551b7759a1d.diff LOG: libclc: Update hypot implementation (#185873) This avoids bithacking on the values and improves value tracking. Added: Modified: libclc/clc/lib/generic/math/clc_hypot.cl libclc/clc/lib/generic/math/clc_hypot.inc Removed: ################################################################################ diff --git a/libclc/clc/lib/generic/math/clc_hypot.cl b/libclc/clc/lib/generic/math/clc_hypot.cl index c934ab29da91b..7b5a5a7027da0 100644 --- a/libclc/clc/lib/generic/math/clc_hypot.cl +++ b/libclc/clc/lib/generic/math/clc_hypot.cl @@ -6,16 +6,18 @@ // //===----------------------------------------------------------------------===// -#include <clc/clc_convert.h> -#include <clc/integer/clc_abs.h> -#include <clc/internal/clc.h> -#include <clc/math/clc_fma.h> -#include <clc/math/clc_mad.h> -#include <clc/math/clc_sqrt.h> -#include <clc/math/clc_subnormal_config.h> -#include <clc/math/math.h> -#include <clc/relational/clc_isnan.h> -#include <clc/shared/clc_clamp.h> +#include "clc/clc_convert.h" +#include "clc/float/definitions.h" +#include "clc/internal/clc.h" +#include "clc/math/clc_fabs.h" +#include "clc/math/clc_fmax.h" +#include "clc/math/clc_frexp.h" +#include "clc/math/clc_ldexp.h" +#include "clc/math/clc_mad.h" +#include "clc/math/clc_sqrt_fast.h" +#include "clc/math/math.h" +#include "clc/relational/clc_isinf.h" +#include "clc/relational/clc_isunordered.h" #define __CLC_BODY <clc_hypot.inc> #include <clc/math/gentype.inc> diff --git a/libclc/clc/lib/generic/math/clc_hypot.inc b/libclc/clc/lib/generic/math/clc_hypot.inc index 2fa91620b1fa8..2321fb3dcbeb4 100644 --- a/libclc/clc/lib/generic/math/clc_hypot.inc +++ b/libclc/clc/lib/generic/math/clc_hypot.inc @@ -10,85 +10,48 @@ // warrants it #if __CLC_FPSIZE == 32 -_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, - __CLC_GENTYPE y) { - __CLC_UINTN ux = __CLC_AS_UINTN(x); - __CLC_UINTN aux = ux & EXSIGNBIT_SP32; - __CLC_UINTN uy = __CLC_AS_UINTN(y); - __CLC_UINTN auy = uy & EXSIGNBIT_SP32; - __CLC_INTN c = aux > auy; - ux = c ? aux : auy; - uy = c ? auy : aux; - - __CLC_INTN xexp = __clc_clamp( - __CLC_AS_INTN(ux >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32, -126, 126); - __CLC_GENTYPE fx_exp = - __CLC_AS_GENTYPE((xexp + EXPBIAS_SP32) << EXPSHIFTBITS_SP32); - __CLC_GENTYPE fi_exp = - __CLC_AS_GENTYPE((-xexp + EXPBIAS_SP32) << EXPSHIFTBITS_SP32); - __CLC_GENTYPE fx = __CLC_AS_GENTYPE(ux) * fi_exp; - __CLC_GENTYPE fy = __CLC_AS_GENTYPE(uy) * fi_exp; - - __CLC_GENTYPE retval = __clc_sqrt(__clc_mad(fx, fx, fy * fy)) * fx_exp; - - retval = (ux > PINFBITPATT_SP32 || uy == 0) ? __CLC_AS_GENTYPE(ux) : retval; - retval = (ux == PINFBITPATT_SP32 || uy == PINFBITPATT_SP32) - ? __CLC_AS_GENTYPE((__CLC_UINTN)PINFBITPATT_SP32) - : retval; - return retval; +_CLC_OVERLOAD _CLC_DEF _CLC_CONST __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, + __CLC_GENTYPE y) { + __CLC_GENTYPE a = __clc_fabs(x); + __CLC_GENTYPE b = __clc_fabs(y); + __CLC_GENTYPE t = __clc_fmax(a, b); + __CLC_INTN e = __clc_frexp_exp(t); + + a = __clc_ldexp(a, -e); + b = __clc_ldexp(b, -e); + __CLC_GENTYPE ret = __clc_ldexp(__clc_sqrt_fast(__clc_mad(a, a, b * b)), e); + + return __clc_isinf(t) ? __CLC_GENTYPE_INF : ret; } #elif __CLC_FPSIZE == 64 -_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, - __CLC_GENTYPE y) { - __CLC_ULONGN ux = __CLC_AS_ULONGN(x) & ~SIGNBIT_DP64; - __CLC_INTN xexp = __CLC_CONVERT_INTN(ux >> EXPSHIFTBITS_DP64); - x = __CLC_AS_GENTYPE(ux); - - __CLC_ULONGN uy = __CLC_AS_ULONGN(y) & ~SIGNBIT_DP64; - __CLC_INTN yexp = __CLC_CONVERT_INTN(uy >> EXPSHIFTBITS_DP64); - y = __CLC_AS_GENTYPE(uy); - - __CLC_LONGN c = __CLC_CONVERT_LONGN(xexp > EXPBIAS_DP64 + 500 || - yexp > EXPBIAS_DP64 + 500); - __CLC_GENTYPE preadjust = c ? 0x1.0p-600 : 1.0; - __CLC_GENTYPE postadjust = c ? 0x1.0p+600 : 1.0; - - c = __CLC_CONVERT_LONGN(xexp < EXPBIAS_DP64 - 500 || - yexp < EXPBIAS_DP64 - 500); - preadjust = c ? 0x1.0p+600 : preadjust; - postadjust = c ? 0x1.0p-600 : postadjust; +_CLC_OVERLOAD _CLC_DEF _CLC_CONST __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, + __CLC_GENTYPE y) { + __CLC_GENTYPE a = __clc_fabs(x); + __CLC_GENTYPE b = __clc_fabs(y); + __CLC_GENTYPE t = __clc_fmax(a, b); + __CLC_INTN e = __clc_frexp_exp(t); - __CLC_GENTYPE ax = x * preadjust; - __CLC_GENTYPE ay = y * preadjust; + a = __clc_ldexp(a, -e); + b = __clc_ldexp(b, -e); + __CLC_GENTYPE ret = __clc_ldexp(__clc_sqrt_fast(__clc_mad(a, a, b * b)), e); - // The post adjust may overflow, but this can't be avoided in any case - __CLC_GENTYPE r = __clc_sqrt(__clc_fma(ax, ax, ay * ay)) * postadjust; - - // If the diff erence in exponents between x and y is large - __CLC_GENTYPE s = x + y; - c = __CLC_CONVERT_LONGN(__clc_abs(xexp - yexp) > MANTLENGTH_DP64 + 1); - r = c ? s : r; - - // Check for NaN - c = __clc_isnan(x) || __clc_isnan(y); - r = c ? __CLC_AS_GENTYPE((__CLC_ULONGN)QNANBITPATT_DP64) : r; - - // If either is Inf, we must return Inf - c = x == __CLC_AS_GENTYPE((__CLC_ULONGN)PINFBITPATT_DP64) || - y == __CLC_AS_GENTYPE((__CLC_ULONGN)PINFBITPATT_DP64); - r = c ? __CLC_AS_GENTYPE((__CLC_ULONGN)PINFBITPATT_DP64) : r; - - return r; + ret = __clc_isunordered(x, y) ? __CLC_GENTYPE_NAN : ret; + return __clc_isinf(x) || __clc_isinf(y) ? __CLC_GENTYPE_INF : ret; } #elif __CLC_FPSIZE == 16 -_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, - __CLC_GENTYPE y) { - return __CLC_CONVERT_GENTYPE( - __clc_hypot(__CLC_CONVERT_FLOATN(x), __CLC_CONVERT_FLOATN(y))); +_CLC_OVERLOAD _CLC_DEF _CLC_CONST __CLC_GENTYPE __clc_hypot(__CLC_GENTYPE x, + __CLC_GENTYPE y) { + __CLC_FLOATN fx = __CLC_CONVERT_FLOATN(x); + __CLC_FLOATN fy = __CLC_CONVERT_FLOATN(y); + __CLC_FLOATN d2 = __clc_mad(fx, fx, fy * fy); + + __CLC_GENTYPE ret = __CLC_CONVERT_HALFN(__clc_sqrt_fast(d2)); + + return __clc_isinf(x) || __clc_isinf(y) ? __CLC_GENTYPE_INF : ret; } #endif _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
