From 6347c09b6748219fe4099426d9ee7ef12a685238 Mon Sep 17 00:00:00 2001 From: simmse Date: Thu, 24 Sep 2020 10:01:00 -0500 Subject: [PATCH 1/2] The new _Bit_cast function does not allow 80 bits wide long double. The Intel C++ compiler has an option to set the long double type to 80 bits wide (e.g. /Qlong-double). Coordinating with S.T. Lavavej, this modification uses the pre-processor when compiling with Intel C++, to revert the _Ctraits template class' _Isnan and _Isinf function bodies, to the single _LDtest line used in the previous complex include file implementation. If the new pre-processor logic is activated, the function bodies use the _LDtest function and compares the output to either _NANCODE or _INFCODE respectively. The pre-processor logic is such that three conditions have to be met to use the _LDtest function: 1) The __INTEL_COMPILER macro has to be defined 2) The __LONG_DOUBLE_SIZE__ macro has to be defined 3) The __LONG_DOUBLE_SIZE__ has to equal 80 The above two macros are defined when using the Intel C++ Compiler. Without the modification, the Intel C++ Compiler with /Qlong-double enabled, produces the following output messages from a single declaration of a complex variable using the 80 bit long double (e.g. complex sum;) 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\complex(205): error : no instance of function template "std::_Bit_cast" matches the argument list 1> argument types are: (long double) 1> const auto _Uint = _Bit_cast(_Left); 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\complex(214): error : no instance of function template "std::_Bit_cast" matches the argument list 1> argument types are: (long double) 1> const auto _Uint = _Bit_cast(_Left); --- stl/inc/complex | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stl/inc/complex b/stl/inc/complex index fbefce0f12e..93ee56ce8b9 100644 --- a/stl/inc/complex +++ b/stl/inc/complex @@ -223,13 +223,21 @@ public: } static bool _Isinf(_Ty _Left) { // test for infinity +#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && (__LONG_DOUBLE_SIZE__ == 80) + return _CSTD _LDtest(&_Left) == _INFCODE; +#else const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) == 0x7ff0000000000000U; +#endif } static _CONSTEXPR20 bool _Isnan(_Ty _Left) { +#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && (__LONG_DOUBLE_SIZE__ == 80) + return _CSTD _LDtest(&_Left) == _NANCODE; +#else const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) > 0x7ff0000000000000U; +#endif } static constexpr _Ty _Nanv() { // return NaN From 3c331ac31eaf104ad769d7508033e3a678c892e2 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 24 Sep 2020 17:52:05 -0700 Subject: [PATCH 2/2] Remove parentheses, add preprocessor comments. --- stl/inc/complex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/complex b/stl/inc/complex index 93ee56ce8b9..175c2a283f8 100644 --- a/stl/inc/complex +++ b/stl/inc/complex @@ -223,21 +223,21 @@ public: } static bool _Isinf(_Ty _Left) { // test for infinity -#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && (__LONG_DOUBLE_SIZE__ == 80) +#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && __LONG_DOUBLE_SIZE__ == 80 return _CSTD _LDtest(&_Left) == _INFCODE; -#else +#else // ^^^ 80-bit long double (not supported by MSVC in general, see GH-1316) / 64-bit long double vvv const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) == 0x7ff0000000000000U; -#endif +#endif // ^^^ 64-bit long double ^^^ } static _CONSTEXPR20 bool _Isnan(_Ty _Left) { -#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && (__LONG_DOUBLE_SIZE__ == 80) +#if defined(__INTEL_COMPILER) && defined(__LONG_DOUBLE_SIZE__) && __LONG_DOUBLE_SIZE__ == 80 return _CSTD _LDtest(&_Left) == _NANCODE; -#else +#else // ^^^ 80-bit long double (not supported by MSVC in general, see GH-1316) / 64-bit long double vvv const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) > 0x7ff0000000000000U; -#endif +#endif // ^^^ 64-bit long double ^^^ } static constexpr _Ty _Nanv() { // return NaN