1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
| # RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s -o - | FileCheck %s
--- |
declare void @f2()
define void @func0() { ret void }
define void @func1() { ret void }
define void @func2() { ret void }
...
---
# Check coalescing of COPYs from reserved physregs.
# CHECK-LABEL: name: func0
name: func0
body: |
bb.0:
; We usually should not coalesce copies from allocatable physregs.
; CHECK: %0:gpr32 = COPY $w7
; CHECK: STRWui %0, $x1, 0
%0 : gpr32 = COPY $w7
STRWui %0, $x1, 0
; It is fine to coalesce copies from reserved physregs
; CHECK-NOT: COPY
; CHECK: STRXui $fp, $x1, 0
%1 : gpr64 = COPY $fp
STRXui %1, $x1, 0
; It is not fine to coalesce copies from reserved physregs when they are
; clobbered.
; CHECK: %2:gpr64 = COPY $fp
; CHECK: STRXui %2, $x1, 0
%2 : gpr64 = COPY $fp
$fp = SUBXri $fp, 4, 0
STRXui %2, $x1, 0
; Is is fine to coalesce copies from constant physregs even when they are
; clobbered.
; CHECK-NOT: COPY
; CHECK: STRWui $wzr, $x1
%3 : gpr32 = COPY $wzr
dead $wzr = SUBSWri $w1, 0, 0, implicit-def $nzcv
STRWui %3, $x1, 0
; Is is fine to coalesce copies from constant physregs even when they are
; clobbered.
; CHECK-NOT: COPY
; CHECK: STRXui $xzr, $x1
%4 : gpr64 = COPY $xzr
dead $wzr = SUBSWri $w1, 0, 0, implicit-def $nzcv
STRXui %4, $x1, 0
; Coalescing COPYs into constant physregs.
; CHECK: $wzr = SUBSWri $w1, 0, 0
%5 : gpr32 = SUBSWri $w1, 0, 0, implicit-def $nzcv
$wzr = COPY %5
; Only coalesce when the source register is reserved as a whole (this is
; a limitation of the current code which cannot update liveness information
; of the non-reserved part).
; CHECK: %6:xseqpairsclass = COPY $x28_fp
; CHECK: HINT 0, implicit %6
%6 : xseqpairsclass = COPY $x28_fp
HINT 0, implicit %6
; It is not fine to coalesce copies from reserved physregs when they are
; clobbered by the regmask on a call.
; CHECK: %7:gpr64 = COPY $x18
; CHECK: BL @f2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
; CHECK: STRXui %7, $x1, 0
; Need a def of x18 so that it's not deduced as "constant".
$x18 = COPY $xzr
%7 : gpr64 = COPY $x18
BL @f2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
STRXui %7, $x1, 0
; This can be coalesced.
; CHECK: $fp = SUBXri $fp, 4, 0
%8 : gpr64sp = SUBXri $fp, 4, 0
$fp = COPY %8
; Cannot coalesce when there are reads of the physreg.
; CHECK-NOT: $fp = SUBXri $fp, 8, 0
; CHECK: %9:gpr64sp = SUBXri $fp, 8, 0
; CHECK: STRXui $fp, $fp, 0
; CHECK: $fp = COPY %9
%9 : gpr64sp = SUBXri $fp, 8, 0
STRXui $fp, $fp, 0
$fp = COPY %9
...
---
# Check coalescing of COPYs from reserved physregs.
# CHECK-LABEL: name: func1
name: func1
body: |
bb.0:
; Cannot coalesce physreg because we have reads on other CFG paths (we
; currently abort for any control flow)
; CHECK-NOT: $fp = SUBXri
; CHECK: %0:gpr64sp = SUBXri $fp, 12, 0
; CHECK: CBZX undef $x0, %bb.1
; CHECK: B %bb.2
%0 : gpr64sp = SUBXri $fp, 12, 0
CBZX undef $x0, %bb.1
B %bb.2
bb.1:
$fp = COPY %0
RET_ReallyLR
bb.2:
STRXui $fp, $fp, 0
RET_ReallyLR
...
---
# CHECK-LABEL: name: func2
name: func2
body: |
bb.0:
; We can coalesce copies from physreg to vreg across multiple blocks.
; CHECK-NOT: COPY
; CHECK: CBZX undef $x0, %bb.1
; CHECK-NEXT: B %bb.2
%0 : gpr64sp = COPY $fp
CBZX undef $x0, %bb.1
B %bb.2
bb.1:
; CHECK: STRXui undef $x0, $fp, 0
; CHECK-NEXT: RET_ReallyLR
STRXui undef $x0, %0, 0
RET_ReallyLR
bb.2:
RET_ReallyLR
...
|