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.