diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5529b17927a..891c37c3f84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-01-03 Andrew Pinski + + PR middle-end/20353 + * gimplify.c (gimplify_modify_expr_complex_part): Move below + tree_to_gimple_tuple. Call tree_to_gimple_tuple when we need + the value. + 2007-01-03 Kazu Hirata * config/i386/i386.h (NON_STACK_REG_P, REGNO_OK_FOR_SIREG_P, diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 1876f64808a..d14e01e8202 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3467,46 +3467,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, return ret; } -/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is - a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with - DECL_GIMPLE_REG_P set. */ - -static enum gimplify_status -gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value) -{ - enum tree_code code, ocode; - tree lhs, rhs, new_rhs, other, realpart, imagpart; - - lhs = GENERIC_TREE_OPERAND (*expr_p, 0); - rhs = GENERIC_TREE_OPERAND (*expr_p, 1); - code = TREE_CODE (lhs); - lhs = TREE_OPERAND (lhs, 0); - - ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; - other = build1 (ocode, TREE_TYPE (rhs), lhs); - other = get_formal_tmp_var (other, pre_p); - - realpart = code == REALPART_EXPR ? rhs : other; - imagpart = code == REALPART_EXPR ? other : rhs; - - if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart)) - new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart); - else - new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart); - - GENERIC_TREE_OPERAND (*expr_p, 0) = lhs; - GENERIC_TREE_OPERAND (*expr_p, 1) = new_rhs; - - if (want_value) - { - append_to_statement_list (*expr_p, pre_p); - *expr_p = rhs; - } - - return GS_ALL_DONE; -} - - /* Destructively convert the TREE pointer in TP into a gimple tuple if appropriate. */ @@ -3553,6 +3513,47 @@ tree_to_gimple_tuple (tree *tp) } } +/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is + a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with + DECL_GIMPLE_REG_P set. */ + +static enum gimplify_status +gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value) +{ + enum tree_code code, ocode; + tree lhs, rhs, new_rhs, other, realpart, imagpart; + + lhs = GENERIC_TREE_OPERAND (*expr_p, 0); + rhs = GENERIC_TREE_OPERAND (*expr_p, 1); + code = TREE_CODE (lhs); + lhs = TREE_OPERAND (lhs, 0); + + ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; + other = build1 (ocode, TREE_TYPE (rhs), lhs); + other = get_formal_tmp_var (other, pre_p); + + realpart = code == REALPART_EXPR ? rhs : other; + imagpart = code == REALPART_EXPR ? other : rhs; + + if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart)) + new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart); + else + new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart); + + GENERIC_TREE_OPERAND (*expr_p, 0) = lhs; + GENERIC_TREE_OPERAND (*expr_p, 1) = new_rhs; + + if (want_value) + { + tree_to_gimple_tuple (expr_p); + + append_to_statement_list (*expr_p, pre_p); + *expr_p = rhs; + } + + return GS_ALL_DONE; +} + /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P. modify_expr diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7f252b62646..954e876a730 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-01-03 Andrew Pinski + + PR middle-end/30353 + * gcc.c-torture/compile/complex-4.c: New test. + 2007-01-03 Joseph Myers * g++.dg/vect/vect.exp: Skip PowerPC targets not supporting diff --git a/gcc/testsuite/gcc.c-torture/compile/complex-4.c b/gcc/testsuite/gcc.c-torture/compile/complex-4.c new file mode 100644 index 00000000000..cf100290313 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/complex-4.c @@ -0,0 +1,9 @@ +/* This used to ICE because gimplify_modify_expr_complex_part was not + updated for the GIMPLE_MODIFY_EXPR changes in that calling + tree_to_gimple_tuple was needed. */ + +void f(void) +{ + double _Complex Res; + __real__ Res = __imag__ Res = 0.0; +}