This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[power7-meissner] Fix PR 39457
- From: Michael Meissner <meissner at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 13 Mar 2009 16:15:19 -0400
- Subject: [power7-meissner] Fix PR 39457
This patch reverts to the old behavior of allowing floating point values in the
LR/CTR registers, and adds an undocumented switch for debugging the new change.
[gcc]
2009-03-13 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/39457
* config/rs6000/rs6000.opt (-mdisallow-float-in-lr-ctr): Add
temporary debug switch.
* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Revert
behavior of disallowing
[gcc/target]
2009-03-13 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/39457
* gcc.target/powerpc/pr39457.c: New test.
Index: gcc/testsuite/gcc.target/powerpc/pr39457.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr39457.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr39457.c (revision 0)
@@ -0,0 +1,56 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-options "-m64 -O2 -mminimal-toc" } */
+
+/* PR 39457 -- fix breakage because the compiler ran out of registers and
+ wanted to stash a floating point value to the LR/CTR register. */
+
+/* -O2 -m64 -mminimal-toc */
+typedef struct { void *s; } S;
+typedef void (*T1) (void);
+typedef void (*T2) (void *, void *, int, void *);
+char *fn1 (const char *, ...);
+void *fn2 (void);
+int fn3 (char *, int);
+int fn4 (const void *);
+int fn5 (const void *);
+long fn6 (void) __attribute__ ((__const__));
+int fn7 (void *, void *, void *);
+void *fn8 (void *, long);
+void *fn9 (void *, long, const char *, ...);
+void *fn10 (void *);
+long fn11 (void) __attribute__ ((__const__));
+long fn12 (void *, const char *, T1, T2, void *);
+void *fn13 (void *);
+long fn14 (void) __attribute__ ((__const__));
+extern void *v1;
+extern char *v2;
+extern int v3;
+
+void
+foo (void *x, char *z)
+{
+ void *i1, *i2;
+ int y;
+ if (v1)
+ return;
+ v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0);
+ y = 520 - (520 - fn4 (x)) / 2;
+ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0,
+ "y", 16.0, "wid", 80.0, "hi", 500.0, 0);
+ fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2",
+ 500.0, "f", fn3 ("fff", 0x0D0DFA00), 0);
+ fn13 (((S *) fn8 (v1, fn6 ()))->s);
+ fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ()));
+ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig",
+ fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi",
+ 500.0, 0);
+ v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2",
+ 500.0, "f", fn3 ("gc", 0x0D0DFA00), 0);
+ fn1 (z, 0);
+ i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x",
+ 800 - fn5 (x) / 2, "y", y - fn4 (x), 0);
+ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/");
+ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0);
+ i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x",
+ 800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0);
+}
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt (revision 144843)
+++ gcc/config/rs6000/rs6000.opt (working copy)
@@ -139,6 +139,9 @@ mvsx-scalar-memory
Target Report Var(TARGET_VSX_SCALAR_MEMORY)
If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default)
+mdisallow-float-in-lr-ctr
+Target Undocumented Var(TARGET_DISALLOW_FLOAT_IN_LR_CTR)
+
mupdate
Target Report Var(TARGET_UPDATE) Init(1)
Generate load/store with update instructions
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 144843)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -1448,10 +1448,15 @@ rs6000_hard_regno_mode_ok (int regno, en
if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
return 1;
- /* Don't allow anything but word sized integers (aka pointers) in CTR/LR. You
- really don't want to spill your floating point values to those
- registers. Also do it for the old MQ register in the power. */
- if (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO)
+ /* Don't allow anything but word sized integers (aka pointers) in CTR/LR.
+ You really don't want to spill your floating point values to those
+ registers. Also do it for the old MQ register in the power.
+
+ While this is desirable in theory, disabling float to go in LR/CTR does
+ cause some regressions, so until they are taken care of, revert to the old
+ behavior by default. */
+ if (TARGET_DISALLOW_FLOAT_IN_LR_CTR
+ && (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO))
return (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_SIZE (mode) <= UNITS_PER_WORD);
--
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com