GCN has some registers which are special purpose, but not "fixed" because we want the register allocator to track their usage and select alternatives that use different special registers (e.g. scalar cc vs. vector cc).
Sometimes this leads the regrename pass to ICE. Quite how it gets confused is not well understood, but considering such registers for renaming is surely not useful. This patch creates a new macro SPECIAL_REGNO_P which disables regrename. In other words, the register is fixed once allocated. 2018-09-05 Kwok Cheung Yeung <k...@codesourcery.com> gcc/ * defaults.h (SPECIAL_REGNO_P): Define to false by default. * regrename.c (check_new_reg_p): Do not rename to a special register. (rename_chains): Do not rename special registers. --- gcc/defaults.h | 4 ++++ gcc/regrename.c | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/gcc/defaults.h b/gcc/defaults.h index 9035b33..40ecf61 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1198,6 +1198,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define NO_FUNCTION_CSE false #endif +#ifndef SPECIAL_REGNO_P +#define SPECIAL_REGNO_P(REGNO) false +#endif + #ifndef HARD_REGNO_RENAME_OK #define HARD_REGNO_RENAME_OK(FROM, TO) true #endif diff --git a/gcc/regrename.c b/gcc/regrename.c index 8424093..92e403e 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -320,6 +320,7 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg, if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i) || fixed_regs[new_reg + i] || global_regs[new_reg + i] + || SPECIAL_REGNO_P (new_reg + i) /* Can't use regs which aren't saved by the prologue. */ || (! df_regs_ever_live_p (new_reg + i) && ! call_used_regs[new_reg + i]) @@ -480,6 +481,7 @@ rename_chains (void) continue; if (fixed_regs[reg] || global_regs[reg] + || SPECIAL_REGNO_P (reg) || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM) || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed