Skip to content

Commit ae22f0b

Browse files
author
Hal Finkel
committedOct 1, 2016
Use __builtin_isnan/isinf/isfinite in complex
The libc-provided isnan/isinf/isfinite macro implementations are specifically designed to function correctly, even in the presence of -ffast-math (or, more specifically, -ffinite-math-only). As such, on most implementation, these either always turn into external function calls (e.g. glibc) or are specifically function calls when FINITE_MATH_ONLY is defined (e.g. Darwin). Our implementation of complex arithmetic makes heavy use of isnan/isinf/isfinite to deal with corner cases involving non-finite quantities. This was problematic in two respects: 1. On systems where these are always function calls (e.g. Linux/glibc), there was a performance penalty 2. When compiling with -ffast-math, there was a significant performance penalty (in fact, on Darwin and systems with similar implementations, the code may in fact be slower than not using -ffast-math, because the inline definitions provided by libc become unavailable to prevent the checks from being optimized out). Eliding these inf/nan checks in -ffast-math mode is consistent with what happens with libstdc++, and in my experience, what users expect. This is critical to getting high-performance code when using complex<T>. This change replaces uses of those functions on basic floating-point types with calls to __builtin_isnan/isinf/isfinite, which Clang will always expand inline. When using -ffast-math (or -ffinite-math-only), the optimizer will remove the checks as expected. Differential Revision: https://reviews.llvm.org/D18639 llvm-svn: 283051
1 parent 630dd6f commit ae22f0b

File tree

2 files changed

+139
-80
lines changed

2 files changed

+139
-80
lines changed
 

‎libcxx/include/cmath

+60
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,66 @@ hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
558558
}
559559
#endif
560560

561+
template <class _A1>
562+
_LIBCPP_ALWAYS_INLINE
563+
typename enable_if<is_floating_point<_A1>::value, bool>::type
564+
__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
565+
{
566+
#if __has_builtin(__builtin_isnan)
567+
return __builtin_isnan(__lcpp_x);
568+
#else
569+
return isnan(__lcpp_x);
570+
#endif
571+
}
572+
573+
template <class _A1>
574+
_LIBCPP_ALWAYS_INLINE
575+
typename enable_if<!is_floating_point<_A1>::value, bool>::type
576+
__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
577+
{
578+
return isnan(__lcpp_x);
579+
}
580+
581+
template <class _A1>
582+
_LIBCPP_ALWAYS_INLINE
583+
typename enable_if<is_floating_point<_A1>::value, bool>::type
584+
__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
585+
{
586+
#if __has_builtin(__builtin_isinf)
587+
return __builtin_isinf(__lcpp_x);
588+
#else
589+
return isinf(__lcpp_x);
590+
#endif
591+
}
592+
593+
template <class _A1>
594+
_LIBCPP_ALWAYS_INLINE
595+
typename enable_if<!is_floating_point<_A1>::value, bool>::type
596+
__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
597+
{
598+
return isinf(__lcpp_x);
599+
}
600+
601+
template <class _A1>
602+
_LIBCPP_ALWAYS_INLINE
603+
typename enable_if<is_floating_point<_A1>::value, bool>::type
604+
__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
605+
{
606+
#if __has_builtin(__builtin_isfinite)
607+
return __builtin_isfinite(__lcpp_x);
608+
#else
609+
return isfinite(__lcpp_x);
610+
#endif
611+
}
612+
613+
template <class _A1>
614+
_LIBCPP_ALWAYS_INLINE
615+
typename enable_if<!is_floating_point<_A1>::value, bool>::type
616+
__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
617+
{
618+
return isfinite(__lcpp_x);
619+
}
620+
561621
_LIBCPP_END_NAMESPACE_STD
562622

563623
#endif // _LIBCPP_CMATH

‎libcxx/include/complex

