www.digitalmars.com         C & C++   DMDScript  

D.gnu - [Bug 73] New: ARM: Wrong code with -O2 (heisenbug)

http://bugzilla.gdcproject.org/show_bug.cgi?id=73

             Bug #: 73
           Summary: ARM: Wrong code with -O2 (heisenbug)
    Classification: Unclassified
           Product: GDC
           Version: development
          Platform: ARM
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: Normal
         Component: gdc
        AssignedTo: ibuclaw gdcproject.org
        ReportedBy: johannespfau gmail.com


Created attachment 42
  --> http://bugzilla.gdcproject.org/attachment.cgi?id=42
test case

This is likely a backend bug but posting it here anyway as I can't get a
working C test case.

The test case and the full tree-original, tree-optimized, gimple reload-rtl and
postreload-rtl logs are attached. The test case works fine at -O1 and doesn't
work at -O2 and higher.
The bug disappears when compiling with -fno-dse. It does not appear at -O1
-fdse though. Some other switch combinations also hide the bug.


GCC is 4.8.1, latest gdc.

First attempt at a explanation: The compiler wrongly optimizes the "Tup3 tup22
= tup3(tup11, tup12);" statement:

After the reload pass we have this rtl:
-----------------
(insn 5 21 7 2 (set (reg/f:SI 4 r4 [156])
        (plus:SI (reg/f:SI 13 sp)
            (const_int 64 [0x40]))) aliasthis-struct.d:23 5 {*arm_addsi3}
     (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 sp)
            (const_int 64 [0x40]))
        (nil)))
[...]
(insn 46 48 41 2 (set (reg:SI 3 r3 [131])
        (const_int 3 [0x3])) aliasthis-struct.d:28 641 {*arm_movsi_vfp}
     (expr_list:REG_EQUIV (const_int 3 [0x3])
        (nil)))
(insn 47 49 51 2 (set (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 64 [0x40])) [10 MEM[(struct Tup2 *)&D.3970]+0 S4
A64])
        (reg:SI 3 r3 [131])) aliasthis-struct.d:28 641 {*arm_movsi_vfp}
     (nil))
[...]
(insn 91 62 92 2 (parallel [
            (set (reg:SI 0 r0)
                (mem/c:SI (reg/f:SI 12 ip [135]) [7 a+0 S4 A64]))
            (set (reg:SI 1 r1)
                (mem/c:SI (plus:SI (reg/f:SI 12 ip [135])
                        (const_int 4 [0x4])) [7 a+4 S4 A32]))
            (set (reg:SI 2 r2)
                (mem/c:SI (plus:SI (reg/f:SI 12 ip [135])
                        (const_int 8 [0x8])) [7 a+8 S4 A64]))
            (set (reg:SI 3 r3)
                (mem/c:SI (plus:SI (reg/f:SI 12 ip [135])
                        (const_int 12 [0xc])) [7 a+12 S4 A32]))
        ]) aliasthis-struct.d:33 360 {*ldm4_ia}
     (nil))
(insn 92 91 93 2 (parallel [
            (set (mem/c:SI (reg/f:SI 4 r4 [156]) [7 D.3973.field1+0 S4 A64])
                (reg:SI 0 r0))
            (set (mem/c:SI (plus:SI (reg/f:SI 4 r4 [156])
                        (const_int 4 [0x4])) [7 D.3973.field1+4 S4 A32])
                (reg:SI 1 r1))
            (set (mem/c:SI (plus:SI (reg/f:SI 4 r4 [156])
                        (const_int 8 [0x8])) [7 D.3973.field1+8 S4 A64])
                (reg:SI 2 r2))
            (set (mem/c:SI (plus:SI (reg/f:SI 4 r4 [156])
                        (const_int 12 [0xc])) [7 D.3973.field1+12 S4 A32])
                (reg:SI 3 r3))
        ]) aliasthis-struct.d:33 364 {*stm4_ia}
     (nil))
(insn 93 92 94 2 (set (reg:SI 1 r1 [orig:111 tup22$field1$field1 ] [111])
        (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 64 [0x40])) [11 MEM[(struct Tup3 *)&D.3973]+0 S4
A64])) aliasthis-struct.d:33 641 {*arm_movsi_vfp}
     (expr_list:REG_EQUIV (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 64 [0x40])) [11 MEM[(struct Tup3 *)&D.3973]+0 S4
A64])
        (nil)))
(insn 94 93 95 2 (set (reg:DI 2 r2 [orig:112 tup22$field1$field2 ] [112])
        (mem/c:DI (plus:SI (reg/f:SI 13 sp)
                (const_int 72 [0x48])) [11 MEM[(struct Tup3 *)&D.3973 + 8B]+0
S8 A64])) aliasthis-struct.d:33 643 {*movdi_vfp}
     (nil))
(insn 95 94 96 2 (set (reg:CC 100 cc)
        (compare:CC (reg:SI 1 r1 [orig:111 tup22$field1$field1 ] [111])
            (const_int 10 [0xa]))) aliasthis-struct.d:43 217 {*arm_cmpsi_insn}
     (nil))
-----------------

However, for some reason the postreload pass doesn't realize that sp+64 has
been set to a different value in instruction 91 and picks up the value that was
set in instruction 47. The constant 3 is the length field of the "str" string.

Output after postreload:
-----------------
[...]
(insn 93 92 94 2 (set (reg:SI 1 r1 [orig:111 tup22$field1$field1 ] [111])
        (const_int 3 [0x3])) aliasthis-struct.d:33 641 {*arm_movsi_vfp}
     (expr_list:REG_EQUIV (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 64 [0x40])) [11 MEM[(struct Tup3 *)&D.3973]+0 S4
A64])
        (nil)))
(insn 94 93 95 2 (set (reg:DI 2 r2 [orig:112 tup22$field1$field2 ] [112])
        (mem/c:DI (plus:SI (reg/f:SI 13 sp)
                (const_int 72 [0x48])) [11 MEM[(struct Tup3 *)&D.3973 + 8B]+0
S8 A64])) aliasthis-struct.d:33 643 {*movdi_vfp}
     (nil))
-----------------

-- 
Configure bugmail: http://bugzilla.gdcproject.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.
Aug 06 2013