https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69896
Bug ID: 69896 Summary: [6 Regression] wrong code with -frename-registers @ x64_64 Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: zsojka at seznam dot cz Target Milestone: --- Target: x86_64-pc-linux-gnu Created attachment 37748 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37748&action=edit reduced testcase This particular testcase fails only in trunk, but other branches might be affected as well. Output: $ x86_64-pc-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=/repo/gcc-trunk/binary-latest/bin/x86_64-pc-linux-gnu-gcc COLLECT_LTO_WRAPPER=/repo/gcc-trunk/binary-trunk-233588-checking-yes-rtl-df-nographite/bin/../libexec/gcc/x86_64-pc-linux-gnu/6.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /repo/gcc-trunk//configure --enable-languages=c,c++ --enable-checking=yes,rtl,df --without-cloog --without-ppl --without-isl --disable-libstdcxx-pch --prefix=/repo/gcc-trunk//binary-trunk-233588-checking-yes-rtl-df-nographite Thread model: posix gcc version 6.0.0 20160220 (experimental) (GCC) $ x86_64-pc-linux-gnu-gcc -O -fcaller-saves -fno-dse -frename-registers -fno-tree-ter -mno-sse testcase.c $ ./a.out 00000001074a3e490000000000000000 Correct output is "00000000074a3e490000000000000001". Assembly diff with/out -frename-registers shows the problem is at the beginning of foo: @@ -81,63 +81,64 @@ neg r9d # _13 mov rbx, QWORD PTR [rsp+704] # tmp235, v32u128_1D.1508 mov rsi, QWORD PTR [rsp+712] #, v32u128_1D.1508 + mov ecx, ebx # _16, _15 mov DWORD PTR [rsp+64], edx #, _3 mov DWORD PTR [rsp+68], edx #, _3 mov DWORD PTR [rsp+72], r10d #, _6 mov DWORD PTR [rsp+76], 1 #, mov DWORD PTR [rsp+80], eax #, _10 mov DWORD PTR [rsp+84], r9d #, _13 - mov QWORD PTR [rsp+32], rbx # %sfpD.1587, _15 + mov QWORD PTR [rsp+32], rcx # %sfpD.1587, _15 mov QWORD PTR [rsp+40], rsi # %sfpD.1587, _15 mov DWORD PTR [rsp+88], ebx #, tmp236 mov DWORD PTR [rsp+92], 1 #, "mov ecx,ebx" zeroes the higher 32bits of rcx, thus the store to "[rsp+32]" works with a different value (0xffffffff vs. 0xffffffffffffffff). Looking at the dumps with/out -frename-registers, the difference in 272r.cprop_hardreg (just after rnreg) is: @@ -133,7 +133,7 @@ (expr_list:REG_UNUSED (reg:DI 41 r12 [ _15+8 ]) (nil))) (note 273 282 31 2 NOTE_INSN_DELETED) -(insn 31 273 32 2 (set (reg:SI 3 bx [orig:99 _16 ] [99]) +(insn 31 273 32 2 (set (reg:SI 2 cx [orig:99 _16 ] [99]) (reg:SI 3 bx [orig:98 _15 ] [98])) testcase.c:13 86 {*movsi_internal} (nil)) (insn 32 31 33 2 (set (mem/c:SI (plus:DI (reg/f:DI 7 sp) @@ -166,7 +166,7 @@ (nil))) (insn 283 37 284 2 (set (mem/c:DI (plus:DI (reg/f:DI 7 sp) (const_int 32 [0x20])) [6 %sfpD.1587+-352 S8 A128]) - (reg:DI 3 bx [orig:98 _15 ] [98])) testcase.c:13 85 {*movdi_internal} + (reg:DI 2 cx [orig:98 _15 ] [98])) testcase.c:13 85 {*movdi_internal} (nil)) (insn 284 283 278 2 (set (mem/c:DI (plus:DI (reg/f:DI 7 sp) (const_int 40 [0x28])) [6 %sfpD.1587+-344 S8 A64]) ... here, rnreg just changed the "mov ebx,ebx" SI move to "mov ecx,ebx" (which is valid). It seems this just uncovered an error, since the original "mov ebx,ebx" (eg. the (set (reg:SI 2 cx [orig:99 _16 ] [99]) (reg:SI 3 bx [orig:98 _15 ] [98])) {*movsi_internal}) was already wrong, but it got removed in .rtl_dce: @@ -285,8 +287,6 @@ deleting insn with uid = 309. DCE: Deleting insn 251 deleting insn with uid = 251. -DCE: Deleting insn 31 -deleting insn with uid = 31. DCE: Deleting insn 282 deleting insn with uid = 282. DCE: Deleting insn 281 Is it correct the *movsi_internal matches insn 31, and that insn 31 got removed in .rtl_dce? (I don't know what is the "(set (reg:SI ..." semantics for higher bits of the destination register) Tested revisions: trunk r233588 - FAIL 5-branch r233025 - OK 4_9-branch r233576 - OK