xref: /llvm-project/llvm/test/CodeGen/RISCV/alu32.ll (revision af0ecfccae82ade32581959d61fe86f573d08def)
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
7; These tests are each targeted at a particular RISC-V ALU instruction. Most
8; other files in this folder exercise LLVM IR instructions that don't directly
9; match a RISC-V instruction.
10
11; Register-immediate instructions.
12
13define i32 @addi(i32 %a) nounwind {
14; RV32I-LABEL: addi:
15; RV32I:       # %bb.0:
16; RV32I-NEXT:    addi a0, a0, 1
17; RV32I-NEXT:    ret
18;
19; RV64I-LABEL: addi:
20; RV64I:       # %bb.0:
21; RV64I-NEXT:    addiw a0, a0, 1
22; RV64I-NEXT:    ret
23  %1 = add i32 %a, 1
24  ret i32 %1
25}
26
27define i32 @slti(i32 %a) nounwind {
28; RV32I-LABEL: slti:
29; RV32I:       # %bb.0:
30; RV32I-NEXT:    slti a0, a0, 2
31; RV32I-NEXT:    ret
32;
33; RV64I-LABEL: slti:
34; RV64I:       # %bb.0:
35; RV64I-NEXT:    sext.w a0, a0
36; RV64I-NEXT:    slti a0, a0, 2
37; RV64I-NEXT:    ret
38  %1 = icmp slt i32 %a, 2
39  %2 = zext i1 %1 to i32
40  ret i32 %2
41}
42
43define i32 @sltiu(i32 %a) nounwind {
44; RV32I-LABEL: sltiu:
45; RV32I:       # %bb.0:
46; RV32I-NEXT:    sltiu a0, a0, 3
47; RV32I-NEXT:    ret
48;
49; RV64I-LABEL: sltiu:
50; RV64I:       # %bb.0:
51; RV64I-NEXT:    sext.w a0, a0
52; RV64I-NEXT:    sltiu a0, a0, 3
53; RV64I-NEXT:    ret
54  %1 = icmp ult i32 %a, 3
55  %2 = zext i1 %1 to i32
56  ret i32 %2
57}
58
59define i32 @xori(i32 %a) nounwind {
60; RV32I-LABEL: xori:
61; RV32I:       # %bb.0:
62; RV32I-NEXT:    xori a0, a0, 4
63; RV32I-NEXT:    ret
64;
65; RV64I-LABEL: xori:
66; RV64I:       # %bb.0:
67; RV64I-NEXT:    xori a0, a0, 4
68; RV64I-NEXT:    ret
69  %1 = xor i32 %a, 4
70  ret i32 %1
71}
72
73define i32 @ori(i32 %a) nounwind {
74; RV32I-LABEL: ori:
75; RV32I:       # %bb.0:
76; RV32I-NEXT:    ori a0, a0, 5
77; RV32I-NEXT:    ret
78;
79; RV64I-LABEL: ori:
80; RV64I:       # %bb.0:
81; RV64I-NEXT:    ori a0, a0, 5
82; RV64I-NEXT:    ret
83  %1 = or i32 %a, 5
84  ret i32 %1
85}
86
87define i32 @andi(i32 %a) nounwind {
88; RV32I-LABEL: andi:
89; RV32I:       # %bb.0:
90; RV32I-NEXT:    andi a0, a0, 6
91; RV32I-NEXT:    ret
92;
93; RV64I-LABEL: andi:
94; RV64I:       # %bb.0:
95; RV64I-NEXT:    andi a0, a0, 6
96; RV64I-NEXT:    ret
97  %1 = and i32 %a, 6
98  ret i32 %1
99}
100
101define i32 @slli(i32 %a) nounwind {
102; RV32I-LABEL: slli:
103; RV32I:       # %bb.0:
104; RV32I-NEXT:    slli a0, a0, 7
105; RV32I-NEXT:    ret
106;
107; RV64I-LABEL: slli:
108; RV64I:       # %bb.0:
109; RV64I-NEXT:    slliw a0, a0, 7
110; RV64I-NEXT:    ret
111  %1 = shl i32 %a, 7
112  ret i32 %1
113}
114
115define i32 @srli(i32 %a) nounwind {
116; RV32I-LABEL: srli:
117; RV32I:       # %bb.0:
118; RV32I-NEXT:    srli a0, a0, 8
119; RV32I-NEXT:    ret
120;
121; RV64I-LABEL: srli:
122; RV64I:       # %bb.0:
123; RV64I-NEXT:    srliw a0, a0, 8
124; RV64I-NEXT:    ret
125  %1 = lshr i32 %a, 8
126  ret i32 %1
127}
128
129; This makes sure SimplifyDemandedBits doesn't prevent us from matching SRLIW
130; on RV64.
131define i32 @srli_demandedbits(i32 %0) {
132; RV32I-LABEL: srli_demandedbits:
133; RV32I:       # %bb.0:
134; RV32I-NEXT:    srli a0, a0, 3
135; RV32I-NEXT:    ori a0, a0, 1
136; RV32I-NEXT:    ret
137;
138; RV64I-LABEL: srli_demandedbits:
139; RV64I:       # %bb.0:
140; RV64I-NEXT:    srliw a0, a0, 3
141; RV64I-NEXT:    ori a0, a0, 1
142; RV64I-NEXT:    ret
143  %2 = lshr i32 %0, 3
144  %3 = or i32 %2, 1
145  ret i32 %3
146}
147
148define i32 @srai(i32 %a) nounwind {
149; RV32I-LABEL: srai:
150; RV32I:       # %bb.0:
151; RV32I-NEXT:    srai a0, a0, 9
152; RV32I-NEXT:    ret
153;
154; RV64I-LABEL: srai:
155; RV64I:       # %bb.0:
156; RV64I-NEXT:    sraiw a0, a0, 9
157; RV64I-NEXT:    ret
158  %1 = ashr i32 %a, 9
159  ret i32 %1
160}
161
162; Register-register instructions
163
164define i32 @add(i32 %a, i32 %b) nounwind {
165; RV32I-LABEL: add:
166; RV32I:       # %bb.0:
167; RV32I-NEXT:    add a0, a0, a1
168; RV32I-NEXT:    ret
169;
170; RV64I-LABEL: add:
171; RV64I:       # %bb.0:
172; RV64I-NEXT:    addw a0, a0, a1
173; RV64I-NEXT:    ret
174  %1 = add i32 %a, %b
175  ret i32 %1
176}
177
178define i32 @sub(i32 %a, i32 %b) nounwind {
179; RV32I-LABEL: sub:
180; RV32I:       # %bb.0:
181; RV32I-NEXT:    sub a0, a0, a1
182; RV32I-NEXT:    ret
183;
184; RV64I-LABEL: sub:
185; RV64I:       # %bb.0:
186; RV64I-NEXT:    subw a0, a0, a1
187; RV64I-NEXT:    ret
188  %1 = sub i32 %a, %b
189  ret i32 %1
190}
191
192define i32 @sub_negative_constant_lhs(i32 %a) nounwind {
193; RV32I-LABEL: sub_negative_constant_lhs:
194; RV32I:       # %bb.0:
195; RV32I-NEXT:    li a1, -2
196; RV32I-NEXT:    sub a0, a1, a0
197; RV32I-NEXT:    ret
198;
199; RV64I-LABEL: sub_negative_constant_lhs:
200; RV64I:       # %bb.0:
201; RV64I-NEXT:    li a1, -2
202; RV64I-NEXT:    subw a0, a1, a0
203; RV64I-NEXT:    ret
204  %1 = sub i32 -2, %a
205  ret i32 %1
206}
207
208define i32 @sll(i32 %a, i32 %b) nounwind {
209; RV32I-LABEL: sll:
210; RV32I:       # %bb.0:
211; RV32I-NEXT:    sll a0, a0, a1
212; RV32I-NEXT:    ret
213;
214; RV64I-LABEL: sll:
215; RV64I:       # %bb.0:
216; RV64I-NEXT:    sllw a0, a0, a1
217; RV64I-NEXT:    ret
218  %1 = shl i32 %a, %b
219  ret i32 %1
220}
221
222define i32 @sll_negative_constant_lhs(i32 %a) nounwind {
223; RV32I-LABEL: sll_negative_constant_lhs:
224; RV32I:       # %bb.0:
225; RV32I-NEXT:    li a1, -1
226; RV32I-NEXT:    sll a0, a1, a0
227; RV32I-NEXT:    ret
228;
229; RV64I-LABEL: sll_negative_constant_lhs:
230; RV64I:       # %bb.0:
231; RV64I-NEXT:    li a1, -1
232; RV64I-NEXT:    sllw a0, a1, a0
233; RV64I-NEXT:    ret
234  %1 = shl i32 -1, %a
235  ret i32 %1
236}
237
238define i32 @slt(i32 %a, i32 %b) nounwind {
239; RV32I-LABEL: slt:
240; RV32I:       # %bb.0:
241; RV32I-NEXT:    slt a0, a0, a1
242; RV32I-NEXT:    ret
243;
244; RV64I-LABEL: slt:
245; RV64I:       # %bb.0:
246; RV64I-NEXT:    sext.w a1, a1
247; RV64I-NEXT:    sext.w a0, a0
248; RV64I-NEXT:    slt a0, a0, a1
249; RV64I-NEXT:    ret
250  %1 = icmp slt i32 %a, %b
251  %2 = zext i1 %1 to i32
252  ret i32 %2
253}
254
255define i32 @sltu(i32 %a, i32 %b) nounwind {
256; RV32I-LABEL: sltu:
257; RV32I:       # %bb.0:
258; RV32I-NEXT:    sltu a0, a0, a1
259; RV32I-NEXT:    ret
260;
261; RV64I-LABEL: sltu:
262; RV64I:       # %bb.0:
263; RV64I-NEXT:    sext.w a1, a1
264; RV64I-NEXT:    sext.w a0, a0
265; RV64I-NEXT:    sltu a0, a0, a1
266; RV64I-NEXT:    ret
267  %1 = icmp ult i32 %a, %b
268  %2 = zext i1 %1 to i32
269  ret i32 %2
270}
271
272define i32 @xor(i32 %a, i32 %b) nounwind {
273; RV32I-LABEL: xor:
274; RV32I:       # %bb.0:
275; RV32I-NEXT:    xor a0, a0, a1
276; RV32I-NEXT:    ret
277;
278; RV64I-LABEL: xor:
279; RV64I:       # %bb.0:
280; RV64I-NEXT:    xor a0, a0, a1
281; RV64I-NEXT:    ret
282  %1 = xor i32 %a, %b
283  ret i32 %1
284}
285
286define i32 @srl(i32 %a, i32 %b) nounwind {
287; RV32I-LABEL: srl:
288; RV32I:       # %bb.0:
289; RV32I-NEXT:    srl a0, a0, a1
290; RV32I-NEXT:    ret
291;
292; RV64I-LABEL: srl:
293; RV64I:       # %bb.0:
294; RV64I-NEXT:    srlw a0, a0, a1
295; RV64I-NEXT:    ret
296  %1 = lshr i32 %a, %b
297  ret i32 %1
298}
299
300define i32 @srl_negative_constant_lhs(i32 %a) nounwind {
301; RV32I-LABEL: srl_negative_constant_lhs:
302; RV32I:       # %bb.0:
303; RV32I-NEXT:    li a1, -1
304; RV32I-NEXT:    srl a0, a1, a0
305; RV32I-NEXT:    ret
306;
307; RV64I-LABEL: srl_negative_constant_lhs:
308; RV64I:       # %bb.0:
309; RV64I-NEXT:    li a1, -1
310; RV64I-NEXT:    srlw a0, a1, a0
311; RV64I-NEXT:    ret
312  %1 = lshr i32 -1, %a
313  ret i32 %1
314}
315
316define i32 @sra(i32 %a, i32 %b) nounwind {
317; RV32I-LABEL: sra:
318; RV32I:       # %bb.0:
319; RV32I-NEXT:    sra a0, a0, a1
320; RV32I-NEXT:    ret
321;
322; RV64I-LABEL: sra:
323; RV64I:       # %bb.0:
324; RV64I-NEXT:    sraw a0, a0, a1
325; RV64I-NEXT:    ret
326  %1 = ashr i32 %a, %b
327  ret i32 %1
328}
329
330define i32 @sra_negative_constant_lhs(i32 %a) nounwind {
331; RV32I-LABEL: sra_negative_constant_lhs:
332; RV32I:       # %bb.0:
333; RV32I-NEXT:    lui a1, 524288
334; RV32I-NEXT:    sra a0, a1, a0
335; RV32I-NEXT:    ret
336;
337; RV64I-LABEL: sra_negative_constant_lhs:
338; RV64I:       # %bb.0:
339; RV64I-NEXT:    lui a1, 524288
340; RV64I-NEXT:    sraw a0, a1, a0
341; RV64I-NEXT:    ret
342  %1 = ashr i32 2147483648, %a
343  ret i32 %1
344}
345
346define i32 @or(i32 %a, i32 %b) nounwind {
347; RV32I-LABEL: or:
348; RV32I:       # %bb.0:
349; RV32I-NEXT:    or a0, a0, a1
350; RV32I-NEXT:    ret
351;
352; RV64I-LABEL: or:
353; RV64I:       # %bb.0:
354; RV64I-NEXT:    or a0, a0, a1
355; RV64I-NEXT:    ret
356  %1 = or i32 %a, %b
357  ret i32 %1
358}
359
360define i32 @and(i32 %a, i32 %b) nounwind {
361; RV32I-LABEL: and:
362; RV32I:       # %bb.0:
363; RV32I-NEXT:    and a0, a0, a1
364; RV32I-NEXT:    ret
365;
366; RV64I-LABEL: and:
367; RV64I:       # %bb.0:
368; RV64I-NEXT:    and a0, a0, a1
369; RV64I-NEXT:    ret
370  %1 = and i32 %a, %b
371  ret i32 %1
372}
373