Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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
- Loading branch information
1 parent
2fc704a
commit 7360d6d
Showing
3 changed files
with
156 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
; RUN: llc --verify-machineinstrs %s -o - | FileCheck %s | ||
|
||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
target triple = "thumbv7m-unknown-unknown-eabi" | ||
|
||
declare dso_local i32 @h0(i32, i32) local_unnamed_addr #1 | ||
|
||
define dso_local i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) local_unnamed_addr #0 { | ||
entry: | ||
%add = add nsw i32 %a, 1 | ||
%sub = add nsw i32 %b, -1 | ||
%call = tail call i32 @h0(i32 %add, i32 %sub) #0 | ||
%add1 = add nsw i32 %c, %b | ||
%mul = shl nsw i32 %call, 1 | ||
%add2 = add nsw i32 %mul, %add1 | ||
%sub3 = sub nsw i32 %c, %d | ||
%mul4 = mul nsw i32 %add2, %sub3 | ||
%sub5 = sub nsw i32 %call, %add1 | ||
%div = sdiv i32 %mul4, %sub5 | ||
%add6 = add nsw i32 %d, %c | ||
%mul7 = mul nsw i32 %div, %add6 | ||
%add8 = add nsw i32 %mul7, 1 | ||
ret i32 %add8 | ||
} | ||
; CHECK-LABEL: f: | ||
; CHECK: bl h0 | ||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0 | ||
; CHECK-NEXT: adds r0, #1 | ||
; CHECK-NEXT: pop {r4, r5, r6, pc} | ||
|
||
|
||
define dso_local i32 @g(i32 %a, i32 %b, i32 %c, i32 %d) local_unnamed_addr #0 { | ||
entry: | ||
%sub = add nsw i32 %a, -1 | ||
%add = add nsw i32 %b, 1 | ||
%call = tail call i32 @h0(i32 %sub, i32 %add) #0 | ||
%add1 = add nsw i32 %c, %b | ||
%mul = shl nsw i32 %call, 1 | ||
%add2 = add nsw i32 %mul, %add1 | ||
%sub3 = sub nsw i32 %c, %d | ||
%mul4 = mul nsw i32 %add2, %sub3 | ||
%sub5 = sub nsw i32 %call, %add1 | ||
%div = sdiv i32 %mul4, %sub5 | ||
%add6 = add nsw i32 %d, %c | ||
%mul7 = mul nsw i32 %div, %add6 | ||
%add8 = add nsw i32 %mul7, 2 | ||
ret i32 %add8 | ||
} | ||
; CHECK-LABEL: g: | ||
; CHECK: bl h0 | ||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0 | ||
; CHECK-NEXT: adds r0, #2 | ||
; CHECK-NEXT: pop {r4, r5, r6, pc} | ||
|
||
|
||
attributes #0 = { minsize nounwind optsize } | ||
attributes #1 = { minsize optsize } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
; RUN: llc -verify-machineinstrs %s -o - | FileCheck %s | ||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
target triple = "thumbv7m-unknown-unknown-eabi" | ||
|
||
declare dso_local i32 @t(i32) local_unnamed_addr #0 | ||
|
||
define dso_local i32 @f(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { | ||
entry: | ||
%mul = mul nsw i32 %a, 3 | ||
%add = add nsw i32 %mul, 1 | ||
%sub = add nsw i32 %b, -1 | ||
%div = sdiv i32 %add, %sub | ||
%sub1 = sub nsw i32 %a, %c | ||
%div2 = sdiv i32 %div, %sub1 | ||
%mul3 = mul nsw i32 %div2, %b | ||
%add4 = add nsw i32 %mul3, 1 | ||
%call = tail call i32 @t(i32 %add4) #0 | ||
ret i32 %call | ||
} | ||
; CHECK-LABEL: f: | ||
; CHECK: str lr, [sp, #-8]! | ||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0 | ||
; CHECK-NEXT: ldr lr, [sp], #8 | ||
; CHECK-NEXT: adds r0, #1 | ||
; CHECK-NEXT: b t | ||
|
||
define dso_local i32 @g(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { | ||
entry: | ||
%mul = mul nsw i32 %a, 3 | ||
%add = add nsw i32 %mul, 1 | ||
%sub = add nsw i32 %b, -1 | ||
%div = sdiv i32 %add, %sub | ||
%sub1 = sub nsw i32 %a, %c | ||
%div2 = sdiv i32 %div, %sub1 | ||
%mul3 = mul nsw i32 %div2, %b | ||
%add4 = add nsw i32 %mul3, 3 | ||
%call = tail call i32 @t(i32 %add4) #0 | ||
ret i32 %call | ||
} | ||
|
||
; CHECK-LABEL: g: | ||
; CHECK: str lr, [sp, #-8]! | ||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0 | ||
; CHECK-NEXT: ldr lr, [sp], #8 | ||
; CHECK-NEXT: adds r0, #3 | ||
; CHECK-NEXT: b t | ||
|
||
; CHECK-LABEL: OUTLINED_FUNCTION_0: | ||
; CHECK-NOT: lr | ||
; CHECK: bx lr | ||
|
||
attributes #0 = { minsize nounwind optsize } |