• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I
4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefix=RV64I
6
7define i8 @sext_i1_to_i8(i1 %a) nounwind {
8; RV32I-LABEL: sext_i1_to_i8:
9; RV32I:       # %bb.0:
10; RV32I-NEXT:    andi a0, a0, 1
11; RV32I-NEXT:    neg a0, a0
12; RV32I-NEXT:    ret
13;
14; RV64I-LABEL: sext_i1_to_i8:
15; RV64I:       # %bb.0:
16; RV64I-NEXT:    andi a0, a0, 1
17; RV64I-NEXT:    neg a0, a0
18; RV64I-NEXT:    ret
19  %1 = sext i1 %a to i8
20  ret i8 %1
21}
22
23define i16 @sext_i1_to_i16(i1 %a) nounwind {
24; RV32I-LABEL: sext_i1_to_i16:
25; RV32I:       # %bb.0:
26; RV32I-NEXT:    andi a0, a0, 1
27; RV32I-NEXT:    neg a0, a0
28; RV32I-NEXT:    ret
29;
30; RV64I-LABEL: sext_i1_to_i16:
31; RV64I:       # %bb.0:
32; RV64I-NEXT:    andi a0, a0, 1
33; RV64I-NEXT:    neg a0, a0
34; RV64I-NEXT:    ret
35  %1 = sext i1 %a to i16
36  ret i16 %1
37}
38
39define i32 @sext_i1_to_i32(i1 %a) nounwind {
40; RV32I-LABEL: sext_i1_to_i32:
41; RV32I:       # %bb.0:
42; RV32I-NEXT:    andi a0, a0, 1
43; RV32I-NEXT:    neg a0, a0
44; RV32I-NEXT:    ret
45;
46; RV64I-LABEL: sext_i1_to_i32:
47; RV64I:       # %bb.0:
48; RV64I-NEXT:    andi a0, a0, 1
49; RV64I-NEXT:    neg a0, a0
50; RV64I-NEXT:    ret
51  %1 = sext i1 %a to i32
52  ret i32 %1
53}
54
55define i64 @sext_i1_to_i64(i1 %a) nounwind {
56; RV32I-LABEL: sext_i1_to_i64:
57; RV32I:       # %bb.0:
58; RV32I-NEXT:    andi a0, a0, 1
59; RV32I-NEXT:    neg a0, a0
60; RV32I-NEXT:    mv a1, a0
61; RV32I-NEXT:    ret
62;
63; RV64I-LABEL: sext_i1_to_i64:
64; RV64I:       # %bb.0:
65; RV64I-NEXT:    andi a0, a0, 1
66; RV64I-NEXT:    neg a0, a0
67; RV64I-NEXT:    ret
68  %1 = sext i1 %a to i64
69  ret i64 %1
70}
71
72define i16 @sext_i8_to_i16(i8 %a) nounwind {
73; RV32I-LABEL: sext_i8_to_i16:
74; RV32I:       # %bb.0:
75; RV32I-NEXT:    slli a0, a0, 24
76; RV32I-NEXT:    srai a0, a0, 24
77; RV32I-NEXT:    ret
78;
79; RV64I-LABEL: sext_i8_to_i16:
80; RV64I:       # %bb.0:
81; RV64I-NEXT:    slli a0, a0, 56
82; RV64I-NEXT:    srai a0, a0, 56
83; RV64I-NEXT:    ret
84  %1 = sext i8 %a to i16
85  ret i16 %1
86}
87
88define i32 @sext_i8_to_i32(i8 %a) nounwind {
89; RV32I-LABEL: sext_i8_to_i32:
90; RV32I:       # %bb.0:
91; RV32I-NEXT:    slli a0, a0, 24
92; RV32I-NEXT:    srai a0, a0, 24
93; RV32I-NEXT:    ret
94;
95; RV64I-LABEL: sext_i8_to_i32:
96; RV64I:       # %bb.0:
97; RV64I-NEXT:    slli a0, a0, 56
98; RV64I-NEXT:    srai a0, a0, 56
99; RV64I-NEXT:    ret
100  %1 = sext i8 %a to i32
101  ret i32 %1
102}
103
104define i64 @sext_i8_to_i64(i8 %a) nounwind {
105; RV32I-LABEL: sext_i8_to_i64:
106; RV32I:       # %bb.0:
107; RV32I-NEXT:    slli a1, a0, 24
108; RV32I-NEXT:    srai a0, a1, 24
109; RV32I-NEXT:    srai a1, a1, 31
110; RV32I-NEXT:    ret
111;
112; RV64I-LABEL: sext_i8_to_i64:
113; RV64I:       # %bb.0:
114; RV64I-NEXT:    slli a0, a0, 56
115; RV64I-NEXT:    srai a0, a0, 56
116; RV64I-NEXT:    ret
117  %1 = sext i8 %a to i64
118  ret i64 %1
119}
120
121define i32 @sext_i16_to_i32(i16 %a) nounwind {
122; RV32I-LABEL: sext_i16_to_i32:
123; RV32I:       # %bb.0:
124; RV32I-NEXT:    slli a0, a0, 16
125; RV32I-NEXT:    srai a0, a0, 16
126; RV32I-NEXT:    ret
127;
128; RV64I-LABEL: sext_i16_to_i32:
129; RV64I:       # %bb.0:
130; RV64I-NEXT:    slli a0, a0, 48
131; RV64I-NEXT:    srai a0, a0, 48
132; RV64I-NEXT:    ret
133  %1 = sext i16 %a to i32
134  ret i32 %1
135}
136
137define i64 @sext_i16_to_i64(i16 %a) nounwind {
138; RV32I-LABEL: sext_i16_to_i64:
139; RV32I:       # %bb.0:
140; RV32I-NEXT:    slli a1, a0, 16
141; RV32I-NEXT:    srai a0, a1, 16
142; RV32I-NEXT:    srai a1, a1, 31
143; RV32I-NEXT:    ret
144;
145; RV64I-LABEL: sext_i16_to_i64:
146; RV64I:       # %bb.0:
147; RV64I-NEXT:    slli a0, a0, 48
148; RV64I-NEXT:    srai a0, a0, 48
149; RV64I-NEXT:    ret
150  %1 = sext i16 %a to i64
151  ret i64 %1
152}
153
154define i64 @sext_i32_to_i64(i32 %a) nounwind {
155; RV32I-LABEL: sext_i32_to_i64:
156; RV32I:       # %bb.0:
157; RV32I-NEXT:    srai a1, a0, 31
158; RV32I-NEXT:    ret
159;
160; RV64I-LABEL: sext_i32_to_i64:
161; RV64I:       # %bb.0:
162; RV64I-NEXT:    sext.w a0, a0
163; RV64I-NEXT:    ret
164  %1 = sext i32 %a to i64
165  ret i64 %1
166}
167
168define i8 @zext_i1_to_i8(i1 %a) nounwind {
169; RV32I-LABEL: zext_i1_to_i8:
170; RV32I:       # %bb.0:
171; RV32I-NEXT:    andi a0, a0, 1
172; RV32I-NEXT:    ret
173;
174; RV64I-LABEL: zext_i1_to_i8:
175; RV64I:       # %bb.0:
176; RV64I-NEXT:    andi a0, a0, 1
177; RV64I-NEXT:    ret
178  %1 = zext i1 %a to i8
179  ret i8 %1
180}
181
182define i16 @zext_i1_to_i16(i1 %a) nounwind {
183; RV32I-LABEL: zext_i1_to_i16:
184; RV32I:       # %bb.0:
185; RV32I-NEXT:    andi a0, a0, 1
186; RV32I-NEXT:    ret
187;
188; RV64I-LABEL: zext_i1_to_i16:
189; RV64I:       # %bb.0:
190; RV64I-NEXT:    andi a0, a0, 1
191; RV64I-NEXT:    ret
192  %1 = zext i1 %a to i16
193  ret i16 %1
194}
195
196define i32 @zext_i1_to_i32(i1 %a) nounwind {
197; RV32I-LABEL: zext_i1_to_i32:
198; RV32I:       # %bb.0:
199; RV32I-NEXT:    andi a0, a0, 1
200; RV32I-NEXT:    ret
201;
202; RV64I-LABEL: zext_i1_to_i32:
203; RV64I:       # %bb.0:
204; RV64I-NEXT:    andi a0, a0, 1
205; RV64I-NEXT:    ret
206  %1 = zext i1 %a to i32
207  ret i32 %1
208}
209
210define i64 @zext_i1_to_i64(i1 %a) nounwind {
211; RV32I-LABEL: zext_i1_to_i64:
212; RV32I:       # %bb.0:
213; RV32I-NEXT:    andi a0, a0, 1
214; RV32I-NEXT:    mv a1, zero
215; RV32I-NEXT:    ret
216;
217; RV64I-LABEL: zext_i1_to_i64:
218; RV64I:       # %bb.0:
219; RV64I-NEXT:    andi a0, a0, 1
220; RV64I-NEXT:    ret
221  %1 = zext i1 %a to i64
222  ret i64 %1
223}
224
225define i16 @zext_i8_to_i16(i8 %a) nounwind {
226; RV32I-LABEL: zext_i8_to_i16:
227; RV32I:       # %bb.0:
228; RV32I-NEXT:    andi a0, a0, 255
229; RV32I-NEXT:    ret
230;
231; RV64I-LABEL: zext_i8_to_i16:
232; RV64I:       # %bb.0:
233; RV64I-NEXT:    andi a0, a0, 255
234; RV64I-NEXT:    ret
235  %1 = zext i8 %a to i16
236  ret i16 %1
237}
238
239define i32 @zext_i8_to_i32(i8 %a) nounwind {
240; RV32I-LABEL: zext_i8_to_i32:
241; RV32I:       # %bb.0:
242; RV32I-NEXT:    andi a0, a0, 255
243; RV32I-NEXT:    ret
244;
245; RV64I-LABEL: zext_i8_to_i32:
246; RV64I:       # %bb.0:
247; RV64I-NEXT:    andi a0, a0, 255
248; RV64I-NEXT:    ret
249  %1 = zext i8 %a to i32
250  ret i32 %1
251}
252
253define i64 @zext_i8_to_i64(i8 %a) nounwind {
254; RV32I-LABEL: zext_i8_to_i64:
255; RV32I:       # %bb.0:
256; RV32I-NEXT:    andi a0, a0, 255
257; RV32I-NEXT:    mv a1, zero
258; RV32I-NEXT:    ret
259;
260; RV64I-LABEL: zext_i8_to_i64:
261; RV64I:       # %bb.0:
262; RV64I-NEXT:    andi a0, a0, 255
263; RV64I-NEXT:    ret
264  %1 = zext i8 %a to i64
265  ret i64 %1
266}
267
268define i32 @zext_i16_to_i32(i16 %a) nounwind {
269; RV32I-LABEL: zext_i16_to_i32:
270; RV32I:       # %bb.0:
271; RV32I-NEXT:    lui a1, 16
272; RV32I-NEXT:    addi a1, a1, -1
273; RV32I-NEXT:    and a0, a0, a1
274; RV32I-NEXT:    ret
275;
276; RV64I-LABEL: zext_i16_to_i32:
277; RV64I:       # %bb.0:
278; RV64I-NEXT:    lui a1, 16
279; RV64I-NEXT:    addiw a1, a1, -1
280; RV64I-NEXT:    and a0, a0, a1
281; RV64I-NEXT:    ret
282  %1 = zext i16 %a to i32
283  ret i32 %1
284}
285
286define i64 @zext_i16_to_i64(i16 %a) nounwind {
287; RV32I-LABEL: zext_i16_to_i64:
288; RV32I:       # %bb.0:
289; RV32I-NEXT:    lui a1, 16
290; RV32I-NEXT:    addi a1, a1, -1
291; RV32I-NEXT:    and a0, a0, a1
292; RV32I-NEXT:    mv a1, zero
293; RV32I-NEXT:    ret
294;
295; RV64I-LABEL: zext_i16_to_i64:
296; RV64I:       # %bb.0:
297; RV64I-NEXT:    lui a1, 16
298; RV64I-NEXT:    addiw a1, a1, -1
299; RV64I-NEXT:    and a0, a0, a1
300; RV64I-NEXT:    ret
301  %1 = zext i16 %a to i64
302  ret i64 %1
303}
304
305define i64 @zext_i32_to_i64(i32 %a) nounwind {
306; RV32I-LABEL: zext_i32_to_i64:
307; RV32I:       # %bb.0:
308; RV32I-NEXT:    mv a1, zero
309; RV32I-NEXT:    ret
310;
311; RV64I-LABEL: zext_i32_to_i64:
312; RV64I:       # %bb.0:
313; RV64I-NEXT:    slli a0, a0, 32
314; RV64I-NEXT:    srli a0, a0, 32
315; RV64I-NEXT:    ret
316  %1 = zext i32 %a to i64
317  ret i64 %1
318}
319
320define i1 @trunc_i8_to_i1(i8 %a) nounwind {
321; RV32I-LABEL: trunc_i8_to_i1:
322; RV32I:       # %bb.0:
323; RV32I-NEXT:    ret
324;
325; RV64I-LABEL: trunc_i8_to_i1:
326; RV64I:       # %bb.0:
327; RV64I-NEXT:    ret
328  %1 = trunc i8 %a to i1
329  ret i1 %1
330}
331
332define i1 @trunc_i16_to_i1(i16 %a) nounwind {
333; RV32I-LABEL: trunc_i16_to_i1:
334; RV32I:       # %bb.0:
335; RV32I-NEXT:    ret
336;
337; RV64I-LABEL: trunc_i16_to_i1:
338; RV64I:       # %bb.0:
339; RV64I-NEXT:    ret
340  %1 = trunc i16 %a to i1
341  ret i1 %1
342}
343
344define i1 @trunc_i32_to_i1(i32 %a) nounwind {
345; RV32I-LABEL: trunc_i32_to_i1:
346; RV32I:       # %bb.0:
347; RV32I-NEXT:    ret
348;
349; RV64I-LABEL: trunc_i32_to_i1:
350; RV64I:       # %bb.0:
351; RV64I-NEXT:    ret
352  %1 = trunc i32 %a to i1
353  ret i1 %1
354}
355
356define i1 @trunc_i64_to_i1(i64 %a) nounwind {
357; RV32I-LABEL: trunc_i64_to_i1:
358; RV32I:       # %bb.0:
359; RV32I-NEXT:    ret
360;
361; RV64I-LABEL: trunc_i64_to_i1:
362; RV64I:       # %bb.0:
363; RV64I-NEXT:    ret
364  %1 = trunc i64 %a to i1
365  ret i1 %1
366}
367
368define i8 @trunc_i16_to_i8(i16 %a) nounwind {
369; RV32I-LABEL: trunc_i16_to_i8:
370; RV32I:       # %bb.0:
371; RV32I-NEXT:    ret
372;
373; RV64I-LABEL: trunc_i16_to_i8:
374; RV64I:       # %bb.0:
375; RV64I-NEXT:    ret
376  %1 = trunc i16 %a to i8
377  ret i8 %1
378}
379
380define i8 @trunc_i32_to_i8(i32 %a) nounwind {
381; RV32I-LABEL: trunc_i32_to_i8:
382; RV32I:       # %bb.0:
383; RV32I-NEXT:    ret
384;
385; RV64I-LABEL: trunc_i32_to_i8:
386; RV64I:       # %bb.0:
387; RV64I-NEXT:    ret
388  %1 = trunc i32 %a to i8
389  ret i8 %1
390}
391
392define i8 @trunc_i64_to_i8(i64 %a) nounwind {
393; RV32I-LABEL: trunc_i64_to_i8:
394; RV32I:       # %bb.0:
395; RV32I-NEXT:    ret
396;
397; RV64I-LABEL: trunc_i64_to_i8:
398; RV64I:       # %bb.0:
399; RV64I-NEXT:    ret
400  %1 = trunc i64 %a to i8
401  ret i8 %1
402}
403
404define i16 @trunc_i32_to_i16(i32 %a) nounwind {
405; RV32I-LABEL: trunc_i32_to_i16:
406; RV32I:       # %bb.0:
407; RV32I-NEXT:    ret
408;
409; RV64I-LABEL: trunc_i32_to_i16:
410; RV64I:       # %bb.0:
411; RV64I-NEXT:    ret
412  %1 = trunc i32 %a to i16
413  ret i16 %1
414}
415
416define i16 @trunc_i64_to_i16(i64 %a) nounwind {
417; RV32I-LABEL: trunc_i64_to_i16:
418; RV32I:       # %bb.0:
419; RV32I-NEXT:    ret
420;
421; RV64I-LABEL: trunc_i64_to_i16:
422; RV64I:       # %bb.0:
423; RV64I-NEXT:    ret
424  %1 = trunc i64 %a to i16
425  ret i16 %1
426}
427
428define i32 @trunc_i64_to_i32(i64 %a) nounwind {
429; RV32I-LABEL: trunc_i64_to_i32:
430; RV32I:       # %bb.0:
431; RV32I-NEXT:    ret
432;
433; RV64I-LABEL: trunc_i64_to_i32:
434; RV64I:       # %bb.0:
435; RV64I-NEXT:    ret
436  %1 = trunc i64 %a to i32
437  ret i32 %1
438}
439
440;; fold (sext (not x)) -> (add (zext x) -1)
441define i32 @sext_of_not_i32(i1 %x) {
442; RV32I-LABEL: sext_of_not_i32:
443; RV32I:       # %bb.0:
444; RV32I-NEXT:    andi a0, a0, 1
445; RV32I-NEXT:    addi a0, a0, -1
446; RV32I-NEXT:    ret
447;
448; RV64I-LABEL: sext_of_not_i32:
449; RV64I:       # %bb.0:
450; RV64I-NEXT:    andi a0, a0, 1
451; RV64I-NEXT:    addi a0, a0, -1
452; RV64I-NEXT:    ret
453  %xor = xor i1 %x, 1
454  %sext = sext i1 %xor to i32
455  ret i32 %sext
456}
457
458define i64 @sext_of_not_i64(i1 %x) {
459; RV32I-LABEL: sext_of_not_i64:
460; RV32I:       # %bb.0:
461; RV32I-NEXT:    andi a1, a0, 1
462; RV32I-NEXT:    addi a0, a1, -1
463; RV32I-NEXT:    sltu a1, a0, a1
464; RV32I-NEXT:    addi a1, a1, -1
465; RV32I-NEXT:    ret
466;
467; RV64I-LABEL: sext_of_not_i64:
468; RV64I:       # %bb.0:
469; RV64I-NEXT:    andi a0, a0, 1
470; RV64I-NEXT:    addi a0, a0, -1
471; RV64I-NEXT:    ret
472  %xor = xor i1 %x, 1
473  %sext = sext i1 %xor to i64
474  ret i64 %sext
475}
476
477;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
478define i32 @sext_of_not_cmp_i32(i32 %x) {
479; RV32I-LABEL: sext_of_not_cmp_i32:
480; RV32I:       # %bb.0:
481; RV32I-NEXT:    addi a0, a0, -7
482; RV32I-NEXT:    snez a0, a0
483; RV32I-NEXT:    neg a0, a0
484; RV32I-NEXT:    ret
485;
486; RV64I-LABEL: sext_of_not_cmp_i32:
487; RV64I:       # %bb.0:
488; RV64I-NEXT:    slli a0, a0, 32
489; RV64I-NEXT:    srli a0, a0, 32
490; RV64I-NEXT:    addi a0, a0, -7
491; RV64I-NEXT:    snez a0, a0
492; RV64I-NEXT:    neg a0, a0
493; RV64I-NEXT:    ret
494  %cmp = icmp eq i32 %x, 7
495  %xor = xor i1 %cmp, 1
496  %sext = sext i1 %xor to i32
497  ret i32 %sext
498}
499
500define i64 @sext_of_not_cmp_i64(i64 %x) {
501; RV32I-LABEL: sext_of_not_cmp_i64:
502; RV32I:       # %bb.0:
503; RV32I-NEXT:    xori a0, a0, 7
504; RV32I-NEXT:    or a0, a0, a1
505; RV32I-NEXT:    snez a0, a0
506; RV32I-NEXT:    neg a0, a0
507; RV32I-NEXT:    mv a1, a0
508; RV32I-NEXT:    ret
509;
510; RV64I-LABEL: sext_of_not_cmp_i64:
511; RV64I:       # %bb.0:
512; RV64I-NEXT:    addi a0, a0, -7
513; RV64I-NEXT:    snez a0, a0
514; RV64I-NEXT:    neg a0, a0
515; RV64I-NEXT:    ret
516  %cmp = icmp eq i64 %x, 7
517  %xor = xor i1 %cmp, 1
518  %sext = sext i1 %xor to i64
519  ret i64 %sext
520}
521
522;; TODO: fold (add (zext (setcc a, b, cc)), -1) -> (sext (setcc a, b, !cc))
523define i32 @dec_of_zexted_cmp_i32(i32 %x) {
524; RV32I-LABEL: dec_of_zexted_cmp_i32:
525; RV32I:       # %bb.0:
526; RV32I-NEXT:    addi a0, a0, -7
527; RV32I-NEXT:    seqz a0, a0
528; RV32I-NEXT:    addi a0, a0, -1
529; RV32I-NEXT:    ret
530;
531; RV64I-LABEL: dec_of_zexted_cmp_i32:
532; RV64I:       # %bb.0:
533; RV64I-NEXT:    slli a0, a0, 32
534; RV64I-NEXT:    srli a0, a0, 32
535; RV64I-NEXT:    addi a0, a0, -7
536; RV64I-NEXT:    seqz a0, a0
537; RV64I-NEXT:    addi a0, a0, -1
538; RV64I-NEXT:    ret
539  %cmp = icmp eq i32 %x, 7
540  %zext = zext i1 %cmp to i32
541  %dec = sub i32 %zext, 1
542  ret i32 %dec
543}
544
545define i64 @dec_of_zexted_cmp_i64(i64 %x) {
546; RV32I-LABEL: dec_of_zexted_cmp_i64:
547; RV32I:       # %bb.0:
548; RV32I-NEXT:    xori a0, a0, 7
549; RV32I-NEXT:    or a0, a0, a1
550; RV32I-NEXT:    seqz a1, a0
551; RV32I-NEXT:    addi a0, a1, -1
552; RV32I-NEXT:    sltu a1, a0, a1
553; RV32I-NEXT:    addi a1, a1, -1
554; RV32I-NEXT:    ret
555;
556; RV64I-LABEL: dec_of_zexted_cmp_i64:
557; RV64I:       # %bb.0:
558; RV64I-NEXT:    addi a0, a0, -7
559; RV64I-NEXT:    seqz a0, a0
560; RV64I-NEXT:    addi a0, a0, -1
561; RV64I-NEXT:    ret
562  %cmp = icmp eq i64 %x, 7
563  %zext = zext i1 %cmp to i64
564  %dec = sub i64 %zext, 1
565  ret i64 %dec
566}
567