xref: /llvm-project/llvm/test/CodeGen/SystemZ/int-conv-14.ll (revision a65ccc1b9fe740c9f65d9cf2b627de50278aad56)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2; Test 128-bit arithmetic in vector registers on z13
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
5
6; Sign extension from i64.
7define i128 @f1(i64 %a) {
8; CHECK-LABEL: f1:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    srag %r0, %r3, 63
11; CHECK-NEXT:    vlvgp %v0, %r0, %r3
12; CHECK-NEXT:    vst %v0, 0(%r2), 3
13; CHECK-NEXT:    br %r14
14  %res = sext i64 %a to i128
15  ret i128 %res
16}
17
18; Sign extension from i64 from memory.
19define i128 @f2(ptr %ptr) {
20; CHECK-LABEL: f2:
21; CHECK:       # %bb.0:
22; CHECK-NEXT:    vlrepg %v0, 0(%r3)
23; CHECK-NEXT:    vrepib %v1, 64
24; CHECK-NEXT:    vsrab %v0, %v0, %v1
25; CHECK-NEXT:    vst %v0, 0(%r2), 3
26; CHECK-NEXT:    br %r14
27  %a = load i64, ptr %ptr
28  %res = sext i64 %a to i128
29  ret i128 %res
30}
31
32; Zero extension from i64.
33define i128 @f3(i64 %a) {
34; CHECK-LABEL: f3:
35; CHECK:       # %bb.0:
36; CHECK-NEXT:    vgbm %v0, 0
37; CHECK-NEXT:    vlvgg %v0, %r3, 1
38; CHECK-NEXT:    vst %v0, 0(%r2), 3
39; CHECK-NEXT:    br %r14
40  %res = zext i64 %a to i128
41  ret i128 %res
42}
43
44; Zero extension from i64 from memory.
45define i128 @f4(ptr %ptr) {
46; CHECK-LABEL: f4:
47; CHECK:       # %bb.0:
48; CHECK-NEXT:    vgbm %v0, 0
49; CHECK-NEXT:    vleg %v0, 0(%r3), 1
50; CHECK-NEXT:    vst %v0, 0(%r2), 3
51; CHECK-NEXT:    br %r14
52  %a = load i64, ptr %ptr
53  %res = zext i64 %a to i128
54  ret i128 %res
55}
56
57; Truncation to i64.
58define i64 @f5(i128 %a) {
59; CHECK-LABEL: f5:
60; CHECK:       # %bb.0:
61; CHECK-NEXT:    vl %v0, 0(%r2), 3
62; CHECK-NEXT:    vaq %v0, %v0, %v0
63; CHECK-NEXT:    vlgvg %r2, %v0, 1
64; CHECK-NEXT:    br %r14
65  %op = add i128 %a, %a
66  %res = trunc i128 %op to i64
67  ret i64 %res
68}
69
70; Truncation to i64 in memory.
71define void @f6(ptr %ptr, i128 %a) {
72; CHECK-LABEL: f6:
73; CHECK:       # %bb.0:
74; CHECK-NEXT:    vl %v0, 0(%r3), 3
75; CHECK-NEXT:    vaq %v0, %v0, %v0
76; CHECK-NEXT:    vsteg %v0, 0(%r2), 1
77; CHECK-NEXT:    br %r14
78  %op = add i128 %a, %a
79  %res = trunc i128 %op to i64
80  store i64 %res, ptr %ptr
81  ret void
82}
83
84; Sign extension from i32.
85define i128 @f7(i32 %a) {
86; CHECK-LABEL: f7:
87; CHECK:       # %bb.0:
88; CHECK-NEXT:    lgfr %r0, %r3
89; CHECK-NEXT:    srag %r1, %r0, 63
90; CHECK-NEXT:    vlvgp %v0, %r1, %r0
91; CHECK-NEXT:    vst %v0, 0(%r2), 3
92; CHECK-NEXT:    br %r14
93  %res = sext i32 %a to i128
94  ret i128 %res
95}
96
97; Sign extension from i32 from memory.
98define i128 @f8(ptr %ptr) {
99; CHECK-LABEL: f8:
100; CHECK:       # %bb.0:
101; CHECK-NEXT:    vlrepf %v0, 0(%r3)
102; CHECK-NEXT:    vrepib %v1, 96
103; CHECK-NEXT:    vsrab %v0, %v0, %v1
104; CHECK-NEXT:    vst %v0, 0(%r2), 3
105; CHECK-NEXT:    br %r14
106  %a = load i32, ptr %ptr
107  %res = sext i32 %a to i128
108  ret i128 %res
109}
110
111; Zero extension from i32.
112define i128 @f9(i32 %a) {
113; CHECK-LABEL: f9:
114; CHECK:       # %bb.0:
115; CHECK-NEXT:    vgbm %v0, 0
116; CHECK-NEXT:    vlvgf %v0, %r3, 3
117; CHECK-NEXT:    vst %v0, 0(%r2), 3
118; CHECK-NEXT:    br %r14
119  %res = zext i32 %a to i128
120  ret i128 %res
121}
122
123; Zero extension from i32 from memory.
124define i128 @f10(ptr %ptr) {
125; CHECK-LABEL: f10:
126; CHECK:       # %bb.0:
127; CHECK-NEXT:    vgbm %v0, 0
128; CHECK-NEXT:    vlef %v0, 0(%r3), 3
129; CHECK-NEXT:    vst %v0, 0(%r2), 3
130; CHECK-NEXT:    br %r14
131  %a = load i32, ptr %ptr
132  %res = zext i32 %a to i128
133  ret i128 %res
134}
135
136; Truncation to i32.
137define i32 @f11(i128 %a) {
138; CHECK-LABEL: f11:
139; CHECK:       # %bb.0:
140; CHECK-NEXT:    vl %v0, 0(%r2), 3
141; CHECK-NEXT:    vaq %v0, %v0, %v0
142; CHECK-NEXT:    vlgvf %r2, %v0, 3
143; CHECK-NEXT:    # kill: def $r2l killed $r2l killed $r2d
144; CHECK-NEXT:    br %r14
145  %op = add i128 %a, %a
146  %res = trunc i128 %op to i32
147  ret i32 %res
148}
149
150; Truncation to i32 in memory.
151define void @f12(ptr %ptr, i128 %a) {
152; CHECK-LABEL: f12:
153; CHECK:       # %bb.0:
154; CHECK-NEXT:    vl %v0, 0(%r3), 3
155; CHECK-NEXT:    vaq %v0, %v0, %v0
156; CHECK-NEXT:    vstef %v0, 0(%r2), 3
157; CHECK-NEXT:    br %r14
158  %op = add i128 %a, %a
159  %res = trunc i128 %op to i32
160  store i32 %res, ptr %ptr
161  ret void
162}
163
164; Sign extension from i16.
165define i128 @f13(i16 %a) {
166; CHECK-LABEL: f13:
167; CHECK:       # %bb.0:
168; CHECK-NEXT:    # kill: def $r3l killed $r3l def $r3d
169; CHECK-NEXT:    lghr %r0, %r3
170; CHECK-NEXT:    srag %r1, %r0, 63
171; CHECK-NEXT:    vlvgp %v0, %r1, %r0
172; CHECK-NEXT:    vst %v0, 0(%r2), 3
173; CHECK-NEXT:    br %r14
174  %res = sext i16 %a to i128
175  ret i128 %res
176}
177
178; Sign extension from i16 from memory.
179define i128 @f14(ptr %ptr) {
180; CHECK-LABEL: f14:
181; CHECK:       # %bb.0:
182; CHECK-NEXT:    vlreph %v0, 0(%r3)
183; CHECK-NEXT:    vrepib %v1, 112
184; CHECK-NEXT:    vsrab %v0, %v0, %v1
185; CHECK-NEXT:    vst %v0, 0(%r2), 3
186; CHECK-NEXT:    br %r14
187  %a = load i16, ptr %ptr
188  %res = sext i16 %a to i128
189  ret i128 %res
190}
191
192; Zero extension from i16.
193define i128 @f15(i16 %a) {
194; CHECK-LABEL: f15:
195; CHECK:       # %bb.0:
196; CHECK-NEXT:    vgbm %v0, 0
197; CHECK-NEXT:    vlvgh %v0, %r3, 7
198; CHECK-NEXT:    vst %v0, 0(%r2), 3
199; CHECK-NEXT:    br %r14
200  %res = zext i16 %a to i128
201  ret i128 %res
202}
203
204; Zero extension from i16 from memory.
205define i128 @f16(ptr %ptr) {
206; CHECK-LABEL: f16:
207; CHECK:       # %bb.0:
208; CHECK-NEXT:    vgbm %v0, 0
209; CHECK-NEXT:    vleh %v0, 0(%r3), 7
210; CHECK-NEXT:    vst %v0, 0(%r2), 3
211; CHECK-NEXT:    br %r14
212  %a = load i16, ptr %ptr
213  %res = zext i16 %a to i128
214  ret i128 %res
215}
216
217; Truncation to i16.
218define i16 @f17(i128 %a) {
219; CHECK-LABEL: f17:
220; CHECK:       # %bb.0:
221; CHECK-NEXT:    vl %v0, 0(%r2), 3
222; CHECK-NEXT:    vaq %v0, %v0, %v0
223; CHECK-NEXT:    vlgvf %r2, %v0, 3
224; CHECK-NEXT:    # kill: def $r2l killed $r2l killed $r2d
225; CHECK-NEXT:    br %r14
226  %op = add i128 %a, %a
227  %res = trunc i128 %op to i16
228  ret i16 %res
229}
230
231; Truncation to i16 in memory.
232define void @f18(ptr %ptr, i128 %a) {
233; CHECK-LABEL: f18:
234; CHECK:       # %bb.0:
235; CHECK-NEXT:    vl %v0, 0(%r3), 3
236; CHECK-NEXT:    vaq %v0, %v0, %v0
237; CHECK-NEXT:    vsteh %v0, 0(%r2), 7
238; CHECK-NEXT:    br %r14
239  %op = add i128 %a, %a
240  %res = trunc i128 %op to i16
241  store i16 %res, ptr %ptr
242  ret void
243}
244
245; Sign extension from i8.
246define i128 @f19(i8 %a) {
247; CHECK-LABEL: f19:
248; CHECK:       # %bb.0:
249; CHECK-NEXT:    # kill: def $r3l killed $r3l def $r3d
250; CHECK-NEXT:    lgbr %r0, %r3
251; CHECK-NEXT:    srag %r1, %r0, 63
252; CHECK-NEXT:    vlvgp %v0, %r1, %r0
253; CHECK-NEXT:    vst %v0, 0(%r2), 3
254; CHECK-NEXT:    br %r14
255  %res = sext i8 %a to i128
256  ret i128 %res
257}
258
259; Sign extension from i8 from memory.
260define i128 @f20(ptr %ptr) {
261; CHECK-LABEL: f20:
262; CHECK:       # %bb.0:
263; CHECK-NEXT:    vlrepb %v0, 0(%r3)
264; CHECK-NEXT:    vrepib %v1, 120
265; CHECK-NEXT:    vsrab %v0, %v0, %v1
266; CHECK-NEXT:    vst %v0, 0(%r2), 3
267; CHECK-NEXT:    br %r14
268  %a = load i8, ptr %ptr
269  %res = sext i8 %a to i128
270  ret i128 %res
271}
272
273; Zero extension from i8.
274define i128 @f21(i8 %a) {
275; CHECK-LABEL: f21:
276; CHECK:       # %bb.0:
277; CHECK-NEXT:    vgbm %v0, 0
278; CHECK-NEXT:    vlvgb %v0, %r3, 15
279; CHECK-NEXT:    vst %v0, 0(%r2), 3
280; CHECK-NEXT:    br %r14
281  %res = zext i8 %a to i128
282  ret i128 %res
283}
284
285; Zero extension from i8 from memory.
286define i128 @f22(ptr %ptr) {
287; CHECK-LABEL: f22:
288; CHECK:       # %bb.0:
289; CHECK-NEXT:    vgbm %v0, 0
290; CHECK-NEXT:    vleb %v0, 0(%r3), 15
291; CHECK-NEXT:    vst %v0, 0(%r2), 3
292; CHECK-NEXT:    br %r14
293  %a = load i8, ptr %ptr
294  %res = zext i8 %a to i128
295  ret i128 %res
296}
297
298; Truncation to i8.
299define i8 @f23(i128 %a) {
300; CHECK-LABEL: f23:
301; CHECK:       # %bb.0:
302; CHECK-NEXT:    vl %v0, 0(%r2), 3
303; CHECK-NEXT:    vaq %v0, %v0, %v0
304; CHECK-NEXT:    vlgvf %r2, %v0, 3
305; CHECK-NEXT:    # kill: def $r2l killed $r2l killed $r2d
306; CHECK-NEXT:    br %r14
307  %op = add i128 %a, %a
308  %res = trunc i128 %op to i8
309  ret i8 %res
310}
311
312; Truncation to i8 in memory.
313define void @f24(ptr %ptr, i128 %a) {
314; CHECK-LABEL: f24:
315; CHECK:       # %bb.0:
316; CHECK-NEXT:    vl %v0, 0(%r3), 3
317; CHECK-NEXT:    vaq %v0, %v0, %v0
318; CHECK-NEXT:    vsteb %v0, 0(%r2), 15
319; CHECK-NEXT:    br %r14
320  %op = add i128 %a, %a
321  %res = trunc i128 %op to i8
322  store i8 %res, ptr %ptr
323  ret void
324}
325
326; Sign extension from i1.
327define i128 @f25(i1 %a) {
328; CHECK-LABEL: f25:
329; CHECK:       # %bb.0:
330; CHECK-NEXT:    larl %r1, .LCPI24_0
331; CHECK-NEXT:    vl %v1, 0(%r1), 3
332; CHECK-NEXT:    vlvgp %v0, %r3, %r3
333; CHECK-NEXT:    vn %v0, %v0, %v1
334; CHECK-NEXT:    vgbm %v1, 0
335; CHECK-NEXT:    vsq %v0, %v1, %v0
336; CHECK-NEXT:    vst %v0, 0(%r2), 3
337; CHECK-NEXT:    br %r14
338  %res = sext i1 %a to i128
339  ret i128 %res
340}
341
342; Sign extension from i1 from memory.
343define i128 @f26(ptr %ptr) {
344; CHECK-LABEL: f26:
345; CHECK:       # %bb.0:
346; CHECK-NEXT:    vgbm %v1, 0
347; CHECK-NEXT:    vleb %v1, 0(%r3), 15
348; CHECK-NEXT:    larl %r1, .LCPI25_0
349; CHECK-NEXT:    vl %v2, 0(%r1), 3
350; CHECK-NEXT:    vgbm %v0, 0
351; CHECK-NEXT:    vn %v1, %v1, %v2
352; CHECK-NEXT:    vsq %v0, %v0, %v1
353; CHECK-NEXT:    vst %v0, 0(%r2), 3
354; CHECK-NEXT:    br %r14
355  %a = load i1, ptr %ptr
356  %res = sext i1 %a to i128
357  ret i128 %res
358}
359
360; Zero extension from i1.
361define i128 @f27(i1 %a) {
362; CHECK-LABEL: f27:
363; CHECK:       # %bb.0:
364; CHECK-NEXT:    larl %r1, .LCPI26_0
365; CHECK-NEXT:    vl %v1, 0(%r1), 3
366; CHECK-NEXT:    vlvgp %v0, %r3, %r3
367; CHECK-NEXT:    vn %v0, %v0, %v1
368; CHECK-NEXT:    vst %v0, 0(%r2), 3
369; CHECK-NEXT:    br %r14
370  %res = zext i1 %a to i128
371  ret i128 %res
372}
373
374; Zero extension from i1 from memory.
375define i128 @f28(ptr %ptr) {
376; CHECK-LABEL: f28:
377; CHECK:       # %bb.0:
378; CHECK-NEXT:    vgbm %v0, 0
379; CHECK-NEXT:    vleb %v0, 0(%r3), 15
380; CHECK-NEXT:    vst %v0, 0(%r2), 3
381; CHECK-NEXT:    br %r14
382  %a = load i1, ptr %ptr
383  %res = zext i1 %a to i128
384  ret i128 %res
385}
386
387; Truncation to i1.
388define i1 @f29(i128 %a) {
389; CHECK-LABEL: f29:
390; CHECK:       # %bb.0:
391; CHECK-NEXT:    vl %v0, 0(%r2), 3
392; CHECK-NEXT:    vaq %v0, %v0, %v0
393; CHECK-NEXT:    vlgvf %r2, %v0, 3
394; CHECK-NEXT:    # kill: def $r2l killed $r2l killed $r2d
395; CHECK-NEXT:    br %r14
396  %op = add i128 %a, %a
397  %res = trunc i128 %op to i1
398  ret i1 %res
399}
400
401; Truncation to i1 in memory.
402define void @f30(ptr %ptr, i128 %a) {
403; CHECK-LABEL: f30:
404; CHECK:       # %bb.0:
405; CHECK-NEXT:    vl %v0, 0(%r3), 3
406; CHECK-NEXT:    larl %r1, .LCPI29_0
407; CHECK-NEXT:    vl %v1, 0(%r1), 3
408; CHECK-NEXT:    vaq %v0, %v0, %v0
409; CHECK-NEXT:    vn %v0, %v0, %v1
410; CHECK-NEXT:    vsteb %v0, 0(%r2), 15
411; CHECK-NEXT:    br %r14
412  %op = add i128 %a, %a
413  %res = trunc i128 %op to i1
414  store i1 %res, ptr %ptr
415  ret void
416}
417