From 3c642f929e645b645c03b6d2490da25d46d6f4e7 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Tue, 20 Apr 2010 20:12:47 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 4 + gcc/builtins.c | 27 ++++++ gcc/testsuite/ChangeLog | 4 + .../gcc.dg/torture/builtin-cproj-1.c | 89 ++++++++++++++++++- 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72c4c9a43cd..cdb7c2b8ad6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2010-04-20 Kaveh R. Ghazi + + * builtins.c (fold_builtin_cproj): Fold more cases. + 2010-04-20 Kaveh R. Ghazi * builtins.c (build_complex_cproj, fold_builtin_cproj): New. diff --git a/gcc/builtins.c b/gcc/builtins.c index 8c3c8e0f4be..997c13a5505 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7082,6 +7082,33 @@ fold_builtin_cproj (location_t loc, tree arg, tree type) else 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2082071b29..e689381a4e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-04-20 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-cproj-1.c: Test more cases. + 2010-04-20 Kaveh R. Ghazi * gcc.dg/torture/builtin-cproj-1.c: New. diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c index 24540310b66..31cd5874ffb 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c @@ -44,7 +44,80 @@ extern void link_error(int); link_error(__LINE__); \ } 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.FI); @@ -79,6 +152,20 @@ void foo (void) 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; } -- 2.30.2