Bug 52530 - [4.8 regression] Many 64-bit execution failures on Solaris 10/11 with Sun as
Summary: [4.8 regression] Many 64-bit execution failures on Solaris 10/11 with Sun as
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Uroš Bizjak
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-08 12:56 UTC by Rainer Orth
Modified: 2012-08-01 19:15 UTC (History)
2 users (show)

See Also:
Host: i386-pc-solaris2.1[01]
Target: i386-pc-solaris2.1[01]
Build: i386-pc-solaris2.1[01]
Known to work:
Known to fail:
Last reconfirmed: 2012-03-09 00:00:00


Attachments
Patch that introduces %E modifier (2.09 KB, patch)
2012-03-09 17:08 UTC, Uroš Bizjak
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2012-03-08 12:56:01 UTC
Between 20120302 and 20120307, many 64-bit execution tests all over the testsuite
started to fail on Solaris 10 and 11/x86 when using Sun as.  With gas, all is fine.

E.g.

FAIL: gcc.c-torture/execute/20021120-1.c execution,  -O3 -fomit-frame-pointer -funroll-loops

The test aborts, and can be reproduced with -m64 -O1 -funroll-loops.  If I add
printf's to investigate the failure (gdb cannot print optimized-out values here),
the failure vanishes.

Between .s files for as and gas, there are no codegen differences when using
-fno-dwarf2-cfi-asm.

When I compare the 4.7 and mainline .s files with as, I find lots of changes
like

--- 20021120-1.s        2012-03-08 13:00:25.054484596 +0100
+++ /var/gcc/regression/trunk/10-gcc/build/gcc/testsuite/gcc/20021120-1.s
2012-03-08 12:48:21.890112842 +0100
@@ -534,37 +534,37 @@
        movsd   %xmm2, gd(,%rcx,8)
        cvtsi2ss        %eax, %xmm3
        movss   %xmm3, gf(,%rcx,4)
-       leal    1(%rax), %edi
+       leal    1(%eax), %edi
        cvtsi2sd        %edi, %xmm4
        movslq  %edi, %r8
        movsd   %xmm4, gd(,%r8,8)

A reghunt revealed that this was caused by this patch:

2012-03-04  H.J. Lu  <hongjiu.lu@intel.com>

       * config/i386/i386.c (ix86_print_operand_address): Only handle
       zero-extended DImode addresses.

I'm now trying another bootstrap with this change reverted to see if this fixes
all the failures.

  Rainer
Comment 1 Uroš Bizjak 2012-03-08 13:49:52 UTC
Ouch.

Before the change, we always used "q" modifier for addresses, only in two special cases we emitted "l". This "q" modifier forced DImode address even for SImode operands, avoiding addr32 prefixes.

The change - while correct - cancelled this optimization.

So, please revert this patch ASAP.

