HomePhabricator

[ARM][MachineOutliner] Do not overestimate LR liveness in return block

Authored by chill on Nov 2 2020, 8:26 AM.

Description

[ARM][MachineOutliner] Do not overestimate LR liveness in return block

The LiveRegUnits utility (as well as LivePhysRegs) considers
callee-saved registers to be alive at the point after the return
instruction in a block. In the ARM backend, the LR register is
classified as callee-saved, which is not really correct (from an ARM
eABI or just common sense point of view). These two conditions cause
the MachineOutliner to overestimate the liveness of LR, which
results in unnecessary saves/restores of LR around calls to outlined
sequences. It also causes the MachineVerifer to crash in some
cases, because the save instruction reads a dead LR, for example
when the following program:

int h(int, int);

int f(int a, int b, int c, int d) {

a = h(a + 1, b - 1);
b = b + c;
return 1 + (2 * a + b) * (c - d) / (a - b) * (c + d);

}

int g(int a, int b, int c, int d) {

a = h(a - 1, b + 1);
b = b + c;
return 2 + (2 * a + b) * (c - d) / (a - b) * (c + d);

}

is compiled with -target arm-eabi -march=armv7-m -Oz.

This patch computes the liveness of LR in return blocks only, while
taking into account the few ARM instructions, which read LR, but
nevertheless the register is not mentioned (explicitly or implicitly)
in the instruction operands.

Differential Revision: https://reviews.llvm.org/D89189