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

--- Comment #2 from James Greenhalgh <jgreenhalgh at gcc dot gnu.org> ---
I'd be surprised if that patch was the real root cause of the issue you're
reporting. Rather it looks like something latent that was exposed by that
patch.

The testcase is a bit too large to easily work with (any ideas for getting the
size down would be helpful), isn't an execute test, and  is difficult to
confirm the exact report with current trunk as the offsets and labels have
changed, but here is what I found:

Here is the relevant memory access coming out of expand. Watch what happens to
insn 1047 (why is that a DImode subreg of an SImode in the first place, rather
than a zero_extend?

----
;; MEM[(struct isl_obj *)&obj1] = &isl_obj_map_vtable;

(insn 1045 1044 1046 (set (reg:SI 480)
        (high:SI (symbol_ref:SI ("isl_obj_map_vtable") [flags 0xc0] <var_decl
0x7fa0363ea240 isl_obj_map_vtable>))) y.c:12702 -1
     (nil))

(insn 1046 1045 1047 (set (reg/f:SI 479)
        (lo_sum:SI (reg:SI 480)
            (symbol_ref:SI ("isl_obj_map_vtable") [flags 0xc0] <var_decl
0x7fa0363ea240 isl_obj_map_vtable>))) y.c:12702 -1
     (expr_list:REG_EQUAL (symbol_ref:SI ("isl_obj_map_vtable") [flags 0xc0]
<var_decl 0x7fa0363ea240 isl_obj_map_vtable>)
        (nil)))

(insn 1047 1046 1048 (set (reg:DI 481)
        (subreg:DI (reg/f:SI 479) 0)) y.c:12702 -1
     (nil))

(insn 1048 1047 0 (set (zero_extract:DI (reg/v:DI 191 [ obj1D.17368 ])
            (const_int 32 [0x20])
            (const_int 0 [0]))
        (reg:DI 481)) y.c:12702 -1
     (nil))
---
Here is the same set of insns just after cse1:

-----
(insn 1045 1044 1046 107 (set (reg/f:SI 480)
        (reg/f:SI 478)) y.c:12702 49 {*movsi_aarch64}
     (expr_list:REG_EQUAL (high:SI (symbol_ref:SI ("isl_obj_map_vtable") [flags
0xc0] <var_decl 0x7fa0363ea240 isl_obj_map_vtable>))
        (nil)))
(insn 1046 1045 1047 107 (set (reg/f:SI 479)
        (subreg/s/v:SI (reg/f:DI 141 [ SR.304D.17381 ]) 0)) y.c:12702 49
{*movsi_aarch64}
     (expr_list:REG_DEAD (reg/f:SI 480)
        (expr_list:REG_EQUAL (symbol_ref:SI ("isl_obj_map_vtable") [flags 0xc0]
<var_decl 0x7fa0363ea240 isl_obj_map_vtable>)
            (nil))))
(insn 1047 1046 1048 107 (set (reg/f:DI 481)
        (subreg:DI (reg/f:SI 477) 0)) y.c:12702 50 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg/f:SI 479)
        (nil)))
(insn 1048 1047 1049 107 (set (zero_extract:DI (reg/v:DI 191 [ obj1D.17368 ])
            (const_int 32 [0x20])
            (const_int 0 [0]))
        (reg/f:DI 481)) y.c:12702 691 {*insv_regdi}
     (expr_list:REG_DEAD (reg/f:DI 481)
        (nil)))
---
Which eliminates the common symbol_refs, and gets cleaned up as:
---
(insn 1047 1044 1048 107 (set (reg/f:DI 481)
        (subreg:DI (reg/f:SI 477) 0)) y.c:12702 50 {*movdi_aarch64}
     (nil))
(insn 1048 1047 1049 107 (set (zero_extract:DI (reg/v:DI 191 [ obj1D.17368 ])
            (const_int 32 [0x20])
            (const_int 0 [0]))
        (reg/f:DI 481)) y.c:12702 691 {*insv_regdi}
     (nil))
---
The next major change is after combine, which merges the zero_extract in with
some other operations...
---

(insn 1047 1044 1048 101 (set (reg/f:DI 481)
        (subreg:DI (reg/f:SI 545) 0)) y.c:12702 50 {*movdi_aarch64}
     (nil))
(insn 1050 1049 1051 101 (set (reg:DI 1 x1)
        (ior:DI (ashift:DI (reg/v/f:DI 144 [ SR.305D.17382 ])
                (const_int 32 [0x20]))
            (reg/f:DI 481))) y.c:12702 507 {*ior_ashldi3}
     (expr_list:REG_DEAD (reg/v/f:DI 144 [ SR.305D.17382 ])
        (nil)))

---
Later, reload gets to it...
---
         Choosing alt 5 in insn 1047:  (0) r  (1) m {*movdi_aarch64}
          alt=0,overall=0,losers=0,rld_nregs=0
---
And here's what comes out the other side:
---

(insn 1047 1051 1050 102 (set (reg/f:DI 20 x20 [481])
        (mem/c:DI (plus:DI (reg/f:DI 29 x29)
                (const_int 112 [0x70])) [50 %sfpD.16965+-16 S8 A128]))
y.c:12702 50 {*movdi_aarch64}
     (nil))
---

So I have two questions.

First, where did the DImode paradoxical subreg come from in the first place,
and why wasn't it a zero-extend?

Second, why did reload decide it was safe to choose a memory location for a
paradoxical subreg and widen the size of the memory access?

Not marking it this as confirmed as I haven't verified the ISL code to check it
isn't breaking any Undefined Behavior rules.

Reply via email to