+79-80
Original file line numberDiff line numberDiff line change
@@ -599,39 +599,39 @@ operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
599599
_Tp __bc = __b * __c;
600600
_Tp __x = __ac - __bd;
601601
_Tp __y = __ad + __bc;
602-
if (isnan(__x) && isnan(__y))
602+
if (__libcpp_isnan(__x) && __libcpp_isnan(__y))
603603
{
604604
bool __recalc = false;
605-
if (isinf(__a) || isinf(__b))
605+
if (__libcpp_isinf(__a) || __libcpp_isinf(__b))
606606
{
607-
__a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);
608-
__b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);
609-
if (isnan(__c))
607+
__a = copysign(__libcpp_isinf(__a) ? _Tp(1) : _Tp(0), __a);
608+
__b = copysign(__libcpp_isinf(__b) ? _Tp(1) : _Tp(0), __b);
609+
if (__libcpp_isnan(__c))
610610
__c = copysign(_Tp(0), __c);
611-
if (isnan(__d))
611+
if (__libcpp_isnan(__d))
612612
__d = copysign(_Tp(0), __d);
613613
__recalc = true;
614614
}
615-
if (isinf(__c) || isinf(__d))
615+
if (__libcpp_isinf(__c) || __libcpp_isinf(__d))
616616
{
617-
__c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);
618-
__d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);
619-
if (isnan(__a))
617+
__c = copysign(__libcpp_isinf(__c) ? _Tp(1) : _Tp(0), __c);
618+
__d = copysign(__libcpp_isinf(__d) ? _Tp(1) : _Tp(0), __d);
619+
if (__libcpp_isnan(__a))
620620
__a = copysign(_Tp(0), __a);
621-
if (isnan(__b))
621+
if (__libcpp_isnan(__b))
622622
__b = copysign(_Tp(0), __b);
623623
__recalc = true;
624624
}
625-
if (!__recalc && (isinf(__ac) || isinf(__bd) ||
626-
isinf(__ad) || isinf(__bc)))
625+
if (!__recalc && (__libcpp_isinf(__ac) || __libcpp_isinf(__bd) ||
626+
__libcpp_isinf(__ad) || __libcpp_isinf(__bc)))
627627
{
628-
if (isnan(__a))
628+
if (__libcpp_isnan(__a))
629629
__a = copysign(_Tp(0), __a);
630-
if (isnan(__b))
630+
if (__libcpp_isnan(__b))
631631
__b = copysign(_Tp(0), __b);
632-
if (isnan(__c))
632+
if (__libcpp_isnan(__c))
633633
__c = copysign(_Tp(0), __c);
634-
if (isnan(__d))
634+
if (__libcpp_isnan(__d))
635635
__d = copysign(_Tp(0), __d);
636636
__recalc = true;
637637
}
@@ -674,7 +674,7 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
674674
_Tp __c = __w.real();
675675
_Tp __d = __w.imag();
676676
_Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
677-
if (isfinite(__logbw))
677+
if (__libcpp_isfinite(__logbw))
678678
{
679679
__ilogbw = static_cast<int>(__logbw);
680680
__c = scalbn(__c, -__ilogbw);
@@ -683,24 +683,24 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
683683
_Tp __denom = __c * __c + __d * __d;
684684
_Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
685685
_Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
686-
if (isnan(__x) && isnan(__y))
686+
if (__libcpp_isnan(__x) && __libcpp_isnan(__y))
687687
{
688-
if ((__denom == _Tp(0)) && (!isnan(__a) || !isnan(__b)))
688+
if ((__denom == _Tp(0)) && (!__libcpp_isnan(__a) || !__libcpp_isnan(__b)))
689689
{
690690
__x = copysign(_Tp(INFINITY), __c) * __a;
691691
__y = copysign(_Tp(INFINITY), __c) * __b;
692692
}
693-
else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
693+
else if ((__libcpp_isinf(__a) || __libcpp_isinf(__b)) && __libcpp_isfinite(__c) && __libcpp_isfinite(__d))
694694
{
695-
__a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);
696-
__b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);
695+
__a = copysign(__libcpp_isinf(__a) ? _Tp(1) : _Tp(0), __a);
696+
__b = copysign(__libcpp_isinf(__b) ? _Tp(1) : _Tp(0), __b);
697697
__x = _Tp(INFINITY) * (__a * __c + __b * __d);
698698
__y = _Tp(INFINITY) * (__b * __c - __a * __d);
699699
}
700-
else if (isinf(__logbw) && __logbw > _Tp(0) && isfinite(__a) && isfinite(__b))
700+
else if (__libcpp_isinf(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite(__a) && __libcpp_isfinite(__b))
701701
{
702-
__c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);
703-
__d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);
702+
__c = copysign(__libcpp_isinf(__c) ? _Tp(1) : _Tp(0), __c);
703+
__d = copysign(__libcpp_isinf(__d) ? _Tp(1) : _Tp(0), __d);
704704
__x = _Tp(0) * (__a * __c + __b * __d);
705705
__y = _Tp(0) * (__b * __c - __a * __d);
706706
}
@@ -910,9 +910,9 @@ inline _LIBCPP_INLINE_VISIBILITY
910910
_Tp
911911
norm(const complex<_Tp>& __c)
912912
{
913-
if (isinf(__c.real()))
913+
if (__libcpp_isinf(__c.real()))
914914
return abs(__c.real());
915-
if (isinf(__c.imag()))
915+
if (__libcpp_isinf(__c.imag()))
916916
return abs(__c.imag());
917917
return __c.real() * __c.real() + __c.imag() * __c.imag();
918918
}
@@ -955,7 +955,7 @@ complex<_Tp>
955955
proj(const complex<_Tp>& __c)
956956
{
957957
std::complex<_Tp> __r = __c;
958-
if (isinf(__c.real()) || isinf(__c.imag()))
958+
if (__libcpp_isinf(__c.real()) || __libcpp_isinf(__c.imag()))
959959
__r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
960960
return __r;
961961
}
@@ -969,7 +969,7 @@ typename enable_if
969969
>::type
970970
proj(_Tp __re)
971971
{
972-
if (isinf(__re))
972+
if (__libcpp_isinf(__re))
973973
__re = abs(__re);
974974
return complex<_Tp>(__re);
975975
}
@@ -987,32 +987,31 @@ proj(_Tp __re)
987987
return _ComplexType(__re);
988988
}
989989

