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.
I think we can get ride of passing nullptr since it is TRI default value in the prototype