Skip to content

Commit 31f81e9

Browse files
authored
[RA] Don't split a register generated from another split (llvm#67351)
Split a register generated from another split usually doesn't bring us too much benefit. It may also cause dead loop as pr67188 shows if the heuristic cost always satisfy the split condition. So prevent such splitting. It fixed pr67188.
1 parent 65eb468 commit 31f81e9

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,10 @@ bool RAGreedy::trySplitAroundHintReg(MCPhysReg Hint,
12181218
const LiveInterval &VirtReg,
12191219
SmallVectorImpl<Register> &NewVRegs,
12201220
AllocationOrder &Order) {
1221+
// Don't allow repeated splitting as a safe guard against looping.
1222+
if (ExtraInfo->getStage(VirtReg) >= RS_Split2)
1223+
return false;
1224+
12211225
BlockFrequency Cost = 0;
12221226
Register Reg = VirtReg.reg();
12231227

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2+
# RUN: llc -o - %s -run-pass=greedy | FileCheck %s
3+
#
4+
# Make sure we don't run into dead loop when split register with a hint.
5+
6+
--- |
7+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
8+
target triple = "aarch64-none-linux-gnu"
9+
10+
define void @foo(ptr %0, i32 %1) gc "statepoint-example" personality ptr null {
11+
bci_0:
12+
unreachable
13+
14+
bci_19:
15+
unreachable
16+
17+
bci_10:
18+
unreachable
19+
}
20+
21+
...
22+
---
23+
name: foo
24+
alignment: 4
25+
exposesReturnsTwice: false
26+
legalized: false
27+
regBankSelected: false
28+
selected: false
29+
failedISel: false
30+
tracksRegLiveness: true
31+
hasWinCFI: false
32+
callsEHReturn: false
33+
callsUnwindInit: false
34+
hasEHCatchret: false
35+
hasEHScopes: false
36+
hasEHFunclets: false
37+
isOutlined: false
38+
debugInstrRef: false
39+
failsVerification: false
40+
tracksDebugUserValues: false
41+
registers:
42+
- { id: 0, class: gpr64, preferred-register: '' }
43+
- { id: 1, class: gpr32, preferred-register: '' }
44+
- { id: 2, class: gpr32, preferred-register: '' }
45+
- { id: 3, class: gpr64all, preferred-register: '' }
46+
- { id: 4, class: gpr64all, preferred-register: '' }
47+
- { id: 5, class: gpr32all, preferred-register: '' }
48+
liveins:
49+
- { reg: '$w1', virtual-reg: '%1' }
50+
frameInfo:
51+
isFrameAddressTaken: false
52+
isReturnAddressTaken: false
53+
hasStackMap: false
54+
hasPatchPoint: false
55+
stackSize: 0
56+
offsetAdjustment: 0
57+
maxAlignment: 1
58+
adjustsStack: true
59+
hasCalls: true
60+
stackProtector: ''
61+
functionContext: ''
62+
maxCallFrameSize: 0
63+
cvBytesOfCalleeSavedRegisters: 0
64+
hasOpaqueSPAdjustment: false
65+
hasVAStart: false
66+
hasMustTailInVarArgFunc: false
67+
hasTailCall: false
68+
localFrameSize: 0
69+
savePoint: ''
70+
restorePoint: ''
71+
fixedStack: []
72+
stack: []
73+
entry_values: []
74+
callSites: []
75+
debugValueSubstitutions: []
76+
constants: []
77+
machineFunctionInfo: {}
78+
body: |
79+
; CHECK-LABEL: name: foo
80+
; CHECK: bb.0.bci_0:
81+
; CHECK-NEXT: successors: %bb.1(0x80000000)
82+
; CHECK-NEXT: liveins: $w1
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
85+
; CHECK-NEXT: {{ $}}
86+
; CHECK-NEXT: bb.1.bci_19:
87+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
88+
; CHECK-NEXT: $x0 = COPY $xzr
89+
; CHECK-NEXT: STATEPOINT 0, 0, 1, $xzr, killed $x0, 2, 0, 2, 0, 2, 33, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, [[COPY]], 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 1, 0, 0, csr_aarch64_aapcs, implicit-def $sp, implicit-def dead $x0, implicit-def dead early-clobber $lr
90+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
91+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
92+
; CHECK-NEXT: $w0 = COPY $wzr
93+
; CHECK-NEXT: STATEPOINT 0, 0, 1, $xzr, killed $w0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, csr_aarch64_aapcs, implicit-def $sp, implicit-def dead early-clobber $lr
94+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
95+
bb.0.bci_0:
96+
successors: %bb.1(0x80000000)
97+
liveins: $w1
98+
99+
%1:gpr32 = COPY $w1
100+
101+
bb.1.bci_19:
102+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
103+
$x0 = COPY $xzr
104+
STATEPOINT 0, 0, 1, $xzr, killed $x0, 2, 0, 2, 0, 2, 33, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, %1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 1, 0, 0, csr_aarch64_aapcs, implicit-def $sp, implicit-def dead $x0, implicit-def dead early-clobber $lr
105+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
106+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
107+
$w0 = COPY $wzr
108+
STATEPOINT 0, 0, 1, $xzr, killed $w0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, csr_aarch64_aapcs, implicit-def $sp, implicit-def dead early-clobber $lr
109+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
110+
111+
...

0 commit comments

Comments
 (0)