Skip to content

[libclc] Avoid out-of-range float-to-int. #19144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions libclc/clc/lib/generic/math/clc_pow.inc
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,15 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_pow(__CLC_GENTYPE x,
const __CLC_GENTYPE lnof2_by_64_head = 0.010830424260348081;
const __CLC_GENTYPE lnof2_by_64_tail = -4.359010638708991e-10;

// If v is so large that we need to return INFINITY, or so small that we
// need to return 0, set v to known values that will produce that result. Do
// not try to continue the computation with the original v and patch it up
// afterwards because v may be so large that temp is out of range of int, in
// which case that conversion, and a value based on that conversion being
// passed to __clc_ldexp, results in undefined behavior.
v = v > max_exp_arg ? 1000.0 : v;
v = v < min_exp_arg ? -1000.0 : v;

__CLC_GENTYPE temp = v * sixtyfour_by_lnof2;
__CLC_INTN n = __CLC_CONVERT_INTN(temp);
__CLC_GENTYPE dn = __CLC_CONVERT_GENTYPE(n);
Expand Down Expand Up @@ -357,10 +366,6 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_pow(__CLC_GENTYPE x,

expv = __clc_fma(f, q, f2) + f1;
expv = __clc_ldexp(expv, m);

expv = v > max_exp_arg ? __CLC_AS_GENTYPE((__CLC_ULONGN)0x7FF0000000000000L)
: expv;
expv = v < min_exp_arg ? 0.0 : expv;
}

// See whether y is an integer.
Expand Down
13 changes: 9 additions & 4 deletions libclc/clc/lib/generic/math/clc_pown.inc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,15 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_pown(__CLC_GENTYPE x,
const __CLC_GENTYPE lnof2_by_64_head = 0.010830424260348081;
const __CLC_GENTYPE lnof2_by_64_tail = -4.359010638708991e-10;

// If v is so large that we need to return INFINITY, or so small that we
// need to return 0, set v to known values that will produce that result. Do
// not try to continue the computation with the original v and patch it up
// afterwards because v may be so large that temp is out of range of int, in
// which case that conversion, and a value based on that conversion being
// passed to __clc_ldexp, results in undefined behavior.
v = v > max_exp_arg ? 1000.0 : v;
v = v < min_exp_arg ? -1000.0 : v;

__CLC_GENTYPE temp = v * sixtyfour_by_lnof2;
__CLC_INTN n = __CLC_CONVERT_INTN(temp);
__CLC_GENTYPE dn = __CLC_CONVERT_GENTYPE(n);
Expand Down Expand Up @@ -344,10 +353,6 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_pown(__CLC_GENTYPE x,

expv = __clc_fma(f, q, f2) + f1;
expv = __clc_ldexp(expv, m);

expv = v > max_exp_arg ? __CLC_AS_GENTYPE((__CLC_ULONGN)0x7FF0000000000000L)
: expv;
expv = v < min_exp_arg ? 0.0 : expv;
}

// See whether y is an integer.
Expand Down
13 changes: 9 additions & 4 deletions libclc/clc/lib/generic/math/clc_powr.inc
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,15 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_powr(__CLC_GENTYPE x,
const __CLC_GENTYPE lnof2_by_64_head = 0.010830424260348081;
const __CLC_GENTYPE lnof2_by_64_tail = -4.359010638708991e-10;

// If v is so large that we need to return INFINITY, or so small that we
// need to return 0, set v to known values that will produce that result. Do
// not try to continue the computation with the original v and patch it up
// afterwards because v may be so large that temp is out of range of int, in
// which case that conversion, and a value based on that conversion being
// passed to __clc_ldexp, results in undefined behavior.
v = v > max_exp_arg ? 1000.0 : v;
v = v < min_exp_arg ? -1000.0 : v;

__CLC_GENTYPE temp = v * sixtyfour_by_lnof2;
__CLC_INTN n = __CLC_CONVERT_INTN(temp);
__CLC_GENTYPE dn = __CLC_CONVERT_GENTYPE(n);
Expand Down Expand Up @@ -343,10 +352,6 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_powr(__CLC_GENTYPE x,

expv = __clc_fma(f, q, f2) + f1;
expv = __clc_ldexp(expv, m);

expv = v > max_exp_arg ? __CLC_AS_GENTYPE((__CLC_ULONGN)0x7FF0000000000000L)
: expv;
expv = v < min_exp_arg ? 0.0 : expv;
}

// See whether y is an integer.
Expand Down
13 changes: 9 additions & 4 deletions libclc/clc/lib/generic/math/clc_rootn.inc
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,15 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_rootn(__CLC_GENTYPE x,
const __CLC_GENTYPE lnof2_by_64_head = 0.010830424260348081;
const __CLC_GENTYPE lnof2_by_64_tail = -4.359010638708991e-10;

// If v is so large that we need to return INFINITY, or so small that we
// need to return 0, set v to known values that will produce that result. Do
// not try to continue the computation with the original v and patch it up
// afterwards because v may be so large that temp is out of range of int, in
// which case that conversion, and a value based on that conversion being
// passed to __clc_ldexp, results in undefined behavior.
v = v > max_exp_arg ? 1000.0 : v;
v = v < min_exp_arg ? -1000.0 : v;

__CLC_GENTYPE temp = v * sixtyfour_by_lnof2;
__CLC_INTN n = __CLC_CONVERT_INTN(temp);
__CLC_GENTYPE dn = __CLC_CONVERT_GENTYPE(n);
Expand Down Expand Up @@ -350,10 +359,6 @@ _CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_rootn(__CLC_GENTYPE x,

expv = __clc_fma(f, q, f2) + f1;
expv = __clc_ldexp(expv, m);

expv = v > max_exp_arg ? __CLC_AS_GENTYPE((__CLC_ULONGN)0x7FF0000000000000L)
: expv;
expv = v < min_exp_arg ? 0.0 : expv;
}

// See whether y is an integer.
Expand Down
12 changes: 9 additions & 3 deletions libclc/libspirv/lib/generic/math/clc_rootn.cl
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,15 @@ _CLC_DEF _CLC_OVERLOAD double __clc_rootn(double x, int ny) {
const double lnof2_by_64_head = 0.010830424260348081;
const double lnof2_by_64_tail = -4.359010638708991e-10;

// If v is so large that we need to return INFINITY, or so small that we
// need to return 0, set v to known values that will produce that result. Do
// not try to continue the computation with the original v and patch it up
// afterwards because v may be so large that temp is out of range of int, in
// which case that conversion, and a value based on that conversion being
// passed to __spirv_ocl_ldexp, results in undefined behavior.
v = v > max_exp_arg ? 1000.0 : v;
v = v < min_exp_arg ? -1000.0 : v;

double temp = v * sixtyfour_by_lnof2;
int n = (int)(long)temp;
double dn = (double)n;
Expand Down Expand Up @@ -354,9 +363,6 @@ _CLC_DEF _CLC_OVERLOAD double __clc_rootn(double x, int ny) {

expv = __spirv_ocl_fma(f, q, f2) + f1;
expv = __spirv_ocl_ldexp(expv, m);

expv = v > max_exp_arg ? __clc_as_double(0x7FF0000000000000L) : expv;
expv = v < min_exp_arg ? 0.0 : expv;
}

// See whether y is an integer.
Expand Down