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.