https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69752

            Bug ID: 69752
           Summary: Reload removing instruction with side-effect
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: andre.simoesdiasvieira at arm dot com
  Target Milestone: ---

This behavior was caught when debugging the following fail for -mcpu=cortex-m0:
FAIL: g++.dg/torture/vshuf-v2di.C -O2 execution test


After some debugging I noticed that reload would remove an insn that contained
a post_inc which would cause the shuffle to be off by 4 (the value of the post
increase).

Using the exact same sources as the testsuite, if you compile with
-fdump-rtl-all you can observe that pre reload (ira) you encounter the
following sequence of RTL:

(insn 455 191 213 6 (set (reg/f:SI 267)
        (reg/f:SI 379)) 748 {*thumb1_movsi_insn}
     (nil))
(insn 213 455 216 6 (set (reg:SI 266)
        (mem/u/c:SI (post_inc:SI (reg/f:SI 267)) [4  S4 A32])) 748
{*thumb1_movsi_insn}
     (expr_list:REG_EQUIV (const_int -1044200508 [0xffffffffc1c2c3c4])
        (expr_list:REG_INC (reg/f:SI 267)
            (nil))))
(insn 216 213 218 6 (set (reg:SI 268)
        (mem/u/c:SI (reg/f:SI 267) [4  S4 A64])) 748 {*thumb1_movsi_insn}
     (expr_list:REG_DEAD (reg/f:SI 267)
        (nil)))

Where pseudo register 267 is post_incremented in insn 213 and used in insn 216
right after.

After reload:

...
Removing equiv init insn 443 (freq=107)
  443: r381:SI=sfp:SI+0x10
      REG_EQUIV sfp:SI-0x40
deleting insn with uid = 443.
...
(insn 455 191 213 6 (set (reg/f:SI 5 r5 [267])
        (reg/f:SI 2 r2 [379])) 748 {*thumb1_movsi_insn}
     (nil))
(note 213 455 216 6 NOTE_INSN_DELETED)
(insn 216 213 521 6 (set (reg:SI 5 r5 [268])
        (mem/u/c:SI (reg/f:SI 5 r5 [267]) [4  S4 A64])) 748
{*thumb1_movsi_insn}
     (nil))

As you see pseudo register 268 (now in r5), will be loaded from mem (r5) which
is still pointing to the old value of 267 and not the increased one, causing an
offset error of 4. I checked and pseudo register 748 is the same in both cases.
Also adding -fno-auto-inc to the test will yield a PASS result.

Reply via email to