https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109495

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
In store_field we run into

  /* If the structure is in a register or if the component
     is a bit field, we cannot use addressing to access it.
     Use bit-field techniques or SUBREG to store in it.  */

because

      /* If the RHS and field are a constant size and the size of the
         RHS isn't the same size as the bitfield, we must use bitfield
         operations.  */
      || (known_size_p (bitsize)
          && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
          && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
                       bitsize)

as bitsize == 524312 and TYPE_SIZE == 524320 (we have a COMPONENT_REF
here and the size of the FIELD_DECL is 524312!)

and since !TREE_ADDRESSABLE we're happily oblieging here.

And then we proceed with

      temp = expand_normal (exp);

which results in a copy on the stack.

I wonder why we should ever, for smaller bitsize, use a copy here, when
bitsize/bitpos is a multiple of BITS_PER_UNIT?  In particular I don't
understand why we need TREE_ADDRESSABLE to let a proper COMPONENT_REF
through?

          /* And except for bitwise copying of TREE_ADDRESSABLE types,
             where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
             includes some extra padding.  store_expr / expand_expr will in
             that case call get_inner_reference that will have the bitsize
             we check here and thus the block move will not clobber the
             padding that shouldn't be clobbered.  In the future we could
             replace the TREE_ADDRESSABLE check with a check that
             get_base_address needs to live in memory.  */
          && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
              || TREE_CODE (exp) != COMPONENT_REF
              || !multiple_p (bitsize, BITS_PER_UNIT)
              || !multiple_p (bitpos, BITS_PER_UNIT)
              || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
                                   &decl_bitsize)
              || maybe_ne (decl_bitsize, bitsize))

removing the !TREE_ADDRESSABLE check fixes the testcase.

Reply via email to