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

Dominik Vogt <vogt at linux dot vnet.ibm.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vogt at linux dot vnet.ibm.com

--- Comment #27 from Dominik Vogt <vogt at linux dot vnet.ibm.com> ---
The patch in comment 22 that was applied on 2015-09-01 with the git commit id
0af99ebfea26293fc900fe9050c5dd514005e4e5 breaks the S/390 compiler (and maybe
other platforms too):

tt.c:
-- snip --
  struct t
  {
    int i;
    void *p;
    void *q;
  };
  void foo (t **g)
  {
    (*g)->p = &((*g)->p);
  }
-- snip --

This code should set "p" to "&p", but actually sets "q" to "&p".  Before the
patch, compiling with "g++ -O2" resulted in this assembly code:

tt.s:
  lg    %r1,0(%r2)  # r1 := *g
  la    %r2,8(%r1)  # r2 := &((*g)->p)
  stg   %r2,8(%r1)  # *r2 := (*g) + 8  <--- GOOD

with the patch it uses r1 for both, effectively doubling the store target's
offset into the structure:

tt.s:
  lg      %r1,0(%r2) # r1 := *g
  la      %r1,8(%r1) # r1 := &((*g)->p)
  stg     %r1,8(%r1) # *(r1 + 8) := (*g) + 8  <--- BAD


RTL details:
============

tt.c.232r.reload (BAD, with patch):
-- snip --
(insn 6 3 7 2 (set (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])
        (mem/f:DI (reg:DI 2 %r2 [ g ]) [1 *g_2(D)+0 S8 A64])) tt.c:9 900
{*movdi_64}
     (nil))
(insn 7 6 13 2 (parallel [
            (set (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])
                (plus:DI (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])
                    (const_int 8 [0x8])))
            (clobber (reg:CC 33 %cc))
        ]) tt.c:9 1171 {*adddi3}
     (nil))
(insn 13 7 10 2 (set (mem/f:DI (plus:DI (reg/f:DI 1 %r1 [orig:61 *g_2(D) ]
[61])
                (const_int 8 [0x8])) [2 _3->p+0 S8 A64])
        (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])) tt.c:9 900 {*movdi_64}
     (nil))
-- snip --


tt.c.232r.reload (GOOD, without patch):
-- snip --
(insn 6 3 12 2 (set (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])
        (mem/f:DI (reg:DI 2 %r2 [ g ]) [1 *g_2(D)+0 S8 A64])) tt.c:9 900
{*movdi_64}
     (nil))
(insn 12 6 7 2 (set (reg:DI 2 %r2 [63])
        (reg/f:DI 1 %r1 [orig:61 *g_2(D) ] [61])) tt.c:9 900 {*movdi_64}
     (nil))
(insn 7 12 13 2 (parallel [
            (set (reg:DI 2 %r2 [63])
                (plus:DI (reg:DI 2 %r2 [63])
                    (const_int 8 [0x8])))
            (clobber (reg:CC 33 %cc))
        ]) tt.c:9 1171 {*adddi3}
     (nil))
(insn 13 7 10 2 (set (mem/f:DI (plus:DI (reg/f:DI 1 %r1 [orig:61 *g_2(D) ]
[61])
                (const_int 8 [0x8])) [2 _3->p+0 S8 A64])
        (reg:DI 2 %r2 [63])) tt.c:9 900 {*movdi_64}
     (nil))
-- snip --


tt.c.231r.ira (GOOD):
-- snip --
(insn 6 3 7 2 (set (reg/f:DI 61 [ *g_2(D) ])
        (mem/f:DI (reg:DI 2 %r2 [ g ]) [1 *g_2(D)+0 S8 A64])) tt.c:9 900
{*movdi_64}
     (expr_list:REG_DEAD (reg:DI 2 %r2 [ g ])
        (nil)))
(insn 7 6 10 2 (parallel [
            (set (mem/f:DI (plus:DI (reg/f:DI 61 [ *g_2(D) ])
                        (const_int 8 [0x8])) [2 _3->p+0 S8 A64])
                (plus:DI (reg/f:DI 61 [ *g_2(D) ])
                    (const_int 8 [0x8])))
            (clobber (reg:CC 33 %cc))
        ]) tt.c:9 1171 {*adddi3}
     (expr_list:REG_DEAD (reg/f:DI 61 [ *g_2(D) ])
        (expr_list:REG_UNUSED (reg:CC 33 %cc)
            (nil))))
-- snip --

Reply via email to