This patch makes regcprop check HARD_REGNO_MODE_OK before creating a hard register in a different mode. It fixes a segfault in a build of bionic on ARM.
The missing check usually doesn't cause problems. The define_insn constraints are likely to reject invalid registers for "real" insns, while debug insns are often able to get away with them without triggering an ICE. It only showed up on ARM because a debug insn used (reg:SI d16), and arm_dwarf_register_span returned a zero-length parallel for this (invalid) case. The host compiler also happened not to optimise away the dead size assignment described here: http://gcc.gnu.org/ml/gcc/2011-07/msg00376.html so we would seg trying to access beyond the end of the vector. Tested on x86_64-linux-gnu and arm-linux-gnueabi. OK to install? Richard gcc/ * regcprop.c (maybe_mode_change): Check HARD_REGNO_MODE_OK. Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2011-06-22 16:46:35.000000000 +0100 +++ gcc/regcprop.c 2011-07-20 13:04:37.000000000 +0100 @@ -418,10 +418,9 @@ maybe_mode_change (enum machine_mode ori offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0) + (BYTES_BIG_ENDIAN ? byteoffset : 0)); - return gen_rtx_raw_REG (new_mode, - regno + subreg_regno_offset (regno, orig_mode, - offset, - new_mode)); + regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); + if (HARD_REGNO_MODE_OK (regno, new_mode)) + return gen_rtx_raw_REG (new_mode, regno); } return NULL_RTX; }