diff --git a/libdevice/fallback-complex-fp64.cpp b/libdevice/fallback-complex-fp64.cpp index 11803a1b72f83..28a5be8ab4a48 100644 --- a/libdevice/fallback-complex-fp64.cpp +++ b/libdevice/fallback-complex-fp64.cpp @@ -152,11 +152,10 @@ double __complex__ __devicelib_cexp(double __complex__ z) { } else if (__spirv_IsNan(z_real)) { if (z_imag == 0.0) return z; - else /* z_imag != 0.0 */ - return CMPLX(NAN, NAN); - } else if (__spirv_IsFinite(z_real)) { - if (__spirv_IsNan(z_imag) || __spirv_IsInf(z_imag)) - return CMPLX(NAN, NAN); + return CMPLX(NAN, NAN); + } else if (__spirv_IsFinite(z_real) && + (__spirv_IsNan(z_imag) || __spirv_IsInf(z_imag))) { + return CMPLX(NAN, NAN); } double __e = __spirv_ocl_exp(z_real); double ret_real = __e * __spirv_ocl_cos(z_imag); diff --git a/libdevice/fallback-complex.cpp b/libdevice/fallback-complex.cpp index e3f58b9eeb019..9f94195a3a407 100644 --- a/libdevice/fallback-complex.cpp +++ b/libdevice/fallback-complex.cpp @@ -141,27 +141,24 @@ DEVICE_EXTERN_C_INLINE float __complex__ __devicelib_cexpf(float __complex__ z) { float z_imag = __devicelib_cimagf(z); float z_real = __devicelib_crealf(z); + if (z_imag == 0) { + return CMPLXF(__spirv_ocl_exp(z_real), __spirv_ocl_copysign(0.f, z_imag)); + } + if (__spirv_IsInf(z_real)) { - if (z_real < 0.0f) { + if (z_real < 0.f) { if (!__spirv_IsFinite(z_imag)) z_imag = 1.0f; - } else if (z_imag == 0.0f || !__spirv_IsFinite(z_imag)) { + } else if (__spirv_IsNan(z_imag)) { + return z; + } else if (z_imag == 0.f || !__spirv_IsFinite(z_imag)) { if (__spirv_IsInf(z_imag)) - z_imag = NAN; - return CMPLXF(z_real, z_imag); + return CMPLXF(z_real, NAN); } - } else if (__spirv_IsNan(z_real) && (z_imag == 0.0f)) { - return z; } - float __e = __spirv_ocl_exp(z_real); - float ret_real = __e * __spirv_ocl_cos(z_imag); - float ret_imag = __e * __spirv_ocl_sin(z_imag); - if (__spirv_IsNan(ret_real)) - ret_real = 0.f; - if (__spirv_IsNan(ret_imag)) - ret_imag = 0.f; - return CMPLXF(ret_real, ret_imag); + float e = __spirv_ocl_exp(z_real); + return CMPLXF(e * __spirv_ocl_cos(z_imag), e * __spirv_ocl_sin(z_imag)); } DEVICE_EXTERN_C_INLINE diff --git a/sycl/test-e2e/DeviceLib/exp/exp-std-complex-double-edge-cases.cpp b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-double-edge-cases.cpp index 791bda2cf1e61..f539f67aacab6 100644 --- a/sycl/test-e2e/DeviceLib/exp/exp-std-complex-double-edge-cases.cpp +++ b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-double-edge-cases.cpp @@ -3,6 +3,7 @@ // // REQUIRES: aspect-fp64 // UNSUPPORTED: hip || cuda +// UNSUPPORTED-INTENDED: This test is intended for backends with SPIR-V support. // // RUN: %{build} -o %t.out // RUN: %{run} %t.out diff --git a/sycl/test-e2e/DeviceLib/exp/exp-std-complex-edge-cases.hpp b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-edge-cases.hpp index 649c960750156..d807a461e574f 100644 --- a/sycl/test-e2e/DeviceLib/exp/exp-std-complex-edge-cases.hpp +++ b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-edge-cases.hpp @@ -5,6 +5,7 @@ #include #include +#include bool check(bool cond, const std::string &cond_str, int line, unsigned testcase) { @@ -290,6 +291,13 @@ template bool test() { } else if (std::isfinite(testcases[i].imag()) && std::abs(testcases[i].imag()) <= 1) { CHECK(!std::signbit(r.real()), passed, i); +#ifdef _WIN32 + // This check fails on win, temporary skipping: + // CMPLRLLVM-61834 + // TODO: Delete this macro block when fixed + if (std::is_same_v) + continue; +#endif CHECK(std::signbit(r.imag()) == std::signbit(testcases[i].imag()), passed, i); // Those tests were taken from oneDPL, not sure what is the corner case diff --git a/sycl/test-e2e/DeviceLib/exp/exp-std-complex-float-edge-cases.cpp b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-float-edge-cases.cpp new file mode 100644 index 0000000000000..e1c956a45e382 --- /dev/null +++ b/sycl/test-e2e/DeviceLib/exp/exp-std-complex-float-edge-cases.cpp @@ -0,0 +1,12 @@ +// This test checks edge cases handling for std::exp(std::complex) used +// in SYCL kernels. +// +// UNSUPPORTED: hip || cuda +// UNSUPPORTED-INTENDED: This test is intended for backends with SPIR-V support. +// +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +#include "exp-std-complex-edge-cases.hpp" + +int main() { return test(); } diff --git a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp index ae42a97ce9264..3602d7d01ae95 100644 --- a/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp +++ b/sycl/test/e2e_test_requirements/no-unsupported-without-info.cpp @@ -54,7 +54,7 @@ // tests to match the required format and in that case you should just update // (i.e. reduce) the number and the list below. // -// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 478 +// NUMBER-OF-UNSUPPORTED-WITHOUT-INFO: 477 // // List of improperly UNSUPPORTED tests. // Remove the CHECK once the test has been properly UNSUPPORTED. @@ -113,7 +113,6 @@ // CHECK-NEXT: DeviceLib/cmath-aot.cpp // CHECK-NEXT: DeviceLib/cmath_fp64_test.cpp // CHECK-NEXT: DeviceLib/complex-fpga.cpp -// CHECK-NEXT: DeviceLib/exp/exp-std-complex-double-edge-cases.cpp // CHECK-NEXT: DeviceLib/imf_bfloat16_integeral_convesions.cpp // CHECK-NEXT: DeviceLib/imf_bfloat16_integeral_convesions.cpp // CHECK-NEXT: DeviceLib/imf_double2bfloat16.cpp