990-
991990
// polar
992991

993992
template<class _Tp>
994993
complex<_Tp>
995994
polar(const _Tp& __rho, const _Tp& __theta = _Tp(0))
996995
{
997-
if (isnan(__rho) || signbit(__rho))
996+
if (__libcpp_isnan(__rho) || signbit(__rho))
998997
return complex<_Tp>(_Tp(NAN), _Tp(NAN));
999-
if (isnan(__theta))
998+
if (__libcpp_isnan(__theta))
1000999
{
1001-
if (isinf(__rho))
1000+
if (__libcpp_isinf(__rho))
10021001
return complex<_Tp>(__rho, __theta);
10031002
return complex<_Tp>(__theta, __theta);
10041003
}
1005-
if (isinf(__theta))
1004+
if (__libcpp_isinf(__theta))
10061005
{
1007-
if (isinf(__rho))
1006+
if (__libcpp_isinf(__rho))
10081007
return complex<_Tp>(__rho, _Tp(NAN));
10091008
return complex<_Tp>(_Tp(NAN), _Tp(NAN));
10101009
}
10111010
_Tp __x = __rho * cos(__theta);
1012-
if (isnan(__x))
1011+
if (__libcpp_isnan(__x))
10131012
__x = 0;
10141013
_Tp __y = __rho * sin(__theta);
1015-
if (isnan(__y))
1014+
if (__libcpp_isnan(__y))
10161015
__y = 0;
10171016
return complex<_Tp>(__x, __y);
10181017
}
@@ -1043,13 +1042,13 @@ template<class _Tp>
10431042
complex<_Tp>
10441043
sqrt(const complex<_Tp>& __x)
10451044
{
1046-
if (isinf(__x.imag()))
1045+
if (__libcpp_isinf(__x.imag()))
10471046
return complex<_Tp>(_Tp(INFINITY), __x.imag());
1048-
if (isinf(__x.real()))
1047+
if (__libcpp_isinf(__x.real()))
10491048
{
10501049
if (__x.real() > _Tp(0))
1051-
return complex<_Tp>(__x.real(), isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1052-
return complex<_Tp>(isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
1050+
return complex<_Tp>(__x.real(), __libcpp_isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1051+
return complex<_Tp>(__libcpp_isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
10531052
}
10541053
return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
10551054
}
@@ -1061,21 +1060,21 @@ complex<_Tp>
10611060
exp(const complex<_Tp>& __x)
10621061
{
10631062
_Tp __i = __x.imag();
1064-
if (isinf(__x.real()))
1063+
if (__libcpp_isinf(__x.real()))
10651064
{
10661065
if (__x.real() < _Tp(0))
10671066
{
1068-
if (!isfinite(__i))
1067+
if (!__libcpp_isfinite(__i))
10691068
__i = _Tp(1);
10701069
}
1071-
else if (__i == 0 || !isfinite(__i))
1070+
else if (__i == 0 || !__libcpp_isfinite(__i))
10721071
{
1073-
if (isinf(__i))
1072+
if (__libcpp_isinf(__i))
10741073
__i = _Tp(NAN);
10751074
return complex<_Tp>(__x.real(), __i);
10761075
}
10771076
}
1078-
else if (isnan(__x.real()) && __x.imag() == 0)
1077+
else if (__libcpp_isnan(__x.real()) && __x.imag() == 0)
10791078
return __x;
10801079
_Tp __e = exp(__x.real());
10811080
return complex<_Tp>(__e * cos(__i), __e * sin(__i));
@@ -1133,23 +1132,23 @@ complex<_Tp>
11331132
asinh(const complex<_Tp>& __x)
11341133
{
11351134
const _Tp __pi(atan2(+0., -0.));
1136-
if (isinf(__x.real()))
1135+
if (__libcpp_isinf(__x.real()))
11371136
{
1138-
if (isnan(__x.imag()))
1137+
if (__libcpp_isnan(__x.imag()))
11391138
return __x;
1140-
if (isinf(__x.imag()))
1139+
if (__libcpp_isinf(__x.imag()))
11411140
return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
11421141
return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
11431142
}
1144-
if (isnan(__x.real()))
1143+
if (__libcpp_isnan(__x.real()))
11451144
{
1146-
if (isinf(__x.imag()))
1145+
if (__libcpp_isinf(__x.imag()))
11471146
return complex<_Tp>(__x.imag(), __x.real());
11481147
if (__x.imag() == 0)
11491148
return __x;
11501149
return complex<_Tp>(__x.real(), __x.real());
11511150
}
1152-
if (isinf(__x.imag()))
1151+
if (__libcpp_isinf(__x.imag()))
11531152
return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
11541153
complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1)));
11551154
return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
@@ -1162,11 +1161,11 @@ complex<_Tp>
11621161
acosh(const complex<_Tp>& __x)
11631162
{
11641163
const _Tp __pi(atan2(+0., -0.));
1165-
if (isinf(__x.real()))
1164+
if (__libcpp_isinf(__x.real()))
11661165
{
1167-
if (isnan(__x.imag()))
1166+
if (__libcpp_isnan(__x.imag()))
11681167
return complex<_Tp>(abs(__x.real()), __x.imag());
1169-
if (isinf(__x.imag()))
1168+
if (__libcpp_isinf(__x.imag()))
11701169
{
11711170
if (__x.real() > 0)
11721171
return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
@@ -1177,13 +1176,13 @@ acosh(const complex<_Tp>& __x)
11771176
return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
11781177
return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
11791178
}
1180-
if (isnan(__x.real()))
1179+
if (__libcpp_isnan(__x.real()))
11811180
{
1182-
if (isinf(__x.imag()))
1181+
if (__libcpp_isinf(__x.imag()))
11831182
return complex<_Tp>(abs(__x.imag()), __x.real());
11841183
return complex<_Tp>(__x.real(), __x.real());
11851184
}
1186-
if (isinf(__x.imag()))
1185+
if (__libcpp_isinf(__x.imag()))
11871186
return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
11881187
complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));
11891188
return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
@@ -1196,21 +1195,21 @@ complex<_Tp>
11961195
atanh(const complex<_Tp>& __x)
11971196
{
11981197
const _Tp __pi(atan2(+0., -0.));
1199-
if (isinf(__x.imag()))
1198+
if (__libcpp_isinf(__x.imag()))
12001199
{
12011200
return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
12021201
}
1203-
if (isnan(__x.imag()))
1202+
if (__libcpp_isnan(__x.imag()))
12041203
{
1205-
if (isinf(__x.real()) || __x.real() == 0)
1204+
if (__libcpp_isinf(__x.real()) || __x.real() == 0)
12061205
return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
12071206
return complex<_Tp>(__x.imag(), __x.imag());
12081207
}
1209-
if (isnan(__x.real()))
1208+
if (__libcpp_isnan(__x.real()))
12101209
{
12111210
return complex<_Tp>(__x.real(), __x.real());
12121211
}
1213-
if (isinf(__x.real()))
1212+
if (__libcpp_isinf(__x.real()))
12141213
{
12151214
return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
12161215
}
@@ -1228,11 +1227,11 @@ template<class _Tp>
12281227
complex<_Tp>
12291228
sinh(const complex<_Tp>& __x)
12301229
{
1231-
if (isinf(__x.real()) && !isfinite(__x.imag()))
1230+
if (__libcpp_isinf(__x.real()) && !__libcpp_isfinite(__x.imag()))
12321231
return complex<_Tp>(__x.real(), _Tp(NAN));
1233-
if (__x.real() == 0 && !isfinite(__x.imag()))
1232+
if (__x.real() == 0 && !__libcpp_isfinite(__x.imag()))
12341233
return complex<_Tp>(__x.real(), _Tp(NAN));
1235-
if (__x.imag() == 0 && !isfinite(__x.real()))
1234+
if (__x.imag() == 0 && !__libcpp_isfinite(__x.real()))
12361235
return __x;
12371236
return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
12381237
}
@@ -1243,13 +1242,13 @@ template<class _Tp>
12431242
complex<_Tp>
12441243
cosh(const complex<_Tp>& __x)
12451244
{
1246-
if (isinf(__x.real()) && !isfinite(__x.imag()))
1245+
if (__libcpp_isinf(__x.real()) && !__libcpp_isfinite(__x.imag()))
12471246
return complex<_Tp>(abs(__x.real()), _Tp(NAN));
1248-
if (__x.real() == 0 && !isfinite(__x.imag()))
1247+
if (__x.real() == 0 && !__libcpp_isfinite(__x.imag()))
12491248
return complex<_Tp>(_Tp(NAN), __x.real());
12501249
if (__x.real() == 0 && __x.imag() == 0)
12511250
return complex<_Tp>(_Tp(1), __x.imag());
1252-
if (__x.imag() == 0 && !isfinite(__x.real()))
1251+
if (__x.imag() == 0 && !__libcpp_isfinite(__x.real()))
12531252
return complex<_Tp>(abs(__x.real()), __x.imag());
12541253
return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
12551254
}
@@ -1260,19 +1259,19 @@ template<class _Tp>
12601259
complex<_Tp>
12611260
tanh(const complex<_Tp>& __x)
12621261
{
1263-
if (isinf(__x.real()))
1262+
if (__libcpp_isinf(__x.real()))
12641263
{
1265-
if (!isfinite(__x.imag()))
1264+
if (!__libcpp_isfinite(__x.imag()))
12661265
return complex<_Tp>(_Tp(1), _Tp(0));
12671266
return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
12681267
}
1269-
if (isnan(__x.real()) && __x.imag() == 0)
1268+
if (__libcpp_isnan(__x.real()) && __x.imag() == 0)
12701269
return __x;
12711270
_Tp __2r(_Tp(2) * __x.real());
12721271
_Tp __2i(_Tp(2) * __x.imag());
12731272
_Tp __d(cosh(__2r) + cos(__2i));
12741273
_Tp __2rsh(sinh(__2r));
1275-
if (isinf(__2rsh) && isinf(__d))
1274+
if (__libcpp_isinf(__2rsh) && __libcpp_isinf(__d))
12761275
return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
12771276
__2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
12781277
return complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
@@ -1295,11 +1294,11 @@ complex<_Tp>
12951294
acos(const complex<_Tp>& __x)
12961295
{
12971296
const _Tp __pi(atan2(+0., -0.));
1298-
if (isinf(__x.real()))
1297+
if (__libcpp_isinf(__x.real()))
12991298
{
1300-
if (isnan(__x.imag()))
1299+
if (__libcpp_isnan(__x.imag()))
13011300
return complex<_Tp>(__x.imag(), __x.real());
1302-
if (isinf(__x.imag()))
1301+
if (__libcpp_isinf(__x.imag()))
13031302
{
13041303
if (__x.real() < _Tp(0))
13051304
return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
@@ -1309,13 +1308,13 @@ acos(const complex<_Tp>& __x)
13091308
return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
13101309
return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
13111310
}
1312-
if (isnan(__x.real()))
1311+
if (__libcpp_isnan(__x.real()))
13131312
{
1314-
if (isinf(__x.imag()))
1313+
if (__libcpp_isinf(__x.imag()))
13151314
return complex<_Tp>(__x.real(), -__x.imag());
13161315
return complex<_Tp>(__x.real(), __x.real());
13171316
}
1318-
if (isinf(__x.imag()))
1317+
if (__libcpp_isinf(__x.imag()))
13191318
return complex<_Tp>(__pi/_Tp(2), -__x.imag());
13201319
if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
13211320
return complex<_Tp>(__pi/_Tp(2), -__x.imag());

0 commit comments

Comments
 (0)
Please sign in to comment.