33# RUN: llc -mtriple=riscv64 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \
44# RUN: | FileCheck -check-prefixes=OUTLINED,RV64I-MO %s
55
6- # CFIs are invisible (they can be outlined, but won't actually impact the outlining result) if there
7- # is no need to unwind. CFIs will be stripped when we build outlined functions.
6+ # Combined tests for outlining with CFI instructions on RISC-V:
7+ # 1) All CFIs present in candidate: outline as tail-call and keep CFIs.
8+ # 2) Partial CFIs in function (extra outside candidate): do not outline.
9+ # 3) CFIs present but candidate is not a tail-call: do not outline.
810
911--- |
10- define void @func1(i32 %a, i32 %b) nounwind { ret void }
11-
12- define void @func2(i32 %a, i32 %b) nounwind { ret void }
13-
14- define void @func3(i32 %a, i32 %b) nounwind { ret void }
12+ define void @funcA(i32 %a, i32 %b) nounwind { ret void }
13+ define void @funcB(i32 %a, i32 %b) nounwind { ret void }
14+ define void @funcC(i32 %a, i32 %b) nounwind { ret void }
15+ define void @funcD(i32 %a, i32 %b) nounwind { ret void }
16+ define void @funcE(i32 %a, i32 %b) nounwind { ret void }
17+ define void @funcF(i32 %a, i32 %b) nounwind { ret void }
1518...
19+
20+ # Case 1: All CFIs present; expect outlining and CFIs retained in outlined body.
1621---
17- name : func1
22+ name : funcA
1823tracksRegLiveness : true
1924body : |
2025 bb.0:
2126 liveins: $x10, $x11
22- ; RV32I-MO-LABEL: name: func1
27+ ; RV32I-MO-LABEL: name: funcA
2328 ; RV32I-MO: liveins: $x10, $x11
2429 ; RV32I-MO-NEXT: {{ $}}
2530 ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
26- ; RV64I-MO-LABEL: name: func1
31+ ;
32+ ; RV64I-MO-LABEL: name: funcA
2733 ; RV64I-MO: liveins: $x10, $x11
2834 ; RV64I-MO-NEXT: {{ $}}
2935 ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
@@ -39,62 +45,213 @@ body: |
3945 PseudoRET
4046 ...
4147---
42- name : func2
48+ name : funcB
4349tracksRegLiveness : true
4450body : |
4551 bb.0:
4652 liveins: $x10, $x11
47- ; RV32I-MO-LABEL: name: func2
53+ ; RV32I-MO-LABEL: name: funcB
4854 ; RV32I-MO: liveins: $x10, $x11
4955 ; RV32I-MO-NEXT: {{ $}}
5056 ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
51- ; RV64I-MO-LABEL: name: func2
57+ ;
58+ ; RV64I-MO-LABEL: name: funcB
5259 ; RV64I-MO: liveins: $x10, $x11
5360 ; RV64I-MO-NEXT: {{ $}}
5461 ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
5562 $x10 = ORI $x10, 1023
5663 CFI_INSTRUCTION offset $x1, 0
5764 $x11 = ORI $x11, 1023
58- CFI_INSTRUCTION offset $x1, -8
59- $x12 = ADDI $x10, 17
6065 CFI_INSTRUCTION offset $x1, -4
66+ $x12 = ADDI $x10, 17
67+ CFI_INSTRUCTION offset $x1, -8
6168 $x11 = AND $x12, $x11
6269 CFI_INSTRUCTION offset $x1, -12
6370 $x10 = SUB $x10, $x11
6471 PseudoRET
6572 ...
73+
74+ # Case 2: Partial CFIs (extra CFI outside candidate in funcD); expect no outlining.
6675---
67- name : func3
76+ name : funcC
6877tracksRegLiveness : true
6978body : |
7079 bb.0:
7180 liveins: $x10, $x11
72- ; RV32I-MO-LABEL: name: func3
81+ ; RV32I-MO-LABEL: name: funcC
7382 ; RV32I-MO: liveins: $x10, $x11
7483 ; RV32I-MO-NEXT: {{ $}}
7584 ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
76- ; RV64I-MO-LABEL: name: func3
85+ ;
86+ ; RV64I-MO-LABEL: name: funcC
7787 ; RV64I-MO: liveins: $x10, $x11
7888 ; RV64I-MO-NEXT: {{ $}}
7989 ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
8090 $x10 = ORI $x10, 1023
81- CFI_INSTRUCTION offset $x1, -12
91+ CFI_INSTRUCTION offset $x1, 0
8292 $x11 = ORI $x11, 1023
93+ CFI_INSTRUCTION offset $x1, -4
94+ $x12 = ADDI $x10, 17
8395 CFI_INSTRUCTION offset $x1, -8
96+ $x11 = AND $x12, $x11
97+ CFI_INSTRUCTION offset $x1, -12
98+ $x10 = SUB $x10, $x11
99+ PseudoRET
100+ ...
101+ ---
102+ name : funcD
103+ tracksRegLiveness : true
104+ body : |
105+ bb.0:
106+ liveins: $x10, $x11
107+ ; RV32I-MO-LABEL: name: funcD
108+ ; RV32I-MO: liveins: $x10, $x11
109+ ; RV32I-MO-NEXT: {{ $}}
110+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -16
111+ ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023
112+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
113+ ; RV32I-MO-NEXT: $x11 = ORI $x11, 1023
114+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
115+ ; RV32I-MO-NEXT: $x12 = ADDI $x10, 17
116+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
117+ ; RV32I-MO-NEXT: $x11 = AND $x12, $x11
118+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
119+ ; RV32I-MO-NEXT: $x10 = SUB $x10, $x11
120+ ; RV32I-MO-NEXT: PseudoRET
121+ ;
122+ ; RV64I-MO-LABEL: name: funcD
123+ ; RV64I-MO: liveins: $x10, $x11
124+ ; RV64I-MO-NEXT: {{ $}}
125+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -16
126+ ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023
127+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
128+ ; RV64I-MO-NEXT: $x11 = ORI $x11, 1023
129+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
130+ ; RV64I-MO-NEXT: $x12 = ADDI $x10, 17
131+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
132+ ; RV64I-MO-NEXT: $x11 = AND $x12, $x11
133+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
134+ ; RV64I-MO-NEXT: $x10 = SUB $x10, $x11
135+ ; RV64I-MO-NEXT: PseudoRET
136+ CFI_INSTRUCTION offset $x1, -16
137+ $x10 = ORI $x10, 1023
138+ CFI_INSTRUCTION offset $x1, 0
139+ $x11 = ORI $x11, 1023
140+ CFI_INSTRUCTION offset $x1, -4
84141 $x12 = ADDI $x10, 17
142+ CFI_INSTRUCTION offset $x1, -8
143+ $x11 = AND $x12, $x11
144+ CFI_INSTRUCTION offset $x1, -12
145+ $x10 = SUB $x10, $x11
146+ PseudoRET
147+ ...
148+
149+ # Case 3: CFIs present but candidate is not a tail-call; expect no outlining.
150+ ---
151+ name : funcE
152+ tracksRegLiveness : true
153+ body : |
154+ bb.0:
155+ liveins: $x10, $x11
156+ ; RV32I-MO-LABEL: name: funcE
157+ ; RV32I-MO: liveins: $x10, $x11
158+ ; RV32I-MO-NEXT: {{ $}}
159+ ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023
160+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
161+ ; RV32I-MO-NEXT: $x11 = ORI $x11, 1023
162+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
163+ ; RV32I-MO-NEXT: $x12 = ADDI $x10, 17
164+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
165+ ; RV32I-MO-NEXT: $x11 = AND $x12, $x11
166+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
167+ ; RV32I-MO-NEXT: $x10 = SUB $x10, $x11
168+ ; RV32I-MO-NEXT: $x10 = ADDI $x10, 1
169+ ; RV32I-MO-NEXT: PseudoRET
170+ ;
171+ ; RV64I-MO-LABEL: name: funcE
172+ ; RV64I-MO: liveins: $x10, $x11
173+ ; RV64I-MO-NEXT: {{ $}}
174+ ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023
175+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
176+ ; RV64I-MO-NEXT: $x11 = ORI $x11, 1023
177+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
178+ ; RV64I-MO-NEXT: $x12 = ADDI $x10, 17
179+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
180+ ; RV64I-MO-NEXT: $x11 = AND $x12, $x11
181+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
182+ ; RV64I-MO-NEXT: $x10 = SUB $x10, $x11
183+ ; RV64I-MO-NEXT: $x10 = ADDI $x10, 1
184+ ; RV64I-MO-NEXT: PseudoRET
185+ $x10 = ORI $x10, 1023
186+ CFI_INSTRUCTION offset $x1, 0
187+ $x11 = ORI $x11, 1023
85188 CFI_INSTRUCTION offset $x1, -4
189+ $x12 = ADDI $x10, 17
190+ CFI_INSTRUCTION offset $x1, -8
86191 $x11 = AND $x12, $x11
192+ CFI_INSTRUCTION offset $x1, -12
193+ $x10 = SUB $x10, $x11
194+ $x10 = ADDI $x10, 1
195+ PseudoRET
196+ ...
197+ ---
198+ name : funcF
199+ tracksRegLiveness : true
200+ body : |
201+ bb.0:
202+ liveins: $x10, $x11
203+ ; RV32I-MO-LABEL: name: funcF
204+ ; RV32I-MO: liveins: $x10, $x11
205+ ; RV32I-MO-NEXT: {{ $}}
206+ ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023
207+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
208+ ; RV32I-MO-NEXT: $x11 = ORI $x11, 1023
209+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
210+ ; RV32I-MO-NEXT: $x12 = ADDI $x10, 17
211+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
212+ ; RV32I-MO-NEXT: $x11 = AND $x12, $x11
213+ ; RV32I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
214+ ; RV32I-MO-NEXT: $x10 = SUB $x10, $x11
215+ ; RV32I-MO-NEXT: $x10 = ADDI $x10, 2
216+ ; RV32I-MO-NEXT: PseudoRET
217+ ;
218+ ; RV64I-MO-LABEL: name: funcF
219+ ; RV64I-MO: liveins: $x10, $x11
220+ ; RV64I-MO-NEXT: {{ $}}
221+ ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023
222+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, 0
223+ ; RV64I-MO-NEXT: $x11 = ORI $x11, 1023
224+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -4
225+ ; RV64I-MO-NEXT: $x12 = ADDI $x10, 17
226+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -8
227+ ; RV64I-MO-NEXT: $x11 = AND $x12, $x11
228+ ; RV64I-MO-NEXT: CFI_INSTRUCTION offset $x1, -12
229+ ; RV64I-MO-NEXT: $x10 = SUB $x10, $x11
230+ ; RV64I-MO-NEXT: $x10 = ADDI $x10, 2
231+ ; RV64I-MO-NEXT: PseudoRET
232+ $x10 = ORI $x10, 1023
87233 CFI_INSTRUCTION offset $x1, 0
234+ $x11 = ORI $x11, 1023
235+ CFI_INSTRUCTION offset $x1, -4
236+ $x12 = ADDI $x10, 17
237+ CFI_INSTRUCTION offset $x1, -8
238+ $x11 = AND $x12, $x11
239+ CFI_INSTRUCTION offset $x1, -12
88240 $x10 = SUB $x10, $x11
241+ $x10 = ADDI $x10, 2
89242 PseudoRET
90-
243+ ...
91244
92245# OUTLINED-LABEL: name: OUTLINED_FUNCTION_0
93246# OUTLINED: liveins: $x11, $x10
94247# OUTLINED-NEXT: {{ $}}
95248# OUTLINED-NEXT: $x10 = ORI $x10, 1023
249+ # OUTLINED-NEXT: CFI_INSTRUCTION offset $x1, 0
96250# OUTLINED-NEXT: $x11 = ORI $x11, 1023
251+ # OUTLINED-NEXT: CFI_INSTRUCTION offset $x1, -4
97252# OUTLINED-NEXT: $x12 = ADDI $x10, 17
253+ # OUTLINED-NEXT: CFI_INSTRUCTION offset $x1, -8
98254# OUTLINED-NEXT: $x11 = AND $x12, $x11
255+ # OUTLINED-NEXT: CFI_INSTRUCTION offset $x1, -12
99256# OUTLINED-NEXT: $x10 = SUB $x10, $x11
100257# OUTLINED-NEXT: PseudoRET
0 commit comments