public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Move some complex simplifications to match.pd
@ 2015-08-30  7:57 Marc Glisse
  2015-08-31 12:29 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Glisse @ 2015-08-30  7:57 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1354 bytes --]

Hello,

just trying to shrink fold-const.c a bit more.

The tests "if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)" seem 
useless, I did one bootstrap+testsuite with asserts there to make sure, so 
I am dropping them. The CONJ_EXPR simplifications don't seem very useful, 
as far as I can tell CONJ_EXPR is immediatly replaced with a piecewise 
operation (where the transformations are obvious), but it seemed easier to 
keep the transformations, in case they are not completely useless. I may 
have been a bit too enthusiastic with the :s on some transformations, but 
again they seem to be dead code... The converts also seem to be not so 
useful since they are expanded piecewise, even the ones that should be 
NOPS, so for
   _Complex unsigned f(_Complex int i){return i;}
we generate:
 	movl	%edi, %eax
 	shrq	$32, %rdi
 	salq	$32, %rdi
 	orq	%rdi, %rax
...

Bootstrap+testsuite on ppc64le-redhat-linux.

2015-08-31  Marc Glisse  <marc.glisse@inria.fr>

gcc/
 	* match.pd (SIN, COS, TAN, COSH): Reorder for consistency.
 	(CEXPI): New operator list.
 	(real (conj (x)), imag (conj (x)), real (x +- y), real (cexpi (x)),
 	imag (cexpi (x)), conj (conj (x)), conj (complex (x, y))):
 	Converted from ...
 	* fold-const.c (fold_unary_loc, fold_binary_loc): ... here. Remove.

gcc/testsuite/
 	* gcc.dg/tree-ssa/complex-7.c: New file.

-- 
Marc Glisse

[-- Attachment #2: Type: TEXT/PLAIN, Size: 8835 bytes --]

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 227316)
+++ gcc/fold-const.c	(working copy)
@@ -7725,35 +7725,20 @@ fold_unary_loc (location_t loc, enum tre
       /* Strip sign ops from argument.  */
       if (TREE_CODE (type) == REAL_TYPE)
 	{
 	  tem = fold_strip_sign_ops (arg0);
 	  if (tem)
 	    return fold_build1_loc (loc, ABS_EXPR, type,
 				fold_convert_loc (loc, type, tem));
 	}
       return NULL_TREE;
 
-    case CONJ_EXPR:
-      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
-	return fold_convert_loc (loc, type, arg0);
-      if (TREE_CODE (arg0) == COMPLEX_EXPR)
-	{
-	  tree itype = TREE_TYPE (type);
-	  tree rpart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0, 0));
-	  tree ipart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0, 1));
-	  return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
-			      negate_expr (ipart));
-	}
-      if (TREE_CODE (arg0) == CONJ_EXPR)
-	return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
-      return NULL_TREE;
-
     case BIT_NOT_EXPR:
       /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
 	  && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
 				    fold_convert_loc (loc, type,
 						      TREE_OPERAND (arg0, 0)))))
 	return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
 				fold_convert_loc (loc, type,
 						  TREE_OPERAND (arg0, 1)));
       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
