Message ID | g4ipqxukrj.fsf@linaro.org |
---|---|
State | New |
Headers | show |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 07/20/11 07:47, Richard Sandiford wrote: > 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. OK. Jeff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJOJuFqAAoJEBRtltQi2kC7LnkH+wbkbNYXRN+1ew8lh49m80HO SAx2lC3eyMXuR581lwG4vT7HBx9rLfJ/5s+smeAr8Vo80+raN2PkST/f2Vj5WKDg O0NSqha/Zw4QLSDJ7XApg2Fi/MHZ+z71kFXXb8Ko9KPHMMhVlwxbnE7Jn3QcRpAQ s9BgNtT0RHzS3zdnmjnbSEFGKDj9K3DNuw0Vp0+mJV6pGh+ljI7uFUJh4QI3pywj uqzQVsKXVtsb7lx7rXlVdCuvf+4fYMSdOPq92BBes4s0CtgyN0HEy6ihpd4qj2aq GLbvM9sTIyOicpzWNs8cBCXWPMRKvR7si5gr7jZms2Oa3si3JMyqV58HAn+Z3Tk= =JXtm -----END PGP SIGNATURE-----
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; }