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

Reply via email to