Hi Jeevitha, on 2023/6/24 00:49, P Jeevitha wrote: > Hi All, > > The following patch has been bootstrapped and regtested on powerpc64le-linux. > > Normally, GPR2 is the TOC pointer and is defined as a fixed and non-volatile > register. However, it can be used as volatile for PCREL addressing. Therefore, > if the code is PCREL and the user is not explicitly requesting TOC addressing, > then the register r2 can be changed to volatile and non-fixed register. > Changes > in register preservation roles can be accomplished with the help of available > target hooks (TARGET_CONDITIONAL_REGISTER_USAGE).
Nice, thanks for improving this. > > 2023-06-23 Jeevitha Palanisamy <jeevi...@linux.ibm.com> > > gcc/ > PR target/PR110320 > * config/rs6000/rs6000.cc (rs6000_conditional_register_usage): Change > GPR2 to volatile and non-fixed register for pc-relative code. > > gcc/testsuite/ > PR target/PR110320 > * gcc.target/powerpc/pr110320_1.c: New testcase. > * gcc.target/powerpc/pr110320_2.c: New testcase. > > diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc > index 546c353029b..9e978f85f9d 100644 > --- a/gcc/config/rs6000/rs6000.cc > +++ b/gcc/config/rs6000/rs6000.cc > @@ -10169,6 +10169,35 @@ rs6000_conditional_register_usage (void) > if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) > call_used_regs[2] = 0; > > + /* The TOC register is not needed for functions using the PC-relative ABI > + extension, so make it available for register allocation as a volatile > + register. */ > + if (FIXED_R2 && rs6000_pcrel_p ()) > + { > + bool cli_fixedr2 = false; > + > + /* Verify the user has not explicitly asked for GPR2 to be fixed. */ > + if (common_deferred_options) > + { > + unsigned int idx; > + cl_deferred_option *opt; > + vec<cl_deferred_option> v; > + v = *((vec<cl_deferred_option> *) common_deferred_options); > + FOR_EACH_VEC_ELT (v, idx, opt) > + if (opt->opt_index == OPT_ffixed_ && strcmp (opt->arg,"r2") == 0) > + { > + cli_fixedr2 = true; > + break; > + } > + } I think the reason why we need to check common_deferred_options is at this time we can't distinguish the fixed_regs[2] is from the initialization or command line user explicit specification. But could we just update the FIXED_REGISTERS without FIXED_R2 and set FIXED_R2 when it's needed in this function instead? Then I'd expect that when we find fixed_regs[2] is set at the beginning of this function, it would mean users specify it explicitly and then we don't need this option checking? Besides, IMHO we need a corresponding test case to cover this -ffixed-r2 handling. > + > + /* If GPR2 is not FIXED (eg, not a TOC register), then it is volatile. > */ > + if (!cli_fixedr2) > + { > + fixed_regs[2] = 0; > + call_used_regs[2] = 1; > + } > + } > if (DEFAULT_ABI == ABI_V4 && flag_pic == 2) > fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; > > diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320_1.c > b/gcc/testsuite/gcc.target/powerpc/pr110320_1.c > new file mode 100644 > index 00000000000..42143fbf889 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr110320_1.c > @@ -0,0 +1,23 @@ > +/* PR target/110320 */ > +/* { dg-require-effective-target power10_ok } */ > +/* { dg-require-effective-target powerpc_pcrel } */ Do we have some environment combination which supports powerpc_pcrel but not power10_ok? I'd expect that only powerpc_pcrel is enough. > +/* { dg-options "-O2 -mdejagnu-cpu=power10 -ffixed-r0 -ffixed-r11 > -ffixed-r12" } */ > + > +/* Ensure we use r2 as a normal volatile register for the code below. > + The test case ensures all of the parameter registers r3 - r10 are used > + and needed after we compute the expression "x + y" which requires a > + temporary. The -ffixed-r* options disallow using the other volatile > + registers r0, r11 and r12. That leaves RA to choose from r2 and the more > + expensive non-volatile registers for the temporary to be assigned to, and > + RA will always chooses the cheaper volatile r2 register. */ > + > +extern long bar (long, long, long, long, long, long, long, long *); > + > +long > +foo (long r3, long r4, long r5, long r6, long r7, long r8, long r9, long > *r10) > +{ > + *r10 = r3 + r4; > + return bar (r3, r4, r5, r6, r7, r8, r9, r10); > +} > + > +/* { dg-final { scan-assembler {\madd 2,3,4\M} } } */ > diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320_2.c > b/gcc/testsuite/gcc.target/powerpc/pr110320_2.c > new file mode 100644 > index 00000000000..9d0da5b9695 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr110320_2.c > @@ -0,0 +1,22 @@ > +/* PR target/110320 */ > +/* { dg-require-effective-target power10_ok } */ > +/* { dg-require-effective-target powerpc_pcrel } */ Ditto. The others look good to me, thanks! BR, Kewen