Commit 3c642f92 by Kaveh R. Ghazi Committed by Kaveh Ghazi

builtins.c (fold_builtin_cproj): Fold more cases.

        * builtins.c (fold_builtin_cproj): Fold more cases.

testsuite:
        * gcc.dg/torture/builtin-cproj-1.c: Test more cases.

From-SVN: r158574
parent 43272bf5
2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (fold_builtin_cproj): Fold more cases.
2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (build_complex_cproj, fold_builtin_cproj): New. * builtins.c (build_complex_cproj, fold_builtin_cproj): New.
(fold_builtin_1): Fold builtin cproj. (fold_builtin_1): Fold builtin cproj.
* builtins.def (BUILT_IN_CPROJ, BUILT_IN_CPROJF, BUILT_IN_CPROJL): * builtins.def (BUILT_IN_CPROJ, BUILT_IN_CPROJF, BUILT_IN_CPROJL):
......
...@@ -7082,6 +7082,33 @@ fold_builtin_cproj (location_t loc, tree arg, tree type) ...@@ -7082,6 +7082,33 @@ fold_builtin_cproj (location_t loc, tree arg, tree type)
else else
return arg; return arg;
} }
else if (TREE_CODE (arg) == COMPLEX_EXPR)
{
tree real = TREE_OPERAND (arg, 0);
tree imag = TREE_OPERAND (arg, 1);
STRIP_NOPS (real);
STRIP_NOPS (imag);
/* If the real part is inf and the imag part is known to be
nonnegative, return (inf + 0i). Remember side-effects are
possible in the imag part. */
if (TREE_CODE (real) == REAL_CST
&& real_isinf (TREE_REAL_CST_PTR (real))
&& tree_expr_nonnegative_p (imag))
return omit_one_operand_loc (loc, type,
build_complex_cproj (type, false),
arg);
/* If the imag part is inf, return (inf+I*copysign(0,imag)).
Remember side-effects are possible in the real part. */
if (TREE_CODE (imag) == REAL_CST
&& real_isinf (TREE_REAL_CST_PTR (imag)))
return
omit_one_operand_loc (loc, type,
build_complex_cproj (type, TREE_REAL_CST_PTR
(imag)->sign), arg);
}
return NULL_TREE; return NULL_TREE;
} }
......
2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-cproj-1.c: Test more cases.
2010-04-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-cproj-1.c: New. * gcc.dg/torture/builtin-cproj-1.c: New.
* gcc.dg/torture/builtin-cproj-2.c: New. * gcc.dg/torture/builtin-cproj-2.c: New.
......
...@@ -44,7 +44,80 @@ extern void link_error(int); ...@@ -44,7 +44,80 @@ extern void link_error(int);
link_error(__LINE__); \ link_error(__LINE__); \
} while (0) } while (0)
void foo (void) /* 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)
{ {
TEST_CST_INF (INF+0I, 0); TEST_CST_INF (INF+0I, 0);
TEST_CST_INF (INF-0I, -0.FI); TEST_CST_INF (INF-0I, -0.FI);
...@@ -79,6 +152,20 @@ void foo (void) ...@@ -79,6 +152,20 @@ void foo (void)
TEST_CST (-22+3I); TEST_CST (-22+3I);
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; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment