On Mon, Dec 2, 2019 at 5:33 PM Richard Sandiford <richard.sandif...@arm.com> wrote: > > Even EXACT_DIV_EXPR doesn't distribute across addition for wrapping > types, so in general we can't fold EXACT_DIV_EXPRs of POLY_INT_CSTs > at compile time. This was causing an ICE when trying to gimplify the > element size field in an ARRAY_REF. > > If the result of that EXACT_DIV_EXPR is an invariant, we don't bother > recording it in the ARRAY_REF and simply read the element size from the > element type. This avoids the overhead of doing: > > /* ??? tree_ssa_useless_type_conversion will eliminate casts to > sizetype from another type of the same width and signedness. */ > if (TREE_TYPE (aligned_size) != sizetype) > aligned_size = fold_convert_loc (loc, sizetype, aligned_size); > return size_binop_loc (loc, MULT_EXPR, aligned_size, > size_int (TYPE_ALIGN_UNIT (elmt_type))); > > each time array_ref_element_size is called. > > So rather than read array_ref_element_size, do some arithmetic on it, > and only then check whether the result is an invariant, we might as > well check whether the element size is an invariant to start with. > We're then directly testing whether array_ref_element_size gives > a reusable value. > > For consistency, the patch makes the same change for the offset field > in a COMPONENT_REF, although I don't think that can trigger yet. > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
OK. Thanks, Richard. > Richard > > > 2019-12-02 Richard Sandiford <richard.sandif...@arm.com> > > gcc/ > * 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. > > gcc/testsuite/ > * gcc.target/aarch64/sve/acle/general-c/struct_1.c: New test. > > Index: gcc/gimplify.c > =================================================================== > --- gcc/gimplify.c 2019-11-22 09:57:52.178273436 +0000 > +++ gcc/gimplify.c 2019-12-02 16:32:08.063499557 +0000 > @@ -2987,17 +2987,18 @@ gimplify_compound_lval (tree *expr_p, gi > > 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, gi > /* 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, > Index: gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/struct_1.c > =================================================================== > --- /dev/null 2019-09-17 11:41:18.176664108 +0100 > +++ gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/struct_1.c > 2019-12-02 16:32:08.075499476 +0000 > @@ -0,0 +1,10 @@ > +/* { dg-options "-std=c99" } */ > + > +#include <arm_sve.h> > + > +void > +f (svint8_t a, svint8_t b) > +{ > + /* Not supported, but mustn't ICE. */ > + (svint8x2_t) { a, b }; > +}