diff --git a/libclc/clc/lib/generic/math/clc_nextafter.cl b/libclc/clc/lib/generic/math/clc_nextafter.cl index 58125485bf684..f77f3647d5985 100644 --- a/libclc/clc/lib/generic/math/clc_nextafter.cl +++ b/libclc/clc/lib/generic/math/clc_nextafter.cl @@ -1,5 +1,6 @@ #include #include +#include #include // This file provides OpenCL C implementations of __clc_nextafter for @@ -12,21 +13,30 @@ FLOAT_TYPE y) { \ const UINT_TYPE sign_bit = (UINT_TYPE)1 \ << (sizeof(INT_TYPE_SCALAR) * 8 - 1); \ - const UINT_TYPE sign_bit_mask = sign_bit - (UINT_TYPE)1; \ - INT_TYPE ix = CLC_AS_TYPE(INT_TYPE)(x); \ - UINT_TYPE ax = CLC_AS_TYPE(UINT_TYPE)(ix) & sign_bit_mask; \ - INT_TYPE mx = CLC_AS_TYPE(INT_TYPE)(sign_bit) - ix; \ - mx = CLC_AS_TYPE(INT_TYPE)(ix) < (INT_TYPE)0 ? mx : ix; \ - INT_TYPE iy = CLC_AS_TYPE(INT_TYPE)(y); \ - UINT_TYPE ay = CLC_AS_TYPE(UINT_TYPE)(iy) & sign_bit_mask; \ - INT_TYPE my = CLC_AS_TYPE(INT_TYPE)(sign_bit) - iy; \ - my = iy < (INT_TYPE)0 ? my : iy; \ + UINT_TYPE ix = CLC_AS_TYPE(UINT_TYPE)(x); \ + FLOAT_TYPE absx = __clc_fabs(x); \ + UINT_TYPE mxu = sign_bit - ix; \ + INT_TYPE mx = CLC_AS_TYPE(INT_TYPE)(mxu); \ + mx = CLC_AS_TYPE(INT_TYPE)(ix) < (INT_TYPE)0 ? mx \ + : CLC_AS_TYPE(INT_TYPE)(ix); \ + UINT_TYPE iy = CLC_AS_TYPE(UINT_TYPE)(y); \ + FLOAT_TYPE absy = __clc_fabs(y); \ + UINT_TYPE myu = sign_bit - iy; \ + INT_TYPE my = CLC_AS_TYPE(INT_TYPE)(myu); \ + my = CLC_AS_TYPE(INT_TYPE)(iy) < (INT_TYPE)0 ? my \ + : CLC_AS_TYPE(INT_TYPE)(iy); \ INT_TYPE t = mx + (mx < my ? (INT_TYPE)1 : (INT_TYPE)-1); \ - INT_TYPE r = CLC_AS_TYPE(INT_TYPE)(sign_bit) - t; \ - r = t < (INT_TYPE)0 ? r : t; \ + UINT_TYPE r = sign_bit - CLC_AS_TYPE(UINT_TYPE)(t); \ + r = (t < (INT_TYPE)0 || (t == (INT_TYPE)0 && mx < my)) \ + ? r \ + : CLC_AS_TYPE(UINT_TYPE)(t); \ r = __clc_isnan(x) ? ix : r; \ - r = __clc_isnan(y) ? CLC_AS_TYPE(INT_TYPE)(iy) : r; \ - r = ((ax | ay) == (UINT_TYPE)0 || ix == iy) ? iy : r; \ + r = __clc_isnan(y) ? iy : r; \ + r = ((CLC_AS_TYPE(UINT_TYPE)(absx) | CLC_AS_TYPE(UINT_TYPE)(absy)) == \ + (UINT_TYPE)0 || \ + ix == iy) \ + ? iy \ + : r; \ return CLC_AS_TYPE(FLOAT_TYPE)(r); \ }