While building newlib with -O2 -mips16 I ran into a problem with GCC aborting due to the compiler trying to execute '0 % 0' in mips16_unextended_reference_p. The problem was that the code checked for BLKmode and skipped the modulo operation in that case because GET_MODE_SIZE (BLKmode) is zero but it didn't check for VOIDmode whose size is also zero. Rather then add a check for VOIDmode I changed the check to 'GET_MODE_SIZE (mode) != 0'.
While looking at the code I also noticed that if offset was zero then we should return true even if mode is BLKmode or VOIDmode. Returning false would not generate bad code or cause problems but returning true would result in better costing model in mips_address_insns so I made that change too. Tested on a mips elf target, OK to checkin? Steve Ellcey sell...@mips.com 2012-09-19 Steve Ellcey <sell...@mips.com> PR target/54619 * config/mips/mips.c (mips16_unextended_reference_p): Check for zero offset and zero size mode. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7f9df4c..ecdb811 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -2230,7 +2230,10 @@ static bool mips16_unextended_reference_p (enum machine_mode mode, rtx base, unsigned HOST_WIDE_INT offset) { - if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0) + if (offset == 0) + return true; + + if (GET_MODE_SIZE (mode) != 0 && offset % GET_MODE_SIZE (mode) == 0) { if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx) return offset < 256U * GET_MODE_SIZE (mode);