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

Richard Sandiford <rsandifo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rsandifo at gcc dot gnu.org

--- Comment #6 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
The problem seems to be that may_trap_or_fault_p returns true for the memory,
which stops loop2_invariant from hoisting the load.  The code there is:

      if (/* MEM_NOTRAP_P only relates to the actual position of the memory
             reference; moving it out of context such as when moving code
             when optimizing, might cause its address to become invalid.  */
          code_changed
          || !MEM_NOTRAP_P (x))
        {
          poly_int64 size = MEM_SIZE_KNOWN_P (x) ? MEM_SIZE (x) : -1;
          return rtx_addr_can_trap_p_1 (XEXP (x, 0), 0, size,
                                        GET_MODE (x), code_changed);
        }

(where code_changed is true).  Since the SVE load doesn't support the full
LO_SUM range, there is no hint that the address refers to invariant memory.

I'm not sure the comment in the code is correct for MEM_READONLY_P, which only
refers to _statically allocated_ readonly memory.  (At least, the comment
doesn't apply to constant memory created by force_const_mem, which creates
things that cannot trap regardless of context.)  Adding:

      if (MEM_READONLY_P (x) && MEM_NOTRAP_P (x))
        return false;

makes the test work for me.

Reply via email to