Commit 8f8abce4 by Richard Henderson Committed by Richard Henderson

re PR tree-optimization/22035 (complex float comparison broken)

        PR tree-opt/22035
        * builtins.c (fold_builtin_complex_mul): Remove.
        (fold_builtin_complex_div): Remove.
        (fold_builtin_1): Don't call them.
        * fold-const.c (fold_complex_add, fold_complex_mult_parts,
        fold_complex_mult, fold_complex_div_parts, fold_complex_div): Remove.
        (fold_binary): Don't call them.  Don't expand complex comparisons to
        elementary comparisons.
        * tree-complex.c (init_dont_simulate_again): Enhance search for
        stmts that require decomposition.
        (complex_visit_stmt): Handle RETURN_EXPR properly.
        (create_components): Handle no referenced variables properly.
        * tree.h (fold_complex_mult_parts): Remove.
        (fold_complex_div_parts): Remove.

From-SVN: r101086
parent 2f84b963
2005-06-16 Richard Henderson <rth@redhat.com>
PR tree-opt/22035
* builtins.c (fold_builtin_complex_mul): Remove.
(fold_builtin_complex_div): Remove.
(fold_builtin_1): Don't call them.
* fold-const.c (fold_complex_add, fold_complex_mult_parts,
fold_complex_mult, fold_complex_div_parts, fold_complex_div): Remove.
(fold_binary): Don't call them. Don't expand complex comparisons to
elementary comparisons.
* tree-complex.c (init_dont_simulate_again): Enhance search for
stmts that require decomposition.
(complex_visit_stmt): Handle RETURN_EXPR properly.
(create_components): Handle no referenced variables properly.
* tree.h (fold_complex_mult_parts): Remove.
(fold_complex_div_parts): Remove.
2005-06-16 Richard Guenther <rguenth@gcc.gnu.org> 2005-06-16 Richard Guenther <rguenth@gcc.gnu.org>
* doc/extend.texi: Document sseregparm target attribute. * doc/extend.texi: Document sseregparm target attribute.
......
...@@ -8430,44 +8430,6 @@ fold_builtin_unordered_cmp (tree fndecl, tree arglist, ...@@ -8430,44 +8430,6 @@ fold_builtin_unordered_cmp (tree fndecl, tree arglist,
fold (build2 (code, type, arg0, arg1)))); fold (build2 (code, type, arg0, arg1))));
} }
/* Fold a call to one of the external complex multiply libcalls. */
static tree
fold_builtin_complex_mul (tree type, tree arglist)
{
tree ar, ai, br, bi;
if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
REAL_TYPE, VOID_TYPE))
return NULL;
ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
bi = TREE_VALUE (arglist);
return fold_complex_mult_parts (type, ar, ai, br, bi);
}
/* Fold a call to one of the external complex division libcalls. */
static tree
fold_builtin_complex_div (tree type, tree arglist)
{
tree ar, ai, br, bi;
if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
REAL_TYPE, VOID_TYPE))
return NULL;
ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
bi = TREE_VALUE (arglist);
return fold_complex_div_parts (type, ar, ai, br, bi, RDIV_EXPR);
}
/* Used by constant folding to simplify calls to builtin functions. EXP is /* Used by constant folding to simplify calls to builtin functions. EXP is
the CALL_EXPR of a call to a builtin function. IGNORE is true if the the CALL_EXPR of a call to a builtin function. IGNORE is true if the
result of the function call is ignored. This function returns NULL_TREE result of the function call is ignored. This function returns NULL_TREE
...@@ -8826,12 +8788,6 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore) ...@@ -8826,12 +8788,6 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
break; break;
default: default:
if (fcode >= BUILT_IN_COMPLEX_MUL_MIN
&& fcode <= BUILT_IN_COMPLEX_MUL_MAX)
return fold_builtin_complex_mul (type, arglist);
if (fcode >= BUILT_IN_COMPLEX_DIV_MIN
&& fcode <= BUILT_IN_COMPLEX_DIV_MAX)
return fold_builtin_complex_div (type, arglist);
break; break;
} }
......
...@@ -150,7 +150,7 @@ init_dont_simulate_again (void) ...@@ -150,7 +150,7 @@ init_dont_simulate_again (void)
basic_block bb; basic_block bb;
block_stmt_iterator bsi; block_stmt_iterator bsi;
tree phi; tree phi;
bool saw_a_complex_value = false; bool saw_a_complex_op = false;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
...@@ -159,21 +159,62 @@ init_dont_simulate_again (void) ...@@ -159,21 +159,62 @@ init_dont_simulate_again (void)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
tree stmt = bsi_stmt (bsi); tree orig_stmt, stmt, rhs = NULL;
bool dsa = true; bool dsa = true;
if (TREE_CODE (stmt) == MODIFY_EXPR orig_stmt = stmt = bsi_stmt (bsi);
&& is_complex_reg (TREE_OPERAND (stmt, 0))) switch (TREE_CODE (stmt))
{ {
dsa = false; case RETURN_EXPR:
saw_a_complex_value = true; stmt = TREE_OPERAND (stmt, 0);
if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
break;
/* FALLTHRU */
case MODIFY_EXPR:
dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
rhs = TREE_OPERAND (stmt, 1);
break;
case COND_EXPR:
rhs = TREE_OPERAND (stmt, 0);
break;
default:
break;
} }
DONT_SIMULATE_AGAIN (stmt) = dsa; if (rhs)
switch (TREE_CODE (rhs))
{
case EQ_EXPR:
case NE_EXPR:
rhs = TREE_OPERAND (rhs, 0);
/* FALLTHRU */
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case RDIV_EXPR:
case NEGATE_EXPR:
case CONJ_EXPR:
if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
saw_a_complex_op = true;
break;
default:
break;
}
DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
} }
} }
return saw_a_complex_value; return saw_a_complex_op;
} }
...@@ -189,6 +230,8 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED, ...@@ -189,6 +230,8 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
/* These conditions should be satisfied due to the initial filter /* These conditions should be satisfied due to the initial filter
set up in init_dont_simulate_again. */ set up in init_dont_simulate_again. */
if (TREE_CODE (stmt) == RETURN_EXPR)
stmt = TREE_OPERAND (stmt, 0);
gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR); gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
lhs = TREE_OPERAND (stmt, 0); lhs = TREE_OPERAND (stmt, 0);
...@@ -308,6 +351,9 @@ create_components (void) ...@@ -308,6 +351,9 @@ create_components (void)
size_t k, n; size_t k, n;
n = num_referenced_vars; n = num_referenced_vars;
if (n == 0)
return;
complex_variable_components = VEC_alloc (tree, heap, 2*n); complex_variable_components = VEC_alloc (tree, heap, 2*n);
VEC_safe_grow (tree, heap, complex_variable_components, 2*n); VEC_safe_grow (tree, heap, complex_variable_components, 2*n);
......
...@@ -3611,9 +3611,6 @@ extern tree build_fold_indirect_ref (tree); ...@@ -3611,9 +3611,6 @@ extern tree build_fold_indirect_ref (tree);
extern tree fold_indirect_ref (tree); extern tree fold_indirect_ref (tree);
extern tree constant_boolean_node (int, tree); extern tree constant_boolean_node (int, tree);
extern tree build_low_bits_mask (tree, unsigned); extern tree build_low_bits_mask (tree, unsigned);
extern tree fold_complex_mult_parts (tree, tree, tree, tree, tree);
extern tree fold_complex_div_parts (tree, tree, tree, tree, tree,
enum tree_code);
extern bool tree_swap_operands_p (tree, tree, bool); extern bool tree_swap_operands_p (tree, tree, bool);
extern enum tree_code swap_tree_comparison (enum tree_code); extern enum tree_code swap_tree_comparison (enum tree_code);
......
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