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, alpha]: Fix all struct-layout-1 failures


Hello!

So, the problem here was not with missing -mieee flag in the testcases, but with the way alpha compiler handles HIGH/LO_SUM combos when loading immediates that are bigger than word_size.

An example from failed tests is when TFmode long double 128bit immediate is loaded via:

   ldah $1,$LC611($29)        !gprelhigh
   ldq $2,$LC611+8($1)        !gprellow
   ldq $1,$LC611($1)        !gprellow

The problem is with +8 explicit reloc, when relocation is exactly 32760 bytes away. Linker then creates:

0x0000000120028da4 <test2141+1768>:     ldah    t0,-3(gp)
0x0000000120028da8 <test2141+1772>:     ldq     t1,-32768(t0)
0x0000000120028dac <test2141+1776>:     ldq     t0,32760(t0)

As can be seen from this example, lo_sum offset of $LABEL+8 folds around to a negative offset.

Disabling explicit relocs for immediates wider than word_mode fixes this problem:

   ldah $1,$LC0($29)        !gprelhigh
   lda $1,$LC0($1)        !gprellow
   ldq $9,0($1)
   ldq $10,8($1)

2009-01-10 Uros Bizjak <ubizjak@gmail.com>

   * config/alpha/alpha.c (alpha_legitimate_address_p): Explicit
   relocations of local symbols  wider than UNITS_PER_WORD are not valid.
   (alpha_legitimize_address): Do not split local symbols wider than
   UNITS_PER_WORD into HIGH/LO_SUM parts.

testsuite/ChangeLog:

2009-01-10 Uros Bizjak <ubizjak@gmail.com>

   Revert:
   2009-01-05  Uros Bizjak  <ubizjak@gmail.com>

   * gcc.dg/compat/struct-layout-1_generate.c (dg-options): Add -mieee
   for alpha*-*-* targets.
   * g++.dg/compat/struct-layout-1_generate.c (dg-options): Ditto.

Attached patch was bootstrapped and regression tested on alphaev56-pc-linux-gnu, -mlong-double-128 -mexplicit-reloc target. This patch fixes all struct-layout-1 failures.

OK for mainline?

Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 143247)
+++ config/alpha/alpha.c	(working copy)
@@ -864,9 +864,11 @@ alpha_legitimate_address_p (enum machine
 	}
     }
 
-  /* If we're managing explicit relocations, LO_SUM is valid, as
-     are small data symbols.  */
-  else if (TARGET_EXPLICIT_RELOCS)
+  /* If we're managing explicit relocations, LO_SUM is valid, as are small
+     data symbols.  Avoid explicit relocations in modes larger than word
+     mode since i.e. $LC0+8($1) can fold around +/- 32k offset.  */
+  else if (TARGET_EXPLICIT_RELOCS
+	   && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
     {
       if (small_symbolic_operand (x, Pmode))
 	return true;
@@ -916,8 +918,7 @@ get_tls_get_addr (void)
    to be legitimate.  If we find one, return the new, valid address.  */
 
 rtx
-alpha_legitimize_address (rtx x, rtx scratch,
-			  enum machine_mode mode ATTRIBUTE_UNUSED)
+alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode)
 {
   HOST_WIDE_INT addend;
 
@@ -965,8 +966,12 @@ alpha_legitimize_address (rtx x, rtx scr
       goto split_addend;
     }
 
-  /* If this is a local symbol, split the address into HIGH/LO_SUM parts.  */
-  if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
+  /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
+     Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
+     around +/- 32k offset.  */
+  if (TARGET_EXPLICIT_RELOCS
+      && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+      && symbolic_operand (x, Pmode))
     {
       rtx r0, r16, eqv, tga, tp, insn, dest, seq;
 
Index: testsuite/gcc.dg/compat/struct-layout-1_generate.c
===================================================================
--- testsuite/gcc.dg/compat/struct-layout-1_generate.c	(revision 143247)
+++ testsuite/gcc.dg/compat/struct-layout-1_generate.c	(working copy)
@@ -48,8 +48,7 @@ const char *dg_options[] = {
 "/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
 "/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
 "/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n"
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
 #define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
 };
 
Index: testsuite/g++.dg/compat/struct-layout-1_generate.c
===================================================================
--- testsuite/g++.dg/compat/struct-layout-1_generate.c	(revision 143247)
+++ testsuite/g++.dg/compat/struct-layout-1_generate.c	(working copy)
@@ -48,8 +48,7 @@ const char *dg_options[] = {
 "/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
 "/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
 "/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n"
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
 #define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
 };
 

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