[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread ubizjak at gmail dot com


--- Comment #21 from ubizjak at gmail dot com  2008-11-22 12:33 ---
This is a trace what happens in the testcase, from .expand dump:

(2) [frame + 8 ]- si
(3) [frame + 16]- dx
(4) r62 - di

(8) r63 - virtual-incoming-args + 0
(9) r64 - virtual-stack-vars - 64
(10) [r64]  - 8;; gp_offset
(11) r65- virtual-stack-vars - 64
(12) [r65 + 8 ] - virtual-incoming-args;; overflow_arg_area
(13) r66- virtual-stack-vars - 64
(14) [r66 + 16] - frame;; reg_save_area
(15) r61- [virtual-stack-vars - 64];; gp_offset
if (r61  39)
   goto label 27

(19) r67- virtual-stack-vars - 32
(20) r68- zext (r61)
(21) r69- [virtual-stack-vars - 48];; reg_save_area
(22) r70- [r69 + r68]
(23) [r67]  - r70
(24) r58- virtual-stack-vars - 32
goto label 32

label 27:
(29) r72- [virtual-stack-vars - 56];; overflow_arg_area
(30) r71- r72 + 15
(31) r58- r71  -16

label 32:
(34) r73- [r58]
(35) [virtual-stack-vars - 16] - r73
(36) r74- [r58 + 8]
(37) [virtual-stack-vars - 8 ] - r74
(38) r60- [virual-stack-vars - 12] ;; arg$b$real
(39) r59- [virual-stack-vars - 8 ] ;; arg$b$imag

So, around insn (22), gcc forgets to copy dx register to reg_save_area. r74 is
then read from uninitialized reg_save_area slot.

I'm looking at va-arg handling implementation in i386.c. But I'm not familiar
with this code, so a bit of help would be most welcome here.


-- 

ubizjak at gmail dot com changed:

   What|Removed |Added

 AssignedTo|ubizjak at gmail dot com|unassigned at gcc dot gnu
   ||dot org
 Status|ASSIGNED|NEW


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread ubizjak at gmail dot com


--- Comment #22 from ubizjak at gmail dot com  2008-11-22 17:07 ---
Aliasing problems, gcc shoots himself in the foot...

When container consists of registers in different modes (due to
X86_64_INTEGERSI_CLASS optimization):

(parallel:BLK [
(expr_list:REG_DEP_TRUE (reg:DI 0 ax)
(const_int 0 [0x0]))
(expr_list:REG_DEP_TRUE (reg:SI 1 dx)
(const_int 8 [0x8]))
])

then ix86_gimplify_va_arg happily creates code with invalid aliasing (from
_.gimple dump):

  addr.0 = va_arg_tmp.3;
 addr.4 = (long unsigned int *) addr.0;
  int_addr.5 = (long unsigned int *) int_addr.1;
  D.1615 = *int_addr.5;
  *addr.4 = D.1615;
 addr.6 = (unsigned int *) addr.0;
  D.1617 = addr.6 + 8;

We access addr.0 as (long unsigned int *) and as (unsigned int *. Following
optimization passes are more than happy to remove the second access.

So to prove my point, testcase compiled with -fno-strict-aliasing works OK.

These problems also apply to FPmode parameters passing through SSE regs, so
following patch moves registers from register area to tmp area in generic mode
that fits argument passing registers best: DImode for integer and V4SFmode for
SSE registers. This avoids aliasing problems.

Index: i386.c
===
--- i386.c  (revision 142120)
+++ i386.c  (working copy)
@@ -6750,7 +6750,8 @@ ix86_gimplify_va_arg (tree valist, tree 
{
  rtx slot = XVECEXP (container, 0, i);
  rtx reg = XEXP (slot, 0);
- enum machine_mode mode = GET_MODE (reg);
+ enum machine_mode mode
+   = SSE_REGNO_P (REGNO (reg)) ? V4SFmode : DImode;
  tree piece_type = lang_hooks.types.type_for_mode (mode, 1);
  tree addr_type = build_pointer_type (piece_type);
  tree src_addr, src;


-- 

ubizjak at gmail dot com changed:

   What|Removed |Added

 AssignedTo|unassigned at gcc dot gnu   |ubizjak at gmail dot com
   |dot org |
 Status|NEW |ASSIGNED
   Last reconfirmed|2008-11-16 20:58:10 |2008-11-22 17:07:30
   date||


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread howarth at nitro dot med dot uc dot edu


--- Comment #23 from howarth at nitro dot med dot uc dot edu  2008-11-22 
17:39 ---
Patch in Comment 22 eliminates the va-arg test case failure at -m64 on
i686-apple-darwin9.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread rguenth at gcc dot gnu dot org


--- Comment #24 from rguenth at gcc dot gnu dot org  2008-11-22 18:20 
---
The va-arg code should probably use ref-all pointers all over the place
instead.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread ubizjak at gmail dot com


--- Comment #25 from ubizjak at gmail dot com  2008-11-22 19:30 ---
Deassigning me, this is tree stuff.


-- 

ubizjak at gmail dot com changed:

   What|Removed |Added

 AssignedTo|ubizjak at gmail dot com|unassigned at gcc dot gnu
   ||dot org
 Status|ASSIGNED|NEW


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread rguenth at gcc dot gnu dot org


--- Comment #26 from rguenth at gcc dot gnu dot org  2008-11-22 20:41 
---
Even with ref-all pointers we end up with

bb 5:
  # addr.0{0}_1 = PHI va_arg_tmp.3(3), addr.0{0}_22(4)
  # ap_38 = PHI ap_56(3), ap_57(4)
  # va_arg_tmp.3_39 = PHI va_arg_tmp.3_55(3), va_arg_tmp.3_50(4)
  addr.8_25 = (struct S2848 * {ref-all}) addr.0{0}_1;
  # VUSE fails_48, ap_38, SMT.26_53
  # arg_59 = VDEF arg_58(D)
  arg = *addr.8_25;

where the last stmt misses a VUSE of va_arg_tmp.3.  This looks like a bug
in alias computation.

I have a fix for that parts.  The gimplify_va_arg still needs to use ref-all
pointers properly.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-22 Thread rguenth at gcc dot gnu dot org


--- Comment #27 from rguenth at gcc dot gnu dot org  2008-11-22 20:41 
---
I have patches.


-- 

rguenth at gcc dot gnu dot org changed:

   What|Removed |Added

 AssignedTo|unassigned at gcc dot gnu   |rguenth at gcc dot gnu dot
   |dot org |org
 Status|NEW |ASSIGNED
   Last reconfirmed|2008-11-22 17:07:30 |2008-11-22 20:41:24
   date||


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread howarth at nitro dot med dot uc dot edu


--- Comment #15 from howarth at nitro dot med dot uc dot edu  2008-11-20 
12:55 ---
The patch in comment 13 appears to be sufficient to completely fix the problem
on i686-apple-darwin9.
The results for current gcc trunk with the patch...

http://gcc.gnu.org/ml/gcc-testresults/2008-11/msg01712.html

...compared to those without the patch...

http://gcc.gnu.org/ml/gcc-testresults/2008-11/msg01535.html

shows that...

FAIL: tmpdir-gcc.dg-struct-layout-1/t028 c_compat_x_tst.o-c_compat_y_tst.o
execute 

is eliminated at -m64 without any regressions in other tests.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread ubizjak at gmail dot com


--- Comment #16 from ubizjak at gmail dot com  2008-11-20 19:50 ---
Problems from Comment #10 and Comment #11 are fixed by the patch from Comment
#13, but following test still fails, even with a patched compiler:

--cut here--
void abort (void);

struct S2848
{
  unsigned int a;
  _Complex int b;
  struct
  {
  } __attribute__ ((aligned)) c;
};

struct S2848 s2848;

int fails;

void  __attribute__((noinline))
check2848va (int z, ...)
{
  struct S2848 arg;
  __builtin_va_list ap;

  __builtin_va_start (ap, z);

  arg = __builtin_va_arg (ap, struct S2848);

  if (s2848.a != arg.a)
++fails;
  if (s2848.b != arg.b)
++fails;

  __builtin_va_end (ap);
}

int main (void)
{
  s2848.a = 4027477739U;
  s2848.b = (723419448 + -218144346 * __extension__ 1i);

  check2848va (1, s2848);

  if (fails)
abort ();

  return 0;
}
--cut here--

 gcc -O2 t1.c

 ./a.out
Aborted

 gdb ./a.out
[...]
(gdb) watch fails
Hardware watchpoint 1: fails
(gdb) run
Starting program: /home/uros/test/compat/a.out 
Hardware watchpoint 1: fails

Old value = 0
New value = 1
0x0040051d in check2848va (z=1) at t1.c:29
29  ++fails;
Missing separate debuginfos, use: debuginfo-install glibc.x86_64
(gdb) p /x arg.b
$2 = 0x004005802b1e8138
(gdb) p /x s2848.b
$3 = 0xf2ff61a62b1e8138


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread uros at gcc dot gnu dot org


--- Comment #17 from uros at gcc dot gnu dot org  2008-11-20 21:12 ---
Subject: Bug 38151

Author: uros
Date: Thu Nov 20 21:11:22 2008
New Revision: 142059

URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=142059
Log:
PR target/38151
* config/i386/i386.c (classify_argument) [integer mode size = 64bit]:
Handle cases when integer argument crosses argument register boundary.

testsuite/ChangeLog:

PR target/38151
* gcc.target/i386/pr38151-1.c: New test.


Added:
trunk/gcc/testsuite/gcc.target/i386/pr38151-1.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/config/i386/i386.c
trunk/gcc/testsuite/ChangeLog


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread ubizjak at gmail dot com


--- Comment #18 from ubizjak at gmail dot com  2008-11-20 21:13 ---
va_arg problem from Comment #16 remains unfixed.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread ubizjak at gmail dot com


--- Comment #19 from ubizjak at gmail dot com  2008-11-20 21:37 ---
Hm, rdx gets corrupted:

check2848va:
.LFB0:
.cfi_startproc
movq%rsi, %rcx  # tmp73,
leaq8(%rsp), %rax   #,
(+) movq%rdx, -40(%rsp) #,
shrq$32, %rcx   #,
cmpl%esi, s2848(%rip)   # tmp73, s2848.a
 movq-80(%rsp), %rdx #, tmp74
movq%rax, -112(%rsp)#, variable.overflow_arg_area
leaq-56(%rsp), %rax #,
movq%rsi, -48(%rsp) #,
movl$8, -120(%rsp)  #, variable.gp_offset
movq%rsi, -88(%rsp) # tmp70,
movq%rax, -104(%rsp)#, variable.reg_save_area
movq%rsi, -72(%rsp) # tmp73, arg
movq%rdx, -64(%rsp) # tmp74, arg
je  .L4 #,
addl$1, fails(%rip) #, fails
.L4:
cmpl%ecx, s2848+4(%rip) # arg$b$real, s2848.b
setne   %cl #, tmp79
(++)cmpl%edx, s2848+8(%rip) # arg$b$imag, s2848.b
setne   %al #, tmp82
orb %al, %cl# tmp82, tmp79
je  .L6 #,
addl$1, fails(%rip) #, fails

rdx is saved at the point of (+), corrupted at  and this corrupted value
is used at (++). The insn at  just falls in the insn stream from the sky,
it is not present if a is changed to unsigned long in S2848 structure.

In case when a is changed to unsigned long, testcase works OK. The testcase
also works when insn at  is removed.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-20 Thread howarth at nitro dot med dot uc dot edu


--- Comment #20 from howarth at nitro dot med dot uc dot edu  2008-11-21 
00:05 ---
The test case in comment 16 passes on i686-apple-darwin9 when compiled with
-m32 but fails when compiled with -m64.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-19 Thread ubizjak at gmail dot com


--- Comment #12 from ubizjak at gmail dot com  2008-11-19 19:32 ---
Created an attachment (id=16723)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=16723action=view)
Da patch.

Jack, can you try attached patch?


-- 

ubizjak at gmail dot com changed:

   What|Removed |Added

 AssignedTo|unassigned at gcc dot gnu   |ubizjak at gmail dot com
   |dot org |
 Status|NEW |ASSIGNED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-19 Thread ubizjak at gmail dot com


--- Comment #13 from ubizjak at gmail dot com  2008-11-19 21:17 ---
(In reply to comment #12)
 Created an attachment (id=16723)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=16723action=view) [edit]
 Da patch.
 
 Jack, can you try attached patch?

Patch at http://gcc.gnu.org/ml/gcc-patches/2008-11/msg01010.html

It looks we still fail va_arg cases. But number of failures with the original
testcase drops from 10 to 4.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151



[Bug target/38151] structures with _Complex arguments are not passed correctly

2008-11-19 Thread howarth at nitro dot med dot uc dot edu


--- Comment #14 from howarth at nitro dot med dot uc dot edu  2008-11-20 
01:10 ---
The patch from Comment 13 when applied to gcc trunk (without a complete
bootstrap) eliminates the failures in gcc.dg-struct-layout-1 at -m64 while not
introducing any at -m32 on i686-apple-darwin9. I am doing a complete bootstrap
and make check against current gcc trunk.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38151