[Cleaning this thread up to submit patch again, with better explanation] This patch causes subreg_get_info() to exit early in the simple cases where we are extracting a whole register from a multi register. In aarch64 for Big Endian we were producing a subreg of a OImode (256bits) from a CImode (384bits) This would hit the following assert in subreg_get_info: gcc_assert ((GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)) == 0); This is a rule we should be able to relax a little - if the subreg we want fits into a whole register then this is a valid result and can be easily detected earlier in the function. This has the bonus that we should be slightly reducing the execution time for more common cases, for example a subreg of 64bits from 256bits. This patch is required for the second part of the patch, which is aarch64 specific, and fixes up aarch64 Big Endian movoi/ci/xi. This second part has already been approved. This patch will apply cleanly by itself and no regressions were seen when testing aarch64 and x86_64 on make check. Cheers, Alan Changelog: 2014-11-14 Alan Hayward * rtlanal.c (subreg_get_info): Exit early for simple and common cases --- gcc/rtlanal.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index c9bf69c..a3f7b78 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3561,6 +3561,19 @@ subreg_get_info (unsigned int xregno, machine_mode xmode, info->offset = offset / regsize_xmode; return; } + /* Quick exit for the simple and common case of extracting whole + subregisters from a multiregister value. */ + if (!rknown + && WORDS_BIG_ENDIAN == REG_WORDS_BIG_ENDIAN + && regsize_xmode == regsize_ymode + && (offset % regsize_ymode) == 0) + { + info->representable_p = true; + info->nregs = nregs_ymode; + info->offset = offset / regsize_ymode; + gcc_assert (info->offset + info->nregs <= nregs_xmode); + return; + } } /* Lowpart subregs are otherwise valid. */ -- 1.9.1