@@ -7769,95 +7754,20 @@ fold_unary_loc (location_t loc, enum tre
     case TRUTH_NOT_EXPR:
       /* Note that the operand of this must be an int
 	 and its values must be 0 or 1.
 	 ("true" is a fixed value perhaps depending on the language,
 	 but we don't handle values other than 1 correctly yet.)  */
       tem = fold_truth_not_expr (loc, arg0);
       if (!tem)
 	return NULL_TREE;
       return fold_convert_loc (loc, type, tem);
 
-    case REALPART_EXPR:
-      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
-	return fold_convert_loc (loc, type, arg0);
-      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
-	{
-	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
-	  tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
-			     fold_build1_loc (loc, REALPART_EXPR, itype,
-					  TREE_OPERAND (arg0, 0)),
-			     fold_build1_loc (loc, REALPART_EXPR, itype,
-					  TREE_OPERAND (arg0, 1)));
-	  return fold_convert_loc (loc, type, tem);
-	}
-      if (TREE_CODE (arg0) == CONJ_EXPR)
-	{
-	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
-	  tem = fold_build1_loc (loc, REALPART_EXPR, itype,
-			     TREE_OPERAND (arg0, 0));
-	  return fold_convert_loc (loc, type, tem);
-	}
-      if (TREE_CODE (arg0) == CALL_EXPR)
-	{
-	  tree fn = get_callee_fndecl (arg0);
-	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
-	    switch (DECL_FUNCTION_CODE (fn))
-	      {
-	      CASE_FLT_FN (BUILT_IN_CEXPI):
-	        fn = mathfn_built_in (type, BUILT_IN_COS);
-		if (fn)
-	          return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG (arg0, 0));
-		break;
-
-	      default:
-		break;
-	      }
-	}
-      return NULL_TREE;
-
-    case IMAGPART_EXPR:
-      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
-	return build_zero_cst (type);
-      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
-	{
-	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
-	  tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
-			     fold_build1_loc (loc, IMAGPART_EXPR, itype,
-					  TREE_OPERAND (arg0, 0)),
-			     fold_build1_loc (loc, IMAGPART_EXPR, itype,
-					  TREE_OPERAND (arg0, 1)));
-	  return fold_convert_loc (loc, type, tem);
-	}
-      if (TREE_CODE (arg0) == CONJ_EXPR)
-	{
-	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
-	  tem = fold_build1_loc (loc, IMAGPART_EXPR, itype, TREE_OPERAND (arg0, 0));
-	  return fold_convert_loc (loc, type, negate_expr (tem));
-	}
-      if (TREE_CODE (arg0) == CALL_EXPR)
-	{
-	  tree fn = get_callee_fndecl (arg0);
-	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
-	    switch (DECL_FUNCTION_CODE (fn))
-	      {
-	      CASE_FLT_FN (BUILT_IN_CEXPI):
-	        fn = mathfn_built_in (type, BUILT_IN_SIN);
-		if (fn)
-	          return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG (arg0, 0));
-		break;
-
-	      default:
-		break;
-	      }
-	}
-      return NULL_TREE;
-
     case INDIRECT_REF:
       /* Fold *&X to X if X is an lvalue.  */
       if (TREE_CODE (op0) == ADDR_EXPR)
 	{
 	  tree op00 = TREE_OPERAND (op0, 0);
 	  if ((TREE_CODE (op00) == VAR_DECL
 	       || TREE_CODE (op00) == PARM_DECL
 	       || TREE_CODE (op00) == RESULT_DECL)
 	      && !TREE_READONLY (op00))
 	    return op00;
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 227316)
+++ gcc/match.pd	(working copy)
@@ -48,24 +48,25 @@ along with GCC; see the file COPYING3.
 (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL)
 (define_operator_list EXP BUILT_IN_EXPF BUILT_IN_EXP BUILT_IN_EXPL)
 (define_operator_list LOG2 BUILT_IN_LOG2F BUILT_IN_LOG2 BUILT_IN_LOG2L)
 (define_operator_list EXP2 BUILT_IN_EXP2F BUILT_IN_EXP2 BUILT_IN_EXP2L)
 (define_operator_list LOG10 BUILT_IN_LOG10F BUILT_IN_LOG10 BUILT_IN_LOG10L)
 (define_operator_list EXP10 BUILT_IN_EXP10F BUILT_IN_EXP10 BUILT_IN_EXP10L)
 (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
 (define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L)
 (define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
 (define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL)
-(define_operator_list SIN BUILT_IN_SIN BUILT_IN_SINL BUILT_IN_SINF)
-(define_operator_list COS BUILT_IN_COS BUILT_IN_COSL BUILT_IN_COSF)
-(define_operator_list TAN BUILT_IN_TAN BUILT_IN_TANL BUILT_IN_TANF)
-(define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF)
+(define_operator_list SIN BUILT_IN_SINF BUILT_IN_SIN BUILT_IN_SINL)
+(define_operator_list COS BUILT_IN_COSF BUILT_IN_COS BUILT_IN_COSL)
+(define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL)
+(define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL)
+(define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL)
 
 /* Simplifications of operations with one constant operand and
    simplifications to constants or single values.  */
 
 (for op (plus pointer_plus minus bit_ior bit_xor)
   (simplify
     (op @0 integer_zerop)
     (non_lvalue @0)))
 
 /* 0 +p index -> (type)index */
@@ -1305,20 +1306,50 @@ along with GCC; see the file COPYING3.
 (simplify
  (complex (realpart @0) (imagpart @0))
  @0)
 (simplify
  (realpart (complex @0 @1))
  @0)
 (simplify
  (imagpart (complex @0 @1))
  @1)
 
+/* Sometimes we only care about half of a complex expression.  */
+(simplify
+ (realpart (convert?:s (conj:s @0)))
+ (convert (realpart @0)))
+(simplify
+ (imagpart (convert?:s (conj:s @0)))
+ (convert (negate (imagpart @0))))
+(for part (realpart imagpart)
+ (for op (plus minus)
+  (simplify
+   (part (convert?:s@2 (op:s @0 @1)))
+   (convert (op (part @0) (part @1))))))
+(simplify
+ (realpart (convert?:s (CEXPI:s @0)))
+ (convert (COS @0)))
+(simplify
+ (imagpart (convert?:s (CEXPI:s @0)))
+ (convert (SIN @0)))
+
+/* conj(conj(x)) -> x  */
+(simplify
+ (conj (convert? (conj @0)))
+ (if (tree_nop_conversion_p (TREE_TYPE (@0), type))
+  (convert @0)))
+
+/* conj({x,y}) -> {x,-y}  */
+(simplify
+ (conj (convert?:s (complex:s @0 @1)))
+ (with { tree itype = TREE_TYPE (type); }
+  (complex (convert:itype @0) (negate (convert:itype @1)))))
 
 /* BSWAP simplifications, transforms checked by gcc.dg/builtin-bswap-8.c.  */
 (for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32 BUILT_IN_BSWAP64)
  (simplify
   (bswap (bswap @0))
   @0)
  (simplify
   (bswap (bit_not (bswap @0)))
   (bit_not @0))
  (for bitop (bit_xor bit_ior bit_and)
Index: gcc/testsuite/gcc.dg/tree-ssa/complex-7.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/complex-7.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/complex-7.c	(working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+float f(_Complex float x, _Complex float y){
+  x += y;
+  return __builtin_cimagf (x);
+}
+
+double g(double x){
+  _Complex double c = __builtin_cexpi (x);
+  return __builtin_creal (c);
+}
+
+/* { dg-final { scan-tree-dump "__builtin_cos" "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "IMAGPART_EXPR" 2 "forwprop1"} } */

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Move some complex simplifications to match.pd
  2015-08-30  7:57 Move some complex simplifications to match.pd Marc Glisse
@ 2015-08-31 12:29 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2015-08-31 12:29 UTC (permalink / raw)
  To: Marc Glisse; +Cc: GCC Patches

On Sun, Aug 30, 2015 at 9:44 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> just trying to shrink fold-const.c a bit more.
>
> The tests "if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)" seem useless,
> I did one bootstrap+testsuite with asserts there to make sure, so I am
> dropping them. The CONJ_EXPR simplifications don't seem very useful, as far
> as I can tell CONJ_EXPR is immediatly replaced with a piecewise operation
> (where the transformations are obvious), but it seemed easier to keep the
> transformations, in case they are not completely useless. I may have been a
> bit too enthusiastic with the :s on some transformations, but again they
> seem to be dead code... The converts also seem to be not so useful since
> they are expanded piecewise, even the ones that should be NOPS,
> so for
>   _Complex unsigned f(_Complex int i){return i;}
> we generate:
>         movl    %edi, %eax
>         shrq    $32, %rdi
>         salq    $32, %rdi
>         orq     %rdi, %rax
> ...

Yeah, it might help for GENERIC folding but on gimple we lower things
pretty quickly
(partly during gimplification).

> Bootstrap+testsuite on ppc64le-redhat-linux.

Ok.

Thanks,
Richard.

> 2015-08-31  Marc Glisse  <marc.glisse@inria.fr>
>
> gcc/
>         * match.pd (SIN, COS, TAN, COSH): Reorder for consistency.
>         (CEXPI): New operator list.
>         (real (conj (x)), imag (conj (x)), real (x +- y), real (cexpi (x)),
>         imag (cexpi (x)), conj (conj (x)), conj (complex (x, y))):
>         Converted from ...
>         * fold-const.c (fold_unary_loc, fold_binary_loc): ... here. Remove.
>
> gcc/testsuite/
>         * gcc.dg/tree-ssa/complex-7.c: New file.
>
> --
> Marc Glisse
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    (revision 227316)
> +++ gcc/fold-const.c    (working copy)
> @@ -7725,35 +7725,20 @@ fold_unary_loc (location_t loc, enum tre
>        /* Strip sign ops from argument.  */
>        if (TREE_CODE (type) == REAL_TYPE)
>         {
>           tem = fold_strip_sign_ops (arg0);
>           if (tem)
>             return fold_build1_loc (loc, ABS_EXPR, type,
>                                 fold_convert_loc (loc, type, tem));
>         }
>        return NULL_TREE;
>
> -    case CONJ_EXPR:
> -      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> -       return fold_convert_loc (loc, type, arg0);
> -      if (TREE_CODE (arg0) == COMPLEX_EXPR)
> -       {
> -         tree itype = TREE_TYPE (type);
> -         tree rpart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0,
> 0));
> -         tree ipart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0,
> 1));
> -         return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
> -                             negate_expr (ipart));
> -       }
> -      if (TREE_CODE (arg0) == CONJ_EXPR)
> -       return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
> -      return NULL_TREE;
> -
>      case BIT_NOT_EXPR:
>        /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
>        if (TREE_CODE (arg0) == BIT_XOR_EXPR
>           && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
>                                     fold_convert_loc (loc, type,
>                                                       TREE_OPERAND (arg0,
> 0)))))
>         return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
>                                 fold_convert_loc (loc, type,
>                                                   TREE_OPERAND (arg0, 1)));
>        else if (TREE_CODE (arg0) == BIT_XOR_EXPR
> @@ -7769,95 +7754,20 @@ fold_unary_loc (location_t loc, enum tre
>      case TRUTH_NOT_EXPR:
>        /* Note that the operand of this must be an int
>          and its values must be 0 or 1.
>          ("true" is a fixed value perhaps depending on the language,
>          but we don't handle values other than 1 correctly yet.)  */
>        tem = fold_truth_not_expr (loc, arg0);
>        if (!tem)
>         return NULL_TREE;
>        return fold_convert_loc (loc, type, tem);
>
> -    case REALPART_EXPR:
> -      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> -       return fold_convert_loc (loc, type, arg0);
> -      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
> -       {
> -         tree itype = TREE_TYPE (TREE_TYPE (arg0));
> -         tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
> -                            fold_build1_loc (loc, REALPART_EXPR, itype,
> -                                         TREE_OPERAND (arg0, 0)),
> -                            fold_build1_loc (loc, REALPART_EXPR, itype,
> -                                         TREE_OPERAND (arg0, 1)));
> -         return fold_convert_loc (loc, type, tem);
> -       }
> -      if (TREE_CODE (arg0) == CONJ_EXPR)
> -       {
> -         tree itype = TREE_TYPE (TREE_TYPE (arg0));
> -         tem = fold_build1_loc (loc, REALPART_EXPR, itype,
> -                            TREE_OPERAND (arg0, 0));
> -         return fold_convert_loc (loc, type, tem);
> -       }
> -      if (TREE_CODE (arg0) == CALL_EXPR)
> -       {
> -         tree fn = get_callee_fndecl (arg0);
> -         if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
> -           switch (DECL_FUNCTION_CODE (fn))
> -             {
> -             CASE_FLT_FN (BUILT_IN_CEXPI):
> -               fn = mathfn_built_in (type, BUILT_IN_COS);
> -               if (fn)
> -                 return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG
> (arg0, 0));
> -               break;
> -
> -             default:
> -               break;
> -             }
> -       }
> -      return NULL_TREE;
> -
> -    case IMAGPART_EXPR:
> -      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> -       return build_zero_cst (type);
> -      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
> -       {
> -         tree itype = TREE_TYPE (TREE_TYPE (arg0));
> -         tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
> -                            fold_build1_loc (loc, IMAGPART_EXPR, itype,
> -                                         TREE_OPERAND (arg0, 0)),
> -                            fold_build1_loc (loc, IMAGPART_EXPR, itype,
> -                                         TREE_OPERAND (arg0, 1)));
> -         return fold_convert_loc (loc, type, tem);
> -       }
> -      if (TREE_CODE (arg0) == CONJ_EXPR)
> -       {
> -         tree itype = TREE_TYPE (TREE_TYPE (arg0));
> -         tem = fold_build1_loc (loc, IMAGPART_EXPR, itype, TREE_OPERAND
> (arg0, 0));
> -         return fold_convert_loc (loc, type, negate_expr (tem));
> -       }
> -      if (TREE_CODE (arg0) == CALL_EXPR)
> -       {
> -         tree fn = get_callee_fndecl (arg0);
> -         if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
> -           switch (DECL_FUNCTION_CODE (fn))
> -             {
> -             CASE_FLT_FN (BUILT_IN_CEXPI):
> -               fn = mathfn_built_in (type, BUILT_IN_SIN);
> -               if (fn)
> -                 return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG
> (arg0, 0));
> -               break;
> -
> -             default:
> -               break;
> -             }
> -       }
> -      return NULL_TREE;
> -
>      case INDIRECT_REF:
>        /* Fold *&X to X if X is an lvalue.  */
>        if (TREE_CODE (op0) == ADDR_EXPR)
>         {
>           tree op00 = TREE_OPERAND (op0, 0);
>           if ((TREE_CODE (op00) == VAR_DECL
>                || TREE_CODE (op00) == PARM_DECL
>                || TREE_CODE (op00) == RESULT_DECL)
>               && !TREE_READONLY (op00))
>             return op00;
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd        (revision 227316)
> +++ gcc/match.pd        (working copy)
> @@ -48,24 +48,25 @@ along with GCC; see the file COPYING3.
>  (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL)
>  (define_operator_list EXP BUILT_IN_EXPF BUILT_IN_EXP BUILT_IN_EXPL)
>  (define_operator_list LOG2 BUILT_IN_LOG2F BUILT_IN_LOG2 BUILT_IN_LOG2L)
>  (define_operator_list EXP2 BUILT_IN_EXP2F BUILT_IN_EXP2 BUILT_IN_EXP2L)
>  (define_operator_list LOG10 BUILT_IN_LOG10F BUILT_IN_LOG10 BUILT_IN_LOG10L)
>  (define_operator_list EXP10 BUILT_IN_EXP10F BUILT_IN_EXP10 BUILT_IN_EXP10L)
>  (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
>  (define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L)
>  (define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
>  (define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL)
> -(define_operator_list SIN BUILT_IN_SIN BUILT_IN_SINL BUILT_IN_SINF)
> -(define_operator_list COS BUILT_IN_COS BUILT_IN_COSL BUILT_IN_COSF)
> -(define_operator_list TAN BUILT_IN_TAN BUILT_IN_TANL BUILT_IN_TANF)
> -(define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF)
> +(define_operator_list SIN BUILT_IN_SINF BUILT_IN_SIN BUILT_IN_SINL)
> +(define_operator_list COS BUILT_IN_COSF BUILT_IN_COS BUILT_IN_COSL)
> +(define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL)
> +(define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL)
> +(define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL)
>
>  /* Simplifications of operations with one constant operand and
>     simplifications to constants or single values.  */
>
>  (for op (plus pointer_plus minus bit_ior bit_xor)
>    (simplify
>      (op @0 integer_zerop)
>      (non_lvalue @0)))
>
>  /* 0 +p index -> (type)index */
> @@ -1305,20 +1306,50 @@ along with GCC; see the file COPYING3.
>  (simplify
>   (complex (realpart @0) (imagpart @0))
>   @0)
>  (simplify
>   (realpart (complex @0 @1))
>   @0)
>  (simplify
>   (imagpart (complex @0 @1))
>   @1)
>
> +/* Sometimes we only care about half of a complex expression.  */
> +(simplify
> + (realpart (convert?:s (conj:s @0)))
> + (convert (realpart @0)))
> +(simplify
> + (imagpart (convert?:s (conj:s @0)))
> + (convert (negate (imagpart @0))))
> +(for part (realpart imagpart)
> + (for op (plus minus)
> +  (simplify
> +   (part (convert?:s@2 (op:s @0 @1)))
> +   (convert (op (part @0) (part @1))))))
> +(simplify
> + (realpart (convert?:s (CEXPI:s @0)))
> + (convert (COS @0)))
> +(simplify
> + (imagpart (convert?:s (CEXPI:s @0)))
> + (convert (SIN @0)))
> +
> +/* conj(conj(x)) -> x  */
> +(simplify
> + (conj (convert? (conj @0)))
> + (if (tree_nop_conversion_p (TREE_TYPE (@0), type))
> +  (convert @0)))
> +
> +/* conj({x,y}) -> {x,-y}  */
> +(simplify
> + (conj (convert?:s (complex:s @0 @1)))
> + (with { tree itype = TREE_TYPE (type); }
> +  (complex (convert:itype @0) (negate (convert:itype @1)))))
>
>  /* BSWAP simplifications, transforms checked by gcc.dg/builtin-bswap-8.c.
> */
>  (for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32 BUILT_IN_BSWAP64)
>   (simplify
>    (bswap (bswap @0))
>    @0)
>   (simplify
>    (bswap (bit_not (bswap @0)))
>    (bit_not @0))
>   (for bitop (bit_xor bit_ior bit_and)
> Index: gcc/testsuite/gcc.dg/tree-ssa/complex-7.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/complex-7.c   (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/complex-7.c   (working copy)
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-forwprop1" } */
> +
> +float f(_Complex float x, _Complex float y){
> +  x += y;
> +  return __builtin_cimagf (x);
> +}
> +
> +double g(double x){
> +  _Complex double c = __builtin_cexpi (x);
> +  return __builtin_creal (c);
> +}
> +
> +/* { dg-final { scan-tree-dump "__builtin_cos" "forwprop1"} } */
> +/* { dg-final { scan-tree-dump-times "IMAGPART_EXPR" 2 "forwprop1"} } */
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-08-31 12:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-30  7:57 Move some complex simplifications to match.pd Marc Glisse
2015-08-31 12:29 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).