This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Fix PR78458, LRA ICE building libgcc for powerpc-linux-gnuspe e500v2


PR78458 shows a problem in LRA spilling caused by HARD_REGNO_CALLER_SAVE_MODE()
returning a bogus mode (IFmode).  This patch solves the problem by just
returning MODE if MODE is wide enough to save and restore NREGS itself.

This patch passed bootstrap and regtesting on powerpc64le-linux as well
as on powerpc64-linux (testsuite run in both 32-bit and 64-bit modes).
Joseph has confirmed it fixes his ICE and gets him further in his toolchain
build (now ICEs in glibc), which he has separate patches for.

Joseph, I copied the testsuite preamble from another SPE test case.
Does it look correct to you to catch the bug?

Assuming the test case is correct, is this ok for trunk?

Peter


gcc/
	PR target/78458
	* config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Return MODE
	if it is at least NREGS wide.

gcc/testsuite/
	PR target/78458
	* gcc.target/powerpc/pr78458.c: New.

Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 241976)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -1279,9 +1279,11 @@ enum data_align { align_abi, align_opt,
    enough space to account for vectors in FP regs.  However, TFmode/TDmode
    should not use VSX instructions to do a caller save. */
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE)			\
-  (TARGET_VSX								\
-   && ((MODE) == VOIDmode || ALTIVEC_OR_VSX_VECTOR_MODE (MODE))		\
-   && FP_REGNO_P (REGNO)						\
+  (NREGS <= rs6000_hard_regno_nregs[MODE][REGNO]			\
+   ? MODE								\
+   : TARGET_VSX								\
+     && ((MODE) == VOIDmode || ALTIVEC_OR_VSX_VECTOR_MODE (MODE))	\
+     && FP_REGNO_P (REGNO)						\
    ? V2DFmode								\
    : TARGET_E500_DOUBLE && (MODE) == SImode				\
    ? SImode								\
Index: gcc/testsuite/gcc.target/powerpc/pr78458.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78458.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78458.c	(working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=8548 -mspe -mabi=spe -mlra" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
+
+extern void bar (void);
+long double
+pr78458 (long double p1)
+{
+  bar ();
+  asm volatile ("# clobbers" :::
+		"r14", "r15", "r16", "r17", "r18", "r19",
+		"r20", "r21", "r22", "r23", "r24", "r25",
+		"r26", "r27", "r28", "r29", "r30", "r31");
+  return p1;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]