> I suppose I was putting too much store by the expmed.c code. How does > this version look? Tested on x86_64-linux-gnu, powerpc64-linux-gnu > and cris-elf. > > Richard > > > gcc/ > PR middle-end/55438 > * expmed.c (simple_mem_bitfield_p): New function, extracted from > store_bit_field_1 and extract_bit_field_1. Use GET_MODE_ALIGNMENT > rather than bitsize when checking the alignment.
I'd mention explicitly the function: (store_bit_field_1): Call simple_mem_bitfield_p. (extract_bit_field_1): Likewise. > * stor-layout.c (bit_field_mode_iterator::bit_field_mode_iterator): > Don't limit ALIGN_. Assume that memory is mapped in chunks of at > least word size, regardless of BIGGEST_ALIGNMENT. > (bit_field_mode_iterator::get_mode): Use GET_MODE_ALIGNMENT rather > than unit when checking the alignment. > (get_best_mode): Use GET_MODE_ALIGNMENT. OK, modulo: > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c 2012-11-20 19:49:07.000000000 +0000 > +++ gcc/expmed.c 2012-11-27 17:27:38.381139339 +0000 > @@ -416,6 +416,21 @@ lowpart_bit_field_p (unsigned HOST_WIDE_ > else > return bitnum % BITS_PER_WORD == 0; > } > + > +/* Return true if OP is a memory and if a bitfield of size BITSIZE at > + bit number BITNUM can be treated as a simple value of mode MODE. */ > + > +static bool > +simple_mem_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize, > + unsigned HOST_WIDE_INT bitnum, enum machine_mode mode) > +{ > + return (MEM_P (op0) > + && bitnum % BITS_PER_UNIT == 0 > + && bitsize == GET_MODE_BITSIZE (mode) > + && (!SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0)) > + || (bitnum % GET_MODE_ALIGNMENT (mode) == 0 > + && MEM_ALIGN (op0) % GET_MODE_ALIGNMENT (mode) == 0))); > +} I think that the most idiomatic form is MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode) when it comes to alignments. -- Eric Botcazou