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]

Fix PR target/10904 and PR target/13058


The PRs are about failures caused by the inability for the compiler to 
enforce FP register alignment on SPARC64, that is to make sure that an 
odd-numbered FP register is not used where an even-numbered is required.

As Andrew pointed out, the docs contain these very explicit lines
"  When a value occupying several consecutive registers is expected in a
certain class, all the registers used must belong to that class.
Therefore, register classes cannot be used to enforce a requirement for
a register pair to start with an even-numbered register.  The way to
specify this requirement is with `HARD_REGNO_MODE_OK'."

HARD_REGNO_MODE_OK is already correct on SPARC64, so there is a hole 
somewhere.  It turns out that both failures are related to SI:DI paradoxical 
subregs whose inner reg is assigned to a FP reg: the register allocator 
fails to recognize that this subregization introduces a new alignment 
constraint on SPARC64.

Andrew and I explored various (intrusive) ways to solve the problem.  Now 
Richard recently pointed out that PA64 has the same alignment requirement 
for its FP regs, and it doesn't seem to be affected by the problem.

The reason is simple: PA64 forbids the subregization of SI mode values in FP 
regs with CANNOT_CHANGE_MODE_CLASS.  According to the comment, the rationale 
is that LOAD_EXTEND_OP is not valid for FP regs, so SI->DI extension is not 
allowed for FP regs (DImode == word_mode).

It turns out that this rationale applies to SPARC64 for the lower FP regs 
(the upper FP regs can't hold SImode value), so borrowing the whole C_C_M_C 
macro from PA64 makes sense.  And of course solves the two PRs :-)


Bootstrapped/regtested on sparc64-sun-solaris2.9 (3.4 branch, except Ada), 
applied to mainline and 3.4 branch (PR target/13058 is a regression).


2004-01-27  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR target/10904
	PR target/13058
	* config/sparc/sparc.h (CANNOT_CHANGE_MODE_CLASS): New.
	Forbid mode changes from SImode for lower FP regs if ARCH64.


2004-01-27  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.dg/20040127-1.c: New test.
	* gcc.dg/20040127-2.c: New test.


-- 
Eric Botcazou
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.236
diff -u -p -r1.236 sparc.h
--- config/sparc/sparc.h	9 Nov 2003 14:05:10 -0000	1.236
+++ config/sparc/sparc.h	26 Jan 2004 15:03:49 -0000
@@ -1264,6 +1264,20 @@ enum reg_class { NO_REGS, FPCC_REGS, I64
    {-1, -1, -1, 0x20},	/* GENERAL_OR_EXTRA_FP_REGS */	\
    {-1, -1, -1, 0x3f}}	/* ALL_REGS */
 
+/* Defines invalid mode changes.  Borrowed from pa64-regs.h.
+
+   SImode loads to floating-point registers are not zero-extended.
+   The definition for LOAD_EXTEND_OP specifies that integer loads
+   narrower than BITS_PER_WORD will be zero-extended.  As a result,
+   we inhibit changes from SImode unless they are to a mode that is
+   identical in size.  */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
+  (TARGET_ARCH64						\
+   && (FROM) == SImode						\
+   && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)		\
+   ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
/* PR target/10904 */
/* Origin: <kminola@eng.umd.edu> */

/* Verify that the register allocator correctly aligns
   floating-point registers on SPARC64.  */

/* { dg-do assemble } */
/* { dg-options "-O2" } */

extern int foo1();
extern int foo2();

void foo(int n, int b)
{
  int i, a;

  foo1();

  a = (long)(b * ((double) 0.1));

  for (i=0; i < n; i++) {
    foo2(a);
  }
}
/* PR target/13058 */
/* Origin: Lloyd Parkes <lloyd@must-have-coffee.gen.nz> */
/* Reduced testcase by  Falk Hueffner <falk@debian.org> */

/* Verify that the register allocator correctly aligns
   floating-point registers on SPARC64.  */

/* { dg-do compile } */
/* { dg-options "-O" } */

typedef struct { int ThumbnailSize; } ImageInfo_t;

double ConvertAnyFormat(void)
{
  return 0;
}

void ProcessExifDir(ImageInfo_t *ImageInfoP, int NumDirEntries)
{
  unsigned int ThumbnailSize;

  for (; NumDirEntries;) {
    Get16u();
    switch (NumDirEntries) {
      case 0x0201:
      case 0x0202:
        ThumbnailSize = ConvertAnyFormat();
    }
  }

  ImageInfoP->ThumbnailSize = ThumbnailSize;
}

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