[VENTUS][fix] Correct edge-case logic for integer to float rounding (#190)

The conversion script previously applied a complex saturation check
to all integer-to-float conversions using the _rtz and _rtn
rounding modes.

This logic is only necessary for `int` and `uint` to `float`
conversions, where precision loss near the maximum value can occur.
It was incorrectly applied to other types like `long` or `char`, and
to conversions targeting `double`.

This commit refines the conditional logic to ensure this specific
check is now applied only to the four intended cases:
 - int -> float (_rtz/_rtn)
 - uint -> float (_rtz/_rtn)
This commit is contained in:
wenhu1024 2025-07-25 16:31:43 +08:00 committed by GitHub
parent d12d13ec8b
commit 64d0deb8ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 12 deletions

View File

@ -445,12 +445,18 @@ def generate_float_conversion(src, dst, size, mode, sat):
USRC=unsigned_type[src], N=size
)
)
# For integer sources, check for saturation case
print(
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x || (abs_y == abs_x && abs_y == ({USRC}{N}){SRC_MAX})));".format(
DST=dst, N=size, BOOL=bool_type[dst], USRC=unsigned_type[src], SRC_MAX=limit_max[src]
if dst == "float" and src in ["int", "uint"]:
print(
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x || (abs_y == abs_x && abs_y == ({USRC}{N}){SRC_MAX})));".format(
DST=dst, N=size, BOOL=bool_type[dst], USRC=unsigned_type[src], SRC_MAX=limit_max[src]
)
)
else:
print(
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));".format(
DST=dst, N=size, BOOL=bool_type[dst]
)
)
)
else:
print(" {SRC}{N} abs_x = fabs(x);".format(SRC=src, N=size))
print(" {SRC}{N} abs_y = fabs(y);".format(SRC=src, N=size))
@ -467,15 +473,19 @@ def generate_float_conversion(src, dst, size, mode, sat):
)
if mode == "_rtn":
if src in int_types:
# For integer sources, check for saturation case when converting back
# Cast the constant to source type to match vector element type
print(
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x || (y == x && y == ({SRC}{N}){SRC_MAX})));".format(
DST=dst, N=size, BOOL=bool_type[dst], SRC=src, SRC_MAX=limit_max[src]
if dst == "float" and src in ["int", "uint"]:
print(
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x || (y == x && y == ({SRC}{N}){SRC_MAX})));".format(
DST=dst, N=size, BOOL=bool_type[dst], SRC=src, SRC_MAX=limit_max[src]
)
)
else:
print(
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));".format(
DST=dst, N=size, BOOL=bool_type[dst]
)
)
)
else:
# For float sources, use original logic
print(
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));".format(
DST=dst, N=size, BOOL=bool_type[dst]