Move more cproj simplifications to match.pd
Also make build_complex_cproj available globally and use it for the existing match.pd rules. Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. gcc/ * builtins.c (fold_builtin_cproj): Delete. (fold_builtin_1): Handle constant arguments here. (build_complex_cproj): Move and rename to... * tree.c: (build_complex_inf): ...this. * tree.h (build_complex_inf): Declare. * match.pd: Fold cproj(x)->x if x has no infinity. Use build_complex_inf for existing cproj rules. From-SVN: r229164
This commit is contained in:
parent
7477de01a8
commit
92c52eab97
5 changed files with 49 additions and 60 deletions
|
@ -1,3 +1,13 @@
|
|||
2015-10-22 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* builtins.c (fold_builtin_cproj): Delete.
|
||||
(fold_builtin_1): Handle constant arguments here.
|
||||
(build_complex_cproj): Move and rename to...
|
||||
* tree.c: (build_complex_inf): ...this.
|
||||
* tree.h (build_complex_inf): Declare.
|
||||
* match.pd: Fold cproj(x)->x if x has no infinity.
|
||||
Use build_complex_inf for existing cproj rules.
|
||||
|
||||
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||
|
||||
PR target/68015
|
||||
|
|
|
@ -7538,50 +7538,6 @@ fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
|
|||
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))
|
||||
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 function call to builtin tan, tanf, or tanl with argument ARG.
|
||||
Return NULL_TREE if no simplification can be made. */
|
||||
|
||||
|
@ -9504,7 +9460,20 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
|
|||
break;
|
||||
|
||||
CASE_FLT_FN (BUILT_IN_CPROJ):
|
||||
return fold_builtin_cproj (loc, arg0, type);
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
|
||||
{
|
||||
const REAL_VALUE_TYPE *real
|
||||
= TREE_REAL_CST_PTR (TREE_REALPART (arg0));
|
||||
const REAL_VALUE_TYPE *imag
|
||||
= TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
|
||||
|
||||
if (real_isinf (real) || real_isinf (imag))
|
||||
return build_complex_inf (type, imag->sign);
|
||||
else
|
||||
return arg0;
|
||||
}
|
||||
break;
|
||||
|
||||
CASE_FLT_FN (BUILT_IN_CSIN):
|
||||
if (validate_arg (arg0, COMPLEX_TYPE)
|
||||
|
|
24
gcc/match.pd
24
gcc/match.pd
|
@ -2479,30 +2479,24 @@ along with GCC; see the file COPYING3. If not see
|
|||
(CABS (complex @0 @0))
|
||||
(mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); })))
|
||||
|
||||
/* cproj(x) -> x if we're ignoring infinities. */
|
||||
(simplify
|
||||
(CPROJ @0)
|
||||
(if (!HONOR_INFINITIES (type))
|
||||
@0))
|
||||
|
||||
/* If the real part is inf and the imag part is known to be
|
||||
nonnegative, return (inf + 0i). */
|
||||
(simplify
|
||||
(CPROJ (complex REAL_CST@0 tree_expr_nonnegative_p@1))
|
||||
(if (real_isinf (TREE_REAL_CST_PTR (@0)))
|
||||
(with
|
||||
{
|
||||
REAL_VALUE_TYPE rinf;
|
||||
real_inf (&rinf);
|
||||
}
|
||||
{ build_complex (type, build_real (TREE_TYPE (type), rinf),
|
||||
build_zero_cst (TREE_TYPE (type))); })))
|
||||
{ build_complex_inf (type, false); }))
|
||||
|
||||
/* If the imag part is inf, return (inf+I*copysign(0,imag)). */
|
||||
(simplify
|
||||
(CPROJ (complex @0 REAL_CST@1))
|
||||
(if (real_isinf (TREE_REAL_CST_PTR (@1)))
|
||||
(with
|
||||
{
|
||||
REAL_VALUE_TYPE rinf, rzero = dconst0;
|
||||
real_inf (&rinf);
|
||||
rzero.sign = TREE_REAL_CST_PTR (@1)->sign;
|
||||
}
|
||||
{ build_complex (type, build_real (TREE_TYPE (type), rinf),
|
||||
build_real (TREE_TYPE (type), rzero)); })))
|
||||
{ build_complex_inf (type, TREE_REAL_CST_PTR (@1)->sign); }))
|
||||
|
||||
|
||||
/* Narrowing of arithmetic and logical operations.
|
||||
|
|
15
gcc/tree.c
15
gcc/tree.c
|
@ -1986,6 +1986,21 @@ build_complex (tree type, tree real, tree imag)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Build a complex (inf +- 0i), such as for the result of cproj.
|
||||
TYPE is the complex tree type of the result. If NEG is true, the
|
||||
imaginary zero is negative. */
|
||||
|
||||
tree
|
||||
build_complex_inf (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));
|
||||
}
|
||||
|
||||
/* Return the constant 1 in type TYPE. If TYPE has several elements, each
|
||||
element is set to 1. In particular, this is 1 + i for complex types. */
|
||||
|
||||
|
|
|
@ -3853,6 +3853,7 @@ extern tree build_constructor_from_list (tree, tree);
|
|||
extern tree build_constructor_va (tree, int, ...);
|
||||
extern tree build_real_from_int_cst (tree, const_tree);
|
||||
extern tree build_complex (tree, tree, tree);
|
||||
extern tree build_complex_inf (tree, bool);
|
||||
extern tree build_each_one_cst (tree);
|
||||
extern tree build_one_cst (tree);
|
||||
extern tree build_minus_one_cst (tree);
|
||||
|
|
Loading…
Add table
Reference in a new issue