return NULL_TREE;
}
+/* Build a complex (inf +- 0i) for the result of cproj. TYPE is the
+ complex tree type of the result. If NEG is true, the imaginary
+ zero is negative. */
+
+static tree
+build_complex_cproj (tree type, bool neg)
+{
+ REAL_VALUE_TYPE rinf, rzero = dconst0;
+
+ real_inf (&rinf);
+ rzero.sign = neg;
+ return build_complex (type, build_real (TREE_TYPE (type), rinf),
+ build_real (TREE_TYPE (type), rzero));
+}
+
+/* Fold call to builtin cproj, cprojf or cprojl with argument ARG. TYPE is the
+ return type. Return NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_cproj (location_t loc, tree arg, tree type)
+{
+ if (!validate_arg (arg, COMPLEX_TYPE)
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
+ return NULL_TREE;
+
+ /* If there are no infinities, return arg. */
+ if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
+ return non_lvalue_loc (loc, arg);
+
+ /* Calculate the result when the argument is a constant. */
+ if (TREE_CODE (arg) == COMPLEX_CST)
+ {
+ const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
+ const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
+
+ if (real_isinf (real) || real_isinf (imag))
+ return build_complex_cproj (type, imag->sign);
+ else
+ return arg;
+ }
+
+ return NULL_TREE;
+}
+
/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
Return NULL_TREE if no simplification can be made. */
CASE_FLT_FN (BUILT_IN_CCOSH):
return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
+ CASE_FLT_FN (BUILT_IN_CPROJ):
+ return fold_builtin_cproj(loc, arg0, type);
+
CASE_FLT_FN (BUILT_IN_CSIN):
if (validate_arg (arg0, COMPLEX_TYPE)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
link_error(__LINE__); \
} while (0)
-/* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i.
- NEG is either blank or a minus sign when ZERO is negative. */
-#define TEST_IMAG_INF(NEG,ZERO) do { \
- if (CPROJF(f+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
- if (CPROJ(d+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
- if (CPROJL(ld+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
-} while (0)
-
-/* Like TEST_IMAG_INF, but check that side effects are honored. */
-#define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \
- int side = 4; \
- if (CPROJF(++side+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJF(++side+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
- if (CPROJ(++side+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
- if (CPROJL(++side+I*NEG INF) != ZERO+INF \
- || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \
- link_error(__LINE__); \
- if (side != 10) \
- link_error(__LINE__); \
-} while (0)
-
-/* Test that cproj(INF, POSITIVE) -> INF+0i. NEG is either blank or a
- minus sign to test negative INF. */
-#define TEST_REAL_INF(NEG) do { \
- __real cf = NEG INF; \
- __imag cf = (x ? 4 : 5); \
- if (CPROJF(cf) != INF \
- || CKSGN_I (CPROJF(cf), INF)) \
- link_error(__LINE__); \
- __real cd = NEG INF; \
- __imag cd = (x ? 4 : 5); \
- if (CPROJ(cd) != INF \
- || CKSGN_I (CPROJ(cd), INF)) \
- link_error(__LINE__); \
- __real cld = NEG INF; \
- __imag cld = (x ? 4 : 5); \
- if (CPROJL(cld) != INF \
- || CKSGN_I (CPROJL(cld), INF)) \
- link_error(__LINE__); \
-} while (0)
-
-/* Like TEST_REAL_INF, but check that side effects are honored. */
-#define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \
- int side = -9; \
- __real cf = NEG INF; \
- __imag cf = (x ? 4 : 5); \
- if (CPROJF((++side,cf)) != INF \
- || CKSGN_I (CPROJF((++side,cf)), INF)) \
- link_error(__LINE__); \
- __real cd = NEG INF; \
- __imag cd = (x ? 4 : 5); \
- if (CPROJ((++side,cd)) != INF \
- || CKSGN_I (CPROJ((++side,cd)), INF)) \
- link_error(__LINE__); \
- __real cld = NEG INF; \
- __imag cld = (x ? 4 : 5); \
- if (CPROJL((++side,cld)) != INF \
- || CKSGN_I (CPROJL((++side,cld)), INF)) \
- link_error(__LINE__); \
- if (side != -3) \
- link_error(__LINE__); \
-} while (0)
-
-void foo (_Complex long double cld, _Complex double cd, _Complex float cf,
- long double ld, double d, float f, int x)
+void foo (void)
{
TEST_CST_INF (INF+0I, 0);
TEST_CST_INF (INF-0I, -0.FI);
TEST_CST (-22+3I);
TEST_CST (-22-3I);
- TEST_IMAG_INF (,0.FI);
- TEST_IMAG_INF (-,-0.FI);
-
-#ifdef __OPTIMIZE__
- TEST_REAL_INF( );
- TEST_REAL_INF(-);
-
- TEST_IMAG_INF_SIDE_EFFECT (,0.FI);
- TEST_IMAG_INF_SIDE_EFFECT (-,-0.FI);
-
- TEST_REAL_INF_SIDE_EFFECT( );
- TEST_REAL_INF_SIDE_EFFECT(-);
-#endif
-
return;
}