xref: /llvm-project/llvm/test/CodeGen/AArch64/freeze.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64-unknown-linux-gnu -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5; CHECK-GI:       warning: Instruction selection used fallback path for freeze_v2i8
6
7%struct.T = type { i32, i32 }
8
9define i32 @freeze_int() {
10; CHECK-LABEL: freeze_int:
11; CHECK:       // %bb.0:
12; CHECK-NEXT:    mul w0, w8, w8
13; CHECK-NEXT:    ret
14  %y1 = freeze i32 undef
15  %t1 = mul i32 %y1, %y1
16  ret i32 %t1
17}
18
19define i5 @freeze_int2() {
20; CHECK-LABEL: freeze_int2:
21; CHECK:       // %bb.0:
22; CHECK-NEXT:    mul w0, w8, w8
23; CHECK-NEXT:    ret
24  %y1 = freeze i5 undef
25  %t1 = mul i5 %y1, %y1
26  ret i5 %t1
27}
28
29define float @freeze_float() {
30; CHECK-LABEL: freeze_float:
31; CHECK:       // %bb.0:
32; CHECK-NEXT:    fadd s0, s0, s0
33; CHECK-NEXT:    ret
34  %y1 = freeze float undef
35  %t1 = fadd float %y1, %y1
36  ret float %t1
37}
38
39define <2 x i8> @freeze_v2i8() {
40; CHECK-LABEL: freeze_v2i8:
41; CHECK:       // %bb.0:
42; CHECK-NEXT:    add v0.2s, v0.2s, v0.2s
43; CHECK-NEXT:    ret
44  %y1 = freeze <2 x i8> undef
45  %t1 = add <2 x i8> %y1, %y1
46  ret <2 x i8> %t1
47}
48
49define <3 x i8> @freeze_v3i8() {
50; CHECK-SD-LABEL: freeze_v3i8:
51; CHECK-SD:       // %bb.0:
52; CHECK-SD-NEXT:    add v0.4h, v0.4h, v0.4h
53; CHECK-SD-NEXT:    umov w0, v0.h[0]
54; CHECK-SD-NEXT:    umov w1, v0.h[1]
55; CHECK-SD-NEXT:    umov w2, v0.h[2]
56; CHECK-SD-NEXT:    ret
57;
58; CHECK-GI-LABEL: freeze_v3i8:
59; CHECK-GI:       // %bb.0:
60; CHECK-GI-NEXT:    mov b0, v0.b[1]
61; CHECK-GI-NEXT:    mov b1, v0.b[2]
62; CHECK-GI-NEXT:    fmov w8, s0
63; CHECK-GI-NEXT:    mov v0.h[1], w8
64; CHECK-GI-NEXT:    fmov w8, s1
65; CHECK-GI-NEXT:    mov v0.h[2], w8
66; CHECK-GI-NEXT:    add v0.4h, v0.4h, v0.4h
67; CHECK-GI-NEXT:    umov w0, v0.h[0]
68; CHECK-GI-NEXT:    umov w1, v0.h[1]
69; CHECK-GI-NEXT:    umov w2, v0.h[2]
70; CHECK-GI-NEXT:    ret
71  %y1 = freeze <3 x i8> undef
72  %t1 = add <3 x i8> %y1, %y1
73  ret <3 x i8> %t1
74}
75
76define <4 x i8> @freeze_v4i8() {
77; CHECK-SD-LABEL: freeze_v4i8:
78; CHECK-SD:       // %bb.0:
79; CHECK-SD-NEXT:    add v0.4h, v0.4h, v0.4h
80; CHECK-SD-NEXT:    ret
81;
82; CHECK-GI-LABEL: freeze_v4i8:
83; CHECK-GI:       // %bb.0:
84; CHECK-GI-NEXT:    mov b0, v0.b[1]
85; CHECK-GI-NEXT:    fmov w8, s0
86; CHECK-GI-NEXT:    mov b1, v0.b[2]
87; CHECK-GI-NEXT:    mov v0.h[1], w8
88; CHECK-GI-NEXT:    fmov w8, s1
89; CHECK-GI-NEXT:    mov b2, v0.b[3]
90; CHECK-GI-NEXT:    mov v0.h[2], w8
91; CHECK-GI-NEXT:    fmov w8, s2
92; CHECK-GI-NEXT:    mov v0.h[3], w8
93; CHECK-GI-NEXT:    add v0.4h, v0.4h, v0.4h
94; CHECK-GI-NEXT:    ret
95  %y1 = freeze <4 x i8> undef
96  %t1 = add <4 x i8> %y1, %y1
97  ret <4 x i8> %t1
98}
99
100define <8 x i8> @freeze_v8i8() {
101; CHECK-LABEL: freeze_v8i8:
102; CHECK:       // %bb.0:
103; CHECK-NEXT:    add v0.8b, v0.8b, v0.8b
104; CHECK-NEXT:    ret
105  %y1 = freeze <8 x i8> undef
106  %t1 = add <8 x i8> %y1, %y1
107  ret <8 x i8> %t1
108}
109
110define <16 x i8> @freeze_v16i8() {
111; CHECK-LABEL: freeze_v16i8:
112; CHECK:       // %bb.0:
113; CHECK-NEXT:    add v0.16b, v0.16b, v0.16b
114; CHECK-NEXT:    ret
115  %y1 = freeze <16 x i8> undef
116  %t1 = add <16 x i8> %y1, %y1
117  ret <16 x i8> %t1
118}
119
120define <32 x i8> @freeze_v32i8() {
121; CHECK-LABEL: freeze_v32i8:
122; CHECK:       // %bb.0:
123; CHECK-NEXT:    add v0.16b, v0.16b, v0.16b
124; CHECK-NEXT:    mov v1.16b, v0.16b
125; CHECK-NEXT:    ret
126  %y1 = freeze <32 x i8> undef
127  %t1 = add <32 x i8> %y1, %y1
128  ret <32 x i8> %t1
129}
130
131define <2 x i16> @freeze_v2i16() {
132; CHECK-SD-LABEL: freeze_v2i16:
133; CHECK-SD:       // %bb.0:
134; CHECK-SD-NEXT:    add v0.2s, v0.2s, v0.2s
135; CHECK-SD-NEXT:    ret
136;
137; CHECK-GI-LABEL: freeze_v2i16:
138; CHECK-GI:       // %bb.0:
139; CHECK-GI-NEXT:    mov h0, v0.h[1]
140; CHECK-GI-NEXT:    mov v1.s[0], w8
141; CHECK-GI-NEXT:    fmov w8, s0
142; CHECK-GI-NEXT:    mov v1.s[1], w8
143; CHECK-GI-NEXT:    add v0.2s, v1.2s, v1.2s
144; CHECK-GI-NEXT:    ret
145  %y1 = freeze <2 x i16> undef
146  %t1 = add <2 x i16> %y1, %y1
147  ret <2 x i16> %t1
148}
149
150define <3 x i16> @freeze_v3i16() {
151; CHECK-LABEL: freeze_v3i16:
152; CHECK:       // %bb.0:
153; CHECK-NEXT:    add v0.4h, v0.4h, v0.4h
154; CHECK-NEXT:    ret
155  %y1 = freeze <3 x i16> undef
156  %t1 = add <3 x i16> %y1, %y1
157  ret <3 x i16> %t1
158}
159
160define <4 x i16> @freeze_v4i16() {
161; CHECK-LABEL: freeze_v4i16:
162; CHECK:       // %bb.0:
163; CHECK-NEXT:    add v0.4h, v0.4h, v0.4h
164; CHECK-NEXT:    ret
165  %y1 = freeze <4 x i16> undef
166  %t1 = add <4 x i16> %y1, %y1
167  ret <4 x i16> %t1
168}
169
170define <8 x i16> @freeze_v8i16() {
171; CHECK-LABEL: freeze_v8i16:
172; CHECK:       // %bb.0:
173; CHECK-NEXT:    add v0.8h, v0.8h, v0.8h
174; CHECK-NEXT:    ret
175  %y1 = freeze <8 x i16> undef
176  %t1 = add <8 x i16> %y1, %y1
177  ret <8 x i16> %t1
178}
179
180define <16 x i16> @freeze_v16i16() {
181; CHECK-LABEL: freeze_v16i16:
182; CHECK:       // %bb.0:
183; CHECK-NEXT:    add v0.8h, v0.8h, v0.8h
184; CHECK-NEXT:    mov v1.16b, v0.16b
185; CHECK-NEXT:    ret
186  %y1 = freeze <16 x i16> undef
187  %t1 = add <16 x i16> %y1, %y1
188  ret <16 x i16> %t1
189}
190
191define <2 x i32> @freeze_v2i32() {
192; CHECK-LABEL: freeze_v2i32:
193; CHECK:       // %bb.0:
194; CHECK-NEXT:    add v0.2s, v0.2s, v0.2s
195; CHECK-NEXT:    ret
196  %y1 = freeze <2 x i32> undef
197  %t1 = add <2 x i32> %y1, %y1
198  ret <2 x i32> %t1
199}
200
201define <3 x i32> @freeze_v3i32() {
202; CHECK-LABEL: freeze_v3i32:
203; CHECK:       // %bb.0:
204; CHECK-NEXT:    add v0.4s, v0.4s, v0.4s
205; CHECK-NEXT:    ret
206  %y1 = freeze <3 x i32> undef
207  %t1 = add <3 x i32> %y1, %y1
208  ret <3 x i32> %t1
209}
210
211define <4 x i32> @freeze_v4i32() {
212; CHECK-LABEL: freeze_v4i32:
213; CHECK:       // %bb.0:
214; CHECK-NEXT:    add v0.4s, v0.4s, v0.4s
215; CHECK-NEXT:    ret
216  %y1 = freeze <4 x i32> undef
217  %t1 = add <4 x i32> %y1, %y1
218  ret <4 x i32> %t1
219}
220
221define <8 x i32> @freeze_v8i32() {
222; CHECK-LABEL: freeze_v8i32:
223; CHECK:       // %bb.0:
224; CHECK-NEXT:    add v0.4s, v0.4s, v0.4s
225; CHECK-NEXT:    mov v1.16b, v0.16b
226; CHECK-NEXT:    ret
227  %y1 = freeze <8 x i32> undef
228  %t1 = add <8 x i32> %y1, %y1
229  ret <8 x i32> %t1
230}
231
232define <2 x i64> @freeze_v2i64() {
233; CHECK-LABEL: freeze_v2i64:
234; CHECK:       // %bb.0:
235; CHECK-NEXT:    add v0.2d, v0.2d, v0.2d
236; CHECK-NEXT:    ret
237  %y1 = freeze <2 x i64> undef
238  %t1 = add <2 x i64> %y1, %y1
239  ret <2 x i64> %t1
240}
241
242define <3 x i64> @freeze_v3i64() {
243; CHECK-SD-LABEL: freeze_v3i64:
244; CHECK-SD:       // %bb.0:
245; CHECK-SD-NEXT:    add v0.2d, v0.2d, v0.2d
246; CHECK-SD-NEXT:    fmov d2, d0
247; CHECK-SD-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
248; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 killed $q1
249; CHECK-SD-NEXT:    ret
250;
251; CHECK-GI-LABEL: freeze_v3i64:
252; CHECK-GI:       // %bb.0:
253; CHECK-GI-NEXT:    add v0.2d, v0.2d, v0.2d
254; CHECK-GI-NEXT:    add x8, x8, x8
255; CHECK-GI-NEXT:    fmov d2, x8
256; CHECK-GI-NEXT:    mov d1, v0.d[1]
257; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
258; CHECK-GI-NEXT:    ret
259  %y1 = freeze <3 x i64> undef
260  %t1 = add <3 x i64> %y1, %y1
261  ret <3 x i64> %t1
262}
263
264define <4 x i64> @freeze_v4i64() {
265; CHECK-LABEL: freeze_v4i64:
266; CHECK:       // %bb.0:
267; CHECK-NEXT:    add v0.2d, v0.2d, v0.2d
268; CHECK-NEXT:    mov v1.16b, v0.16b
269; CHECK-NEXT:    ret
270  %y1 = freeze <4 x i64> undef
271  %t1 = add <4 x i64> %y1, %y1
272  ret <4 x i64> %t1
273}
274
275define <2 x ptr> @freeze_v2p0() {
276; CHECK-SD-LABEL: freeze_v2p0:
277; CHECK-SD:       // %bb.0:
278; CHECK-SD-NEXT:    mov w8, #4 // =0x4
279; CHECK-SD-NEXT:    dup v0.2d, x8
280; CHECK-SD-NEXT:    add v0.2d, v0.2d, v0.2d
281; CHECK-SD-NEXT:    ret
282;
283; CHECK-GI-LABEL: freeze_v2p0:
284; CHECK-GI:       // %bb.0:
285; CHECK-GI-NEXT:    adrp x8, .LCPI21_0
286; CHECK-GI-NEXT:    ldr q0, [x8, :lo12:.LCPI21_0]
287; CHECK-GI-NEXT:    add v0.2d, v0.2d, v0.2d
288; CHECK-GI-NEXT:    ret
289  %y1 = freeze <2 x ptr> undef
290  %t1 = getelementptr i32, <2 x ptr> %y1, i32 1
291  ret <2 x ptr> %t1
292}
293
294define <3 x ptr> @freeze_v3p0() {
295; CHECK-SD-LABEL: freeze_v3p0:
296; CHECK-SD:       // %bb.0:
297; CHECK-SD-NEXT:    mov w8, #4 // =0x4
298; CHECK-SD-NEXT:    dup v2.2d, x8
299; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
300; CHECK-SD-NEXT:    add d2, d0, d2
301; CHECK-SD-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
302; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
303; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 killed $q1
304; CHECK-SD-NEXT:    ret
305;
306; CHECK-GI-LABEL: freeze_v3p0:
307; CHECK-GI:       // %bb.0:
308; CHECK-GI-NEXT:    adrp x8, .LCPI22_0
309; CHECK-GI-NEXT:    ldr q0, [x8, :lo12:.LCPI22_0]
310; CHECK-GI-NEXT:    add x8, x8, #4
311; CHECK-GI-NEXT:    fmov d2, x8
312; CHECK-GI-NEXT:    add v0.2d, v0.2d, v0.2d
313; CHECK-GI-NEXT:    mov d1, v0.d[1]
314; CHECK-GI-NEXT:    ret
315  %y1 = freeze <3 x ptr> undef
316  %t1 = getelementptr i32, <3 x ptr> %y1, i32 1
317  ret <3 x ptr> %t1
318}
319
320define <4 x ptr> @freeze_v4p0() {
321; CHECK-SD-LABEL: freeze_v4p0:
322; CHECK-SD:       // %bb.0:
323; CHECK-SD-NEXT:    mov w8, #4 // =0x4
324; CHECK-SD-NEXT:    dup v0.2d, x8
325; CHECK-SD-NEXT:    add v0.2d, v0.2d, v0.2d
326; CHECK-SD-NEXT:    mov v1.16b, v0.16b
327; CHECK-SD-NEXT:    ret
328;
329; CHECK-GI-LABEL: freeze_v4p0:
330; CHECK-GI:       // %bb.0:
331; CHECK-GI-NEXT:    adrp x8, .LCPI23_0
332; CHECK-GI-NEXT:    ldr q0, [x8, :lo12:.LCPI23_0]
333; CHECK-GI-NEXT:    add v0.2d, v0.2d, v0.2d
334; CHECK-GI-NEXT:    mov v1.16b, v0.16b
335; CHECK-GI-NEXT:    ret
336  %y1 = freeze <4 x ptr> undef
337  %t1 = getelementptr i32, <4 x ptr> %y1, i32 1
338  ret <4 x ptr> %t1
339}
340
341define ptr @freeze_ptr() {
342; CHECK-LABEL: freeze_ptr:
343; CHECK:       // %bb.0:
344; CHECK-NEXT:    add x0, x8, #4
345; CHECK-NEXT:    ret
346  %y1 = freeze ptr undef
347  %t1 = getelementptr i8, ptr %y1, i64 4
348  ret ptr %t1
349}
350
351define i32 @freeze_struct() {
352; CHECK-LABEL: freeze_struct:
353; CHECK:       // %bb.0:
354; CHECK-NEXT:    add w0, w8, w8
355; CHECK-NEXT:    ret
356  %y1 = freeze %struct.T undef
357  %v1 = extractvalue %struct.T %y1, 0
358  %v2 = extractvalue %struct.T %y1, 1
359  %t1 = add i32 %v1, %v2
360  ret i32 %t1
361}
362
363define i32 @freeze_anonstruct() {
364; CHECK-LABEL: freeze_anonstruct:
365; CHECK:       // %bb.0:
366; CHECK-NEXT:    add w0, w8, w8
367; CHECK-NEXT:    ret
368  %y1 = freeze {i32, i32} undef
369  %v1 = extractvalue {i32, i32} %y1, 0
370  %v2 = extractvalue {i32, i32} %y1, 1
371  %t1 = add i32 %v1, %v2
372  ret i32 %t1
373}
374
375define i32 @freeze_anonstruct2() {
376; CHECK-LABEL: freeze_anonstruct2:
377; CHECK:       // %bb.0:
378; CHECK-NEXT:    add w0, w8, w8, uxth
379; CHECK-NEXT:    ret
380  %y1 = freeze {i32, i16} undef
381  %v1 = extractvalue {i32, i16} %y1, 0
382  %v2 = extractvalue {i32, i16} %y1, 1
383  %z2 = zext i16 %v2 to i32
384  %t1 = add i32 %v1, %z2
385  ret i32 %t1
386}
387
388define i64 @freeze_array() {
389; CHECK-LABEL: freeze_array:
390; CHECK:       // %bb.0:
391; CHECK-NEXT:    add x0, x8, x8
392; CHECK-NEXT:    ret
393  %y1 = freeze [2 x i64] undef
394  %v1 = extractvalue [2 x i64] %y1, 0
395  %v2 = extractvalue [2 x i64] %y1, 1
396  %t1 = add i64 %v1, %v2
397  ret i64 %t1
398}
399