On 07/07/2023 A 12:11 am, Peter Bergner wrote:
> I believe the untested patch below should also work, without having to scan
> the (uncommonly used) options. Jeevitha, can you bootstrap and regtest the
> patch below?
Yeah Peter, Bootstrapped and regtested the below patch on powerpc64le-linux
there was no regression.
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index d197c3f3289..7c356a73ac6 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -10160,9 +10160,13 @@ rs6000_conditional_register_usage (void)
> for (i = 32; i < 64; i++)
> fixed_regs[i] = call_used_regs[i] = 1;
>
> + /* For non PC-relative code, GPR2 is unavailable for register allocation.
> */
> + if (FIXED_R2 && !rs6000_pcrel_p ())
> + fixed_regs[2] = 1;
> +
> /* The TOC register is not killed across calls in a way that is
> visible to the compiler. */
> - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
> + if (fixed_regs[2] && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
> call_used_regs[2] = 0;
>
> if (DEFAULT_ABI == ABI_V4 && flag_pic == 2)
> diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
> index 3503614efbd..2a24fbdf9fd 100644
> --- a/gcc/config/rs6000/rs6000.h
> +++ b/gcc/config/rs6000/rs6000.h
> @@ -812,7 +812,7 @@ enum data_align { align_abi, align_opt, align_both };
>
> #define FIXED_REGISTERS \
> {/* GPRs */ \
> - 0, 1, FIXED_R2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
> + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> /* FPRs */ \
> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>
>
>
>> Besides, IMHO we need a corresponding test case to cover this -ffixed-r2
>> handling.
>
> Good idea. I think we can duplicate the pr110320_2.c test case, replacing the
> -mno-pcrel option with -ffixed-r2. Jeevitha, can you give that a try?
Yeah, adding the new test cases along with the mentioned changes for the older
ones below,
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..a4ad34d9303
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320_1.c
@@ -0,0 +1,22 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_pcrel } */
+/* { 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..9d6aefedd2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320_2.c
@@ -0,0 +1,21 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_pcrel } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -mno-pcrel -ffixed-r0 -ffixed-r11
-ffixed-r12" } */
+
+/* Ensure we don't 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 only leaves RA to choose from the more
+ expensive non-volatile registers for the temporary to be assigned to. */
+
+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-not {\madd 2,3,4\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320_3.c
b/gcc/testsuite/gcc.target/powerpc/pr110320_3.c
new file mode 100644
index 00000000000..ea6c6188c8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320_3.c
@@ -0,0 +1,21 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_pcrel } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -ffixed-r2 -ffixed-r0 -ffixed-r11
-ffixed-r12" } */
+
+/* Ensure we don't 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, r2, r11 and r12. That only leaves RA to choose from the more
+ expensive non-volatile registers for the temporary to be assigned to. */
+
+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-not {\madd 2,3,4\M} } } */