Make regcprop check HARD_REGNO_MODE_OK

Richard Sandiford richard.sandiford@linaro.org
Wed Jul 20 14:16:00 GMT 2011


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;
 }



More information about the Gcc-patches mailing list