1 // RUN: %clang_builtins %s %librt -lm -o %t && %run %t
2 // REQUIRES: librt_has_divtc3
3 // REQUIRES: c99-complex
6 // This test should be XFAILed on 32-bit sparc (sparc-target-arch, Issue
7 // #41838), but that is currently hidden, which caused an XPASS (Issue #72398).
16 // Returns: the quotient of (a + ib) / (c + id)
17 #if defined(CRT_HAS_TF_MODE)
19 COMPILER_RT_ABI Qcomplex
__divtc3(tf_float __a
, tf_float __b
, tf_float __c
,
22 enum {zero
, non_zero
, inf
, NaN
, non_zero_nan
};
24 static int classify(Qcomplex x
) {
25 tf_float real
= COMPLEXTF_REAL(x
);
26 tf_float imag
= COMPLEXTF_IMAGINARY(x
);
27 if (real
== 0.0 && imag
== 0.0)
29 if (crt_isinf(real
) || crt_isinf(imag
))
31 if (crt_isnan(real
) && crt_isnan(imag
))
33 if (crt_isnan(real
)) {
38 if (crt_isnan(imag
)) {
46 static int test__divtc3(tf_float a
, tf_float b
, tf_float c
, tf_float d
) {
47 Qcomplex r
= __divtc3(a
, b
, c
, d
);
51 COMPLEXTF_REAL(dividend
) = a
;
52 COMPLEXTF_IMAGINARY(dividend
) = b
;
53 COMPLEXTF_REAL(divisor
) = c
;
54 COMPLEXTF_IMAGINARY(divisor
) = d
;
56 switch (classify(dividend
)) {
58 switch (classify(divisor
)) {
60 if (classify(r
) != NaN
)
64 if (classify(r
) != zero
)
68 if (classify(r
) != zero
)
72 if (classify(r
) != NaN
)
76 if (classify(r
) != NaN
)
82 switch (classify(divisor
)) {
84 if (classify(r
) != inf
)
88 if (classify(r
) != non_zero
)
91 tf_float zReal
= (a
* c
+ b
* d
) / (c
* c
+ d
* d
);
92 tf_float zImag
= (b
* c
- a
* d
) / (c
* c
+ d
* d
);
94 __divtc3(COMPLEXTF_REAL(r
) - zReal
, COMPLEXTF_IMAGINARY(r
) - zImag
,
95 COMPLEXTF_REAL(r
), COMPLEXTF_IMAGINARY(r
));
96 // cabsl(z) == hypotl(creall(z), cimagl(z))
97 #ifdef CRT_LDBL_128BIT
98 if (hypotl(COMPLEXTF_REAL(diff
), COMPLEXTF_IMAGINARY(diff
)) > 1.e
-6)
100 // Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.
101 if (hypot(COMPLEXTF_REAL(diff
), COMPLEXTF_IMAGINARY(diff
)) > 1.e
-6)
107 if (classify(r
) != zero
)
111 if (classify(r
) != NaN
)
115 if (classify(r
) != NaN
)
121 switch (classify(divisor
)) {
123 if (classify(r
) != inf
)
127 if (classify(r
) != inf
)
131 if (classify(r
) != NaN
)
135 if (classify(r
) != NaN
)
139 if (classify(r
) != NaN
)
145 switch (classify(divisor
)) {
147 if (classify(r
) != NaN
)
151 if (classify(r
) != NaN
)
155 if (classify(r
) != NaN
)
159 if (classify(r
) != NaN
)
163 if (classify(r
) != NaN
)
169 switch (classify(divisor
)) {
171 if (classify(r
) != inf
)
175 if (classify(r
) != NaN
)
179 if (classify(r
) != NaN
)
183 if (classify(r
) != NaN
)
187 if (classify(r
) != NaN
)
197 tf_float x
[][2] = {{1.e
-6, 1.e
-6},
230 {-INFINITY
, -INFINITY
},
239 {INFINITY
, -INFINITY
},
338 {-INFINITY
, INFINITY
},
352 const unsigned N
= sizeof(x
) / sizeof(x
[0]);
354 for (i
= 0; i
< N
; ++i
) {
355 for (j
= 0; j
< N
; ++j
) {
356 if (test__divtc3(x
[i
][0], x
[i
][1], x
[j
][0], x
[j
][1])) {
357 fprintf(stderr
, "Failed for %g, %g, %g, %g\n", (double)x
[i
][0],
358 (double)x
[i
][1], (double)x
[j
][0], (double)x
[j
][1]);
364 fprintf(stderr
, "No errors found.\n");
375 #endif // CRT_HAS_TF_MODE