[Bug target/38151] structures with _Complex arguments are not passed correctly
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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