diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b246171d468..430aedbcb052 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-12-03 Richard Sandiford + + * gimplify.c (gimplify_compound_lval): Don't gimplify and install + an array element size if array_element_size is already an invariant. + Similarly don't gimplify and install a field offset if + component_ref_field_offset is already an invariant. + 2019-12-03 Richard Sandiford * cfgexpand.c (discover_nonconstant_array_refs_r): If an access diff --git a/gcc/gimplify.c b/gcc/gimplify.c index da6566903e07..9073680cb317 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2987,17 +2987,18 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, if (TREE_OPERAND (t, 3) == NULL_TREE) { - tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); - tree elmt_size = unshare_expr (array_ref_element_size (t)); - tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); - - /* Divide the element size by the alignment of the element - type (above). */ - elmt_size - = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor); - + tree elmt_size = array_ref_element_size (t); if (!is_gimple_min_invariant (elmt_size)) { + elmt_size = unshare_expr (elmt_size); + tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); + tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); + + /* Divide the element size by the alignment of the element + type (above). */ + elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, + elmt_size, factor); + TREE_OPERAND (t, 3) = elmt_size; tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p, is_gimple_reg, @@ -3017,16 +3018,18 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* Set the field offset into T and gimplify it. */ if (TREE_OPERAND (t, 2) == NULL_TREE) { - tree offset = unshare_expr (component_ref_field_offset (t)); - tree field = TREE_OPERAND (t, 1); - tree factor - = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); - - /* Divide the offset by its alignment. */ - offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor); - + tree offset = component_ref_field_offset (t); if (!is_gimple_min_invariant (offset)) { + offset = unshare_expr (offset); + tree field = TREE_OPERAND (t, 1); + tree factor + = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); + + /* Divide the offset by its alignment. */ + offset = size_binop_loc (loc, EXACT_DIV_EXPR, + offset, factor); + TREE_OPERAND (t, 2) = offset; tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, is_gimple_reg, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 028755bb51a8..39e8ace59f79 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-12-03 Richard Sandiford + + * gcc.target/aarch64/sve/acle/general-c/struct_1.c: New test. + 2019-12-03 Richard Sandiford * gcc.target/aarch64/sve/acle/general/deref_1.c: New test. diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/struct_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/struct_1.c new file mode 100644 index 000000000000..1ebc229250eb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/struct_1.c @@ -0,0 +1,10 @@ +/* { dg-options "-std=c99" } */ + +#include + +void +f (svint8_t a, svint8_t b) +{ + /* Not supported, but mustn't ICE. */ + (svint8x2_t) { a, b }; +}