Also, Sun is buggy in the way addr32 prefix is handled.
Comment 2 H.J. Lu 2012-03-08 15:06:32 UTC
(In reply to comment #1)
> Ouch.
> 
> Before the change, we always used "q" modifier for addresses, only in two
> special cases we emitted "l". This "q" modifier forced DImode address even for
> SImode operands, avoiding addr32 prefixes.
> 
> The change - while correct - cancelled this optimization.
> 
> So, please revert this patch ASAP.
> 

Uros, can you revert it for me? Thanks.
Comment 3 uros 2012-03-08 15:19:36 UTC
Author: uros
Date: Thu Mar  8 15:19:32 2012
New Revision: 185103

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185103
Log:
	PR target/52530
	Revert:
	2012-03-04  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/i386.c (ix86_print_operand_address): Only handle
	zero-extended DImode addresses.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
Comment 4 Uroš Bizjak 2012-03-08 18:16:21 UTC
Fixed by revert.
Comment 5 Uroš Bizjak 2012-03-09 14:55:18 UTC
However, there is a problem with Pmode != DImode. Consider following test:

struct foo
{
  int *f;
  int i;
};

void
__attribute__ ((noinline))
bar (struct foo x)
{
  *(x.f) = 1;
}

This will compile with -mx32 to:

bar:
       movl    $1, (%rdi)
       ret

which is wrong.

The move is:

#(insn:TI 6 3 13 2 (set (mem:SI (reg:SI 5 di [orig:60 x ] [60]) [4 *D.1704_1+0 S4 A32])
#        (const_int 1 [0x1])) ptr.c:11 64 {*movsi_internal}
#     (expr_list:REG_DEAD (reg:SI 5 di [orig:60 x ] [60])
#        (nil)))
        movl    $1, (%rdi)      # 6     *movsi_internal/2       [length = 6]

So we want to output address in SImode, while avoiding addr32 prefixes for LEAs.

The patch from H.J. should be applied and LEAs should be fixed.
Comment 6 H.J. Lu 2012-03-09 15:17:07 UTC
This patch works for me:

---
diff --git a/gcc/ChangeLog.addr32 b/gcc/ChangeLog.addr32
index 066f1ec..a191e47 100644
--- a/gcc/ChangeLog.addr32
+++ b/gcc/ChangeLog.addr32
@@ -1,3 +1,8 @@
+2012-03-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config/i386/i386.c (ix86_print_operand_address): Only handle
+	zero-extended DImode addresses if Pmode == DImode.
+
 2012-03-06  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/i386/i386.md (*zero_extendsidi2_rex64): Allow loading
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 69cb6ae..c2cad5a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -14548,7 +14548,7 @@ ix86_print_operand_address (FILE *file, rtx addr)
 
       /* Print SImode registers for zero-extended addresses to force
 	 addr32 prefix.  Otherwise print DImode registers to avoid it.  */
-      if (TARGET_64BIT)
+      if (Pmode == DImode)
 	code = ((GET_CODE (addr) == ZERO_EXTEND
 		 || GET_CODE (addr) == AND)
 		? 'l'
--
Comment 7 Uroš Bizjak 2012-03-09 16:50:12 UTC
(In reply to comment #6)
> This patch works for me:
> 
> ---
> diff --git a/gcc/ChangeLog.addr32 b/gcc/ChangeLog.addr32
> index 066f1ec..a191e47 100644
> --- a/gcc/ChangeLog.addr32
> +++ b/gcc/ChangeLog.addr32
> @@ -1,3 +1,8 @@
> +2012-03-08  H.J. Lu  <hongjiu.lu@intel.com>
> +
> +    * config/i386/i386.c (ix86_print_operand_address): Only handle
> +    zero-extended DImode addresses if Pmode == DImode.
> +
>  2012-03-06  Uros Bizjak  <ubizjak@gmail.com>
> 
>      * config/i386/i386.md (*zero_extendsidi2_rex64): Allow loading
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 69cb6ae..c2cad5a 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -14548,7 +14548,7 @@ ix86_print_operand_address (FILE *file, rtx addr)
> 
>        /* Print SImode registers for zero-extended addresses to force
>       addr32 prefix.  Otherwise print DImode registers to avoid it.  */
> -      if (TARGET_64BIT)
> +      if (Pmode == DImode)
>      code = ((GET_CODE (addr) == ZERO_EXTEND
>           || GET_CODE (addr) == AND)
>          ? 'l'
> --

You will have addr32 added to all lea(%SImode),%SImode instructions.

I have a patch in testing that emits addresses in their natural mode (SImode or DImode), forces 'l' override for the above RTXes and 'q' for all LEA insns.

For LEAs, we introduce %E modifier that enables special handling:

+	case 'E':
+	  /* Wrap address in an UNSPEC to declare special handling.  */
+	  if (TARGET_64BIT)
+	    x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
+
+	  output_address (x);
+	  return;

And in ix86_print_operand_address:

+  else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
+    {
+      gcc_assert (TARGET_64BIT);
+      ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
+      code = 'q';
+    }
Comment 8 Uroš Bizjak 2012-03-09 17:08:13 UTC
Created attachment 26865 [details]
Patch that introduces %E modifier

Patch in testing.
Comment 9 uros 2012-03-09 18:01:56 UTC
Author: uros
Date: Fri Mar  9 18:01:47 2012
New Revision: 185148

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185148
Log:
	PR target/52530
	* config/i386/i386.c (ix86_print_operand): Handle 'E' operand modifier.
	(ix86_print_operand_address): Handle UNSPEC_LEA_ADDR. Do not fallback
	to set code to 'q'.
	* config/i386/i386.md (UNSPEC_LEA_ADDR): New unspec.
	(*movdi_internal_rex64): Use %E operand modifier for lea.
	(*movsi_internal): Ditto.
	(*lea_1): Ditto.
	(*lea<mode>_2): Ditto.
	(*lea_{3,4,5,6}_zext): Ditto.
	(*tls_global_dynamic_32_gnu): Ditto.
	(*tls_global_dynamic_64): Ditto.
	(*tls_dynamic_gnu2_lea_32): Ditto.
	(*tls_dynamic_gnu2_lea_64): Ditto.
	(pro_epilogue_adjust_stack_<mode>_add): Ditto.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/config/i386/i386.md
Comment 10 uros 2012-03-11 19:48:02 UTC
Author: uros
Date: Sun Mar 11 19:47:58 2012
New Revision: 185201

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185201
Log:
	PR target/52530
	* gcc.dg/torture/pr52530.c: New test.


Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr52530.c
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 11 Richard Biener 2012-03-12 14:11:18 UTC
Fixed.
Comment 12 uros 2012-08-01 19:15:04 UTC
Author: uros
Date: Wed Aug  1 19:14:59 2012
New Revision: 190048

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190048
Log:
	Backport from mainline
	2012-03-09  Uros Bizjak  <ubizjak@gmail.com>

	PR target/52530
	* config/i386/i386.c (ix86_print_operand): Handle 'E' operand modifier.
	(ix86_print_operand_address): Handle UNSPEC_LEA_ADDR. Do not fallback
	to set code to 'q'.
	* config/i386/i386.md (UNSPEC_LEA_ADDR): New unspec.
	(*movdi_internal_rex64): Use %E operand modifier for lea.
	(*movsi_internal): Ditto.
	(*lea_1): Ditto.
	(*lea<mode>_2): Ditto.
	(*lea_{3,4,5,6}_zext): Ditto.
	(*tls_global_dynamic_32_gnu): Ditto.
	(*tls_global_dynamic_64): Ditto.
	(*tls_dynamic_gnu2_lea_32): Ditto.
	(*tls_dynamic_gnu2_lea_64): Ditto.
	(pro_epilogue_adjust_stack_<mode>_add): Ditto.

testsuite/ChangeLog:

	Backport from mainline
	2012-03-11  Uros Bizjak  <ubizjak@gmail.com>

	PR target/52530
	* gcc.dg/torture/pr52530.c: New test.


Added:
    branches/gcc-4_7-branch/gcc/testsuite/gcc.dg/pr52530.c
Modified:
    branches/gcc-4_7-branch/gcc/ChangeLog
    branches/gcc-4_7-branch/gcc/config/i386/i386.c
    branches/gcc-4_7-branch/gcc/config/i386/i386.md
    branches/gcc-4_7-branch/gcc/testsuite/ChangeLog