https://gcc.gnu.org/g:beb07e21e70fceee2cdf6c7bc5e880836a875d69
commit beb07e21e70fceee2cdf6c7bc5e880836a875d69 Author: Michael Meissner <meiss...@linux.ibm.com> Date: Thu May 23 20:35:49 2024 -0400 Restrict SPR registers to only use integer modes. 2024-05-23 Michael Meissner <meiss...@linux.ibm.com> gcc/ * config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Restrict VRSAVE and VSCR to only hold hold SImode. Restrict LR and CTR to only hold SImode or DImode, based on the address size. Diff: --- gcc/config/rs6000/rs6000.cc | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index c5c4191127e..87861164b07 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1851,9 +1851,13 @@ static int rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode) { int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1; + bool orig_complex_p = false; if (COMPLEX_MODE_P (mode)) - mode = GET_MODE_INNER (mode); + { + mode = GET_MODE_INNER (mode); + orig_complex_p = true; + } /* Vector pair modes need even/odd VSX register pairs. Only allow vector registers. */ @@ -1935,6 +1939,24 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode) if (CA_REGNO_P (regno)) return mode == Pmode || mode == SImode; + /* Restrict SPR registers to only hold the integer mode natural for the + SPR. */ + switch (regno) + { + /* 32-bit registers. */ + case VRSAVE_REGNO: + case VSCR_REGNO: + return (!orig_complex_p && mode == SImode); + + /* Registers that hold addresses. */ + case LR_REGNO: + case CTR_REGNO: + return (!orig_complex_p && mode == Pmode); + + default: + break; + } + /* AltiVec only in AldyVec registers. */ if (ALTIVEC_REGNO_P (regno)) return (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)