https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57003

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |---
   Target Milestone|4.8.1                       |5.0
            Summary|[4.8/4.9 Regression]        |[4.8/4.9/5.0 Regression]
                   |gcc-4.8.0 breaks -O2        |gcc breaks -O2 optimization
                   |optimization with Wine(64)  |with Wine(64) -
                   |- links/info/bisect of      |links/info/bisect of
                   |commits included            |commits included

--- Comment #23 from Uroš Bizjak <ubizjak at gmail dot com> ---
My r215428 change regressed this PR again. The difference is:

--- pr57003.s   2014-10-03 15:08:24.000000000 +0200
+++ pr57003_.s  2014-10-03 15:08:19.000000000 +0200
@@ -78,7 +78,7 @@
        leaq    -20(%rbx), %rdx
        movq    %rax, %rdi
        call    memcpy
-       movq    %rdi, c(%rip)
+       movq    %rax, c(%rip)
 .L8:
        movaps  (%rsp), %xmm6
        movaps  16(%rsp), %xmm7
@@ -321,5 +321,5 @@
        .byte   0xb
        .align 8
 .LEFDE7:
-       .ident  "GCC: (GNU) 5.0.0 20141002 (experimental) [trunk revision
215797]"
+       .ident  "GCC: (GNU) 4.9.2 20141001 (prerelease) [gcc-4_9-branch
revision 215749]"
        .section        .note.GNU-stack,"",@progbits

So, gcc-5.0 does not detect that %rdi is clobbered in ELF ABI.

The runtime failure happens only on CentOS5 (and not in Fedora20), which
supports findings in Comment #17.

The difference is, that previously we emit memcpy call as:

#(call_insn:TI 24 23 27 3 (set (reg:DI 0 ax)
#        (call (mem:QI (symbol_ref:DI ("memcpy") [flags 0x41] <function_decl
0x7fce6f586438 memcpy>) [0 memcpy S1 A8])
#            (const_int 0 [0]))) pr57003.c:32 661 {*call_value}
#     (expr_list:REG_DEAD (reg:DI 5 di)
#        (expr_list:REG_DEAD (reg:DI 4 si)
#            (expr_list:REG_DEAD (reg:DI 1 dx)
#                (expr_list:REG_UNUSED (reg:DI 0 ax)
#                    (expr_list:REG_RETURNED (reg/v/f:DI 2 cx [orig:87 e ]
[87])
#                        (expr_list:REG_CALL_DECL (symbol_ref:DI ("memcpy")
[flags 0x41] <function_decl 0x7fce6f586438 memcpy>)
#                            (expr_list:REG_EH_REGION (const_int 0 [0])
#                                (nil))))))))
#    (expr_list (clobber (reg:TI 52 xmm15))
#        (expr_list (clobber (reg:TI 51 xmm14))
#            (expr_list (clobber (reg:TI 50 xmm13))
#                (expr_list (clobber (reg:TI 49 xmm12))
#                    (expr_list (clobber (reg:TI 48 xmm11))
#                        (expr_list (clobber (reg:TI 47 xmm10))
#                            (expr_list (clobber (reg:TI 46 xmm9))
#                                (expr_list (clobber (reg:TI 45 xmm8))
#                                    (expr_list (clobber (reg:TI 28 xmm7))
#                                        (expr_list (clobber (reg:TI 27 xmm6))
#                                            (expr_list (clobber (reg:DI 5 di))
#                                                (expr_list (clobber (reg:DI 4
si))
#                                                    (expr_list:DI (set (reg:DI
0 ax)
#                                                            (reg:DI 5 di))
#                                                        (expr_list:DI (use
(reg:DI 5 di))
#                                                            (expr_list:DI (use
(reg:DI 4 si))
#                                                                (expr_list:DI
(use (reg:DI 1 dx))
#                                                                   
(nil))))))))))))))))))

which is alternate, but equivalent form of what was generated previously:

#(call_insn:TI 24 23 27 3 (parallel [
#            (set (reg:DI 0 ax)
#                (call (mem:QI (symbol_ref:DI ("memcpy") [flags 0x41]
<function_decl 0x7fd91824a800 memcpy>) [0 memcpy S1 A8])
#                    (const_int 0 [0])))
#            (unspec [
#                    (const_int 0 [0])
#                ] UNSPEC_MS_TO_SYSV_CALL)
#            (clobber (reg:DI 4 si))
#            (clobber (reg:DI 5 di))
#            (clobber (reg:TI 27 xmm6))
#            (clobber (reg:TI 28 xmm7))
#            (clobber (reg:TI 45 xmm8))
#            (clobber (reg:TI 46 xmm9))
#            (clobber (reg:TI 47 xmm10))
#            (clobber (reg:TI 48 xmm11))
#            (clobber (reg:TI 49 xmm12))
#            (clobber (reg:TI 50 xmm13))
#            (clobber (reg:TI 51 xmm14))
#            (clobber (reg:TI 52 xmm15))
#        ]) pr57003.c:32 652 {*call_value_rex64_ms_sysv}
#     (expr_list:REG_DEAD (reg:DI 5 di)
#        (expr_list:REG_DEAD (reg:DI 4 si)
#            (expr_list:REG_DEAD (reg:DI 1 dx)
#                (expr_list:REG_RETURNED (reg/v/f:DI 2 cx [orig:87 e ] [87])
#                    (expr_list:REG_EH_REGION (const_int 0 [0])
#                        (nil))))))
#    (expr_list:DI (set (reg:DI 0 ax)
#            (reg:DI 5 di))
#        (expr_list:DI (use (reg:DI 5 di))
#            (expr_list:DI (use (reg:DI 4 si))
#                (expr_list:DI (use (reg:DI 1 dx))
#                    (nil))))))

It looks that Jakub's patch, proposed in Comment #21 doesn't cover alternative
form, so it doesn't record clobbers in the alternative form properly.

Reopened as 5.0 regression.

Reply via email to