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

            Bug ID: 80352
           Summary: Improper reload of operands with equiv pseudo
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Keywords: ra
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: thopre01 at gcc dot gnu.org
                CC: vmakarov at gcc dot gnu.org
  Target Milestone: ---

Hi,

r235184 introduced the ability to reload expressions with equiv but reload
happens incorrectly due to some failed assumptions:

1) Endless series of reloads due to creation of pseudo reg with NO_REGS class

When a memory constraint is matched to an expression with equiv, the
alternative is given the default class: NO_REGS. In curr_insn_transform the
memory reload code is skipped because MEM_P is false and instead the default
register reload is used. It creates a pseudo reg with the class from goal_alt
hence NO_REGS. When analyzing this new insn process_alt_operands fails the
in_class_p check for the register because its class (NO_REGS) have no intersect
with GENERAL_REGS (from the subunion). A reload must then happen again, etc.

2) reload_nregs is increased despite needing a register reload

reload_nregs is only updated when !no_regs_p is true. Hence the cost of memory
reload is not accurate. Fortunately the fix from Jiong in r237277 seems to be
enough to avoid memory reload when register reload is available.


I believe the issues are due to the assumption that memory constraint does not
need a register and has different reload. However with expression with equiv a
register reload is needed followed by a register spill. Regarding 2) winreg
could be used to signal a register is needed and the check to update
reload_nregs use winreg instead. I am not sure how to solve 1) but I believe
get_reload_reg should no be called with NO_REGS class (an assert could be added
btw).

The issue can be reproduced on arm-none-eabi target by compiling the below code
with arm-none-eabi-gcc -S -mcpu=cortex-m7 -mthumb -O2:

void fn2(int *);

void fn1() {
  int a[1];

  while (1)
    fn2(a);
}

Reply via email to