[VENTUS][fix] Fix libclc math functions (fmax, fmin, pow, powr, rsqrt) to handle edge cases

This commit is contained in:
wenhu1024 2025-03-13 11:12:16 +08:00
parent 1409696b87
commit 641747e8dc
4 changed files with 15 additions and 5 deletions

View File

@ -368,6 +368,9 @@ _CLC_DEF _CLC_OVERLOAD double __clc_pow(double x, double y)
long ret = as_long(expv);
// Now all the edge cases
ret = (ax < 0x3ff0000000000000L && ax > 0 && (uy & 0x8000000000000000L) && ((uy & 0x7FFFFFFFFFFFFFFFL) > 0x7FE0000000000000L) && uy != NINFBITPATT_DP64) ? PINFBITPATT_DP64 : ret;
ret = (!xpos && (uy & 0x8000000000000000L) && ((uy & 0x7FFFFFFFFFFFFFFFL) > 0x7FE0000000000000L) && uy != NINFBITPATT_DP64 && ax < 0x3ff0000000000000L) ? PINFBITPATT_DP64 : ret;
ret = (ax > 0x3ff0000000000000L && !xpos && (uy & 0x8000000000000000L) && ((uy & 0x7FFFFFFFFFFFFFFFL) > 0x7FE0000000000000L) && uy != NINFBITPATT_DP64) ? 0L : ret;
ret = !xpos & (inty == 0) ? QNANBITPATT_DP64 : ret;
ret = ax < 0x3ff0000000000000L & uy == NINFBITPATT_DP64 ? PINFBITPATT_DP64 : ret;
ret = ax > 0x3ff0000000000000L & uy == NINFBITPATT_DP64 ? 0L : ret;

View File

@ -373,7 +373,8 @@ _CLC_DEF _CLC_OVERLOAD double __clc_powr(double x, double y)
ret = ((ax == 0L) & (ay == 0L)) ? QNANBITPATT_DP64 : ret;
ret = ((ax != 0L) & !xpos) ? QNANBITPATT_DP64 : ret;
ret = ax > PINFBITPATT_DP64 ? ux : ret;
ret = ay > PINFBITPATT_DP64 ? uy : ret;
ret = (ax < 0x3ff0000000000000L && ax > 0 && (uy & 0x8000000000000000L) && ((uy & 0x7FFFFFFFFFFFFFFFL) > 0x7FE0000000000000L) && xpos && uy != NINFBITPATT_DP64) ? PINFBITPATT_DP64 : ret;
ret = ((ay & 0x7FF0000000000000L) == 0x7FF0000000000000L && (ay & 0x000FFFFFFFFFFFFFL) != 0) ? QNANBITPATT_DP64 : ret;
return as_double(ret);
}

View File

@ -15,6 +15,14 @@ _CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, rsqrt, float);
_CLC_OVERLOAD _CLC_DEF double rsqrt(double x)
{
if (x == 0.0) {
return __builtin_inf();
}
if (isnan(x)) {
return x;
}
return 1.0 / sqrt(x);
}

View File

@ -16,13 +16,11 @@
#include "types.h"
fp_t _fmax(fp_t x, fp_t y) {
return (__builtin_isnan((x)) || x < y) ? y : x;
return (__builtin_isnan(x)) ? y : ((__builtin_isnan(y)) ? x : ((x < y) ? y : x));
}
fp_t _fmin(fp_t x, fp_t y) {
return (__builtin_isnan((x)) || x < y) ? x : y;
return (__builtin_isnan(x)) ? y : ((__builtin_isnan(y)) ? x : ((x < y) ? x : y));
}
double rint (double x)