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]

[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


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