[libclc] [libclc] Fix int<->float conversion builtins (PR #126905)
Fraser Cormack via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 12 05:08:45 PST 2025
https://github.com/frasercrmck created https://github.com/llvm/llvm-project/pull/126905
While working on moving the conversion builtins to the CLC library in 25c05541 it was discovered that many weren't passing the OpenCL-CTS tests.
As it happens, the clspv-specific code for conversion implementations between integer and floating-point types was more correct. However:
* The clspv code was generating 'sat' conversions to floating-point types, which are not legal
* The clspv code around rtn/rtz conversions needed tweaking as it wasn't validating when sizeof(dst) > sizeof(src), e.g., int -> double.
With this commit, the CTS failures seen before have been resolved.
This also assumes that the new implementations are correct also for clspv. If this is the case, then 'clc' and 'clspv' modes are mutually exclusive and we can simplify the build process for conversions by not building clc-clspv-convert.cl.
Note that there are still outstanding failures in 'rtz' and 'rtp' rounding modes between float->half, double->half, and double->float (i.e., floating-point types when sizeof(src) > sizeof(dst)). These will be looked at separately.
>From 5677a1acb9e705d97713a11f8e154fbf511985b5 Mon Sep 17 00:00:00 2001
From: Fraser Cormack <fraser at codeplay.com>
Date: Wed, 12 Feb 2025 10:50:54 +0000
Subject: [PATCH] [libclc] Fix int<->float conversion builtins
While working on moving the conversion builtins to the CLC library in
25c05541 it was discovered that many weren't passing the OpenCL-CTS
tests.
As it happens, the clspv-specific code for conversion implementations
between integer and floating-point types was more correct. However:
* The clspv code was generating 'sat' conversions to floating-point
types, which are not legal
* The clspv code around rtn/rtz conversions needed tweaking as it wasn't
validating when sizeof(dst) > sizeof(src), e.g., int -> double.
With this commit, the CTS failures seen before have been resolved.
This also assumes that the new implementations are correct also for
clspv. If this is the case, then 'clc' and 'clspv' modes are mutually
exclusive and we can simplify the build process for conversions by not
building clc-clspv-convert.cl.
Note that there are still outstanding failures in 'rtz' and 'rtp'
rounding modes between float->half, double->half, and double->float
(i.e., floating-point types when sizeof(src) > sizeof(dst)). These will
be looked at separately.
---
libclc/generic/lib/gen_convert.py | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
diff --git a/libclc/generic/lib/gen_convert.py b/libclc/generic/lib/gen_convert.py
index 92f32694a52af..d2d5b7975275c 100644
--- a/libclc/generic/lib/gen_convert.py
+++ b/libclc/generic/lib/gen_convert.py
@@ -369,22 +369,13 @@ def generate_saturated_conversion(src, dst, size):
elif src in float_types:
- if clspv:
- # Conversion from float to int
- print(
- f""" {dstn} y = __clc_convert_{dstn}(x);
+ # Conversion from float to int
+ print(
+ f""" {dstn} y = __clc_convert_{dstn}(x);
y = __clc_select(y, ({dstn}){dst_min}, {bool_prefix}(x <= ({srcn}){dst_min}){bool_suffix});
y = __clc_select(y, ({dstn}){dst_max}, {bool_prefix}(x >= ({srcn}){dst_max}){bool_suffix});
return y;"""
- )
- else:
- # Conversion from float to int
- print(
- f""" {dstn} y = __clc_convert_{dstn}(x);
- y = __clc_select(y, ({dstn}){dst_min}, {bool_prefix}(x < ({srcn}){dst_min}){bool_suffix});
- y = __clc_select(y, ({dstn}){dst_max}, {bool_prefix}(x > ({srcn}){dst_max}){bool_suffix});
- return y;"""
- )
+ )
else:
# Integer to integer convesion with sizeof(src) == sizeof(dst)
@@ -494,7 +485,7 @@ def generate_float_conversion(src, dst, size, mode, sat):
print(f" return __clc_convert_{dstn}(x);")
else:
print(f" {dstn} r = __clc_convert_{dstn}(x);")
- if clspv:
+ if src in int_types:
print(f" {srcn} y = __clc_convert_{srcn}_sat(r);")
else:
print(f" {srcn} y = __clc_convert_{srcn}(r);")
@@ -507,7 +498,7 @@ def generate_float_conversion(src, dst, size, mode, sat):
print(f" {srcn} abs_x = __clc_fabs(x);")
print(f" {srcn} abs_y = __clc_fabs(y);")
print(f" {booln} c = __clc_convert_{booln}(abs_y > abs_x);")
- if clspv and sizeof_type[src] >= 4 and src in int_types:
+ if sizeof_type[src] >= sizeof_type[dst] and src in int_types:
print(f" c = c || __clc_convert_{booln}(({srcn}){src_max} == x);")
print(
f" {dstn} sel = __clc_select(r, __clc_nextafter(r, __clc_sign(r) * ({dstn})-INFINITY), c);"
@@ -533,7 +524,7 @@ def generate_float_conversion(src, dst, size, mode, sat):
print(" return sel;")
if mode == "_rtn":
print(f" {booln} c = __clc_convert_{booln}(y > x);")
- if clspv and sizeof_type[src] >= 4 and src in int_types:
+ if sizeof_type[src] >= sizeof_type[dst] and src in int_types:
print(f" c = c || __clc_convert_{booln}(({srcn}){src_max} == x);")
print(
f" {dstn} sel = __clc_select(r, __clc_nextafter(r, ({dstn})-INFINITY), c);"
More information about the cfe-commits
mailing list