diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2020-11-02 16:26:10 +0000 |
---|---|---|
committer | Momchil Velikov <momchil.velikov@arm.com> | 2020-11-02 16:47:22 +0000 |
commit | 7360d6d921c67e92cc82635112e72fb2a59aacf4 (patch) | |
tree | ca93824ee544275497a4e36e8ae717471af451b0 /clang/lib/Frontend/CompilerInvocation.cpp | |
parent | 2fc704a0a529dd7eba7566a293f981a86bfa5c3e (diff) | |
download | llvm-7360d6d921c67e92cc82635112e72fb2a59aacf4.zip llvm-7360d6d921c67e92cc82635112e72fb2a59aacf4.tar.gz llvm-7360d6d921c67e92cc82635112e72fb2a59aacf4.tar.bz2 |
[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
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
0 files changed, 0 insertions, 0 deletions