Hi, On Sat, 14 Mar 2015 13:24:33, Mikael Pettersson wrote: > > Bernd Edlinger writes: >> Hi, >> >> are there any more comments on this? >> >> I would like to apply the patch as is, unless we find a >> a way to get to a test case, maybe with a cross-compiler, >> where the MODE_ALIGNMENT is different from MODE_BITSIZE. >> >> Currently, I think that does not happen. > > On m68k-linux GET_MODE_ALIGNMENT (SImode) == 16 while > GET_MODE_BITSIZE (SImode) == 32. > > I don't know what that means for your patch, just wanted > to inform you that such targets do exist. >
Oh I see, thanks. This is due to BIGGEST_ALIGNMENT=16, STRICT_ALIGNMENT=1 by default on that architecture. If I change this check as suggested: if (bitnum % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (fieldmode) : BITS_PER_UNIT) + bitsize> modesize || (STRICT_ALIGNMENT && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (fieldmode))) return false; Then I can get the assertion failed in store_bit_field: gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (fieldmode)); With this example: cat test.c struct s { short y:16; int x:31; }; void f(volatile struct s* z, int x) { z->x=x; } m68k-elf-gcc -fstrict-volatile-bitfields -mstrict-align -mno-align-int -O2 -S test.c test.c: In function 'f': test.c:10:7: internal compiler error: in store_bit_field, at expmed.c:1005 z->x=x; ^ what I said before.., without the patch the test case generates just invalid code which assigns only 16 bits. There is also a problem in this check. I had to make short y:16 a bit filed to bypass that, initially I wrote short y; /* Check for cases where the C++ memory model applies. */ if (bitregion_end != 0 && (bitnum - bitnum % modesize < bitregion_start || bitnum - bitnum % modesize + modesize - 1> bitregion_end)) return false; This assumes also that the access is at a modesize boundary. If we have BIGGEST_ALIGNMENT=16 that means we have likely a 16 bit architecture. I doubt that the strict alignment code makes any sense for modesize> BIGGEST_ALIGNMENT. I think I should change this check /* The bit size must not be larger than the field mode, and the field mode must not be larger than a word. */ if (bitsize> modesize || modesize> BITS_PER_WORD) return false; to this: if (bitsize> modesize || modesize> BITS_PER_WORD || modesize> BIGGEST_ALIGNMENT) return false; This should avoid these oddities. Bernd.