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
13; TODO: Sign-extension would also work when promoting the operands of
14; sltu/sltiu on RV64 and is cheaper than zero-extension (1 instruction vs 2).
15
16define i32 @addi(i32 %a) nounwind {
17; RV32I-LABEL: addi:
18; RV32I:       # %bb.0:
19; RV32I-NEXT:    addi a0, a0, 1
20; RV32I-NEXT:    ret
21;
22; RV64I-LABEL: addi:
23; RV64I:       # %bb.0:
24; RV64I-NEXT:    addi a0, a0, 1
25; RV64I-NEXT:    ret
26  %1 = add i32 %a, 1
27  ret i32 %1
28}
29
30define i32 @slti(i32 %a) nounwind {
31; RV32I-LABEL: slti:
32; RV32I:       # %bb.0:
33; RV32I-NEXT:    slti a0, a0, 2
34; RV32I-NEXT:    ret
35;
36; RV64I-LABEL: slti:
37; RV64I:       # %bb.0:
38; RV64I-NEXT:    sext.w a0, a0
39; RV64I-NEXT:    slti a0, a0, 2
40; RV64I-NEXT:    ret
41  %1 = icmp slt i32 %a, 2
42  %2 = zext i1 %1 to i32
43  ret i32 %2
44}
45
46define i32 @sltiu(i32 %a) nounwind {
47; RV32I-LABEL: sltiu:
48; RV32I:       # %bb.0:
49; RV32I-NEXT:    sltiu a0, a0, 3
50; RV32I-NEXT:    ret
51;
52; RV64I-LABEL: sltiu:
53; RV64I:       # %bb.0:
54; RV64I-NEXT:    sext.w a0, a0
55; RV64I-NEXT:    sltiu a0, a0, 3
56; RV64I-NEXT:    ret
57  %1 = icmp ult i32 %a, 3
58  %2 = zext i1 %1 to i32
59  ret i32 %2
60}
61
62define i32 @xori(i32 %a) nounwind {
63; RV32I-LABEL: xori:
64; RV32I:       # %bb.0:
65; RV32I-NEXT:    xori a0, a0, 4
66; RV32I-NEXT:    ret
67;
68; RV64I-LABEL: xori:
69; RV64I:       # %bb.0:
70; RV64I-NEXT:    xori a0, a0, 4
71; RV64I-NEXT:    ret
72  %1 = xor i32 %a, 4
73  ret i32 %1
74}
75
76define i32 @ori(i32 %a) nounwind {
77; RV32I-LABEL: ori:
78; RV32I:       # %bb.0:
79; RV32I-NEXT:    ori a0, a0, 5
80; RV32I-NEXT:    ret
81;
82; RV64I-LABEL: ori:
83; RV64I:       # %bb.0:
84; RV64I-NEXT:    ori a0, a0, 5
85; RV64I-NEXT:    ret
86  %1 = or i32 %a, 5
87  ret i32 %1
88}
89
90define i32 @andi(i32 %a) nounwind {
91; RV32I-LABEL: andi:
92; RV32I:       # %bb.0:
93; RV32I-NEXT:    andi a0, a0, 6
94; RV32I-NEXT:    ret
95;
96; RV64I-LABEL: andi:
97; RV64I:       # %bb.0:
98; RV64I-NEXT:    andi a0, a0, 6
99; RV64I-NEXT:    ret
100  %1 = and i32 %a, 6
101  ret i32 %1
102}
103
104define i32 @slli(i32 %a) nounwind {
105; RV32I-LABEL: slli:
106; RV32I:       # %bb.0:
107; RV32I-NEXT:    slli a0, a0, 7
108; RV32I-NEXT:    ret
109;
110; RV64I-LABEL: slli:
111; RV64I:       # %bb.0:
112; RV64I-NEXT:    slli a0, a0, 7
113; RV64I-NEXT:    ret
114  %1 = shl i32 %a, 7
115  ret i32 %1
116}
117
118define i32 @srli(i32 %a) nounwind {
119; RV32I-LABEL: srli:
120; RV32I:       # %bb.0:
121; RV32I-NEXT:    srli a0, a0, 8
122; RV32I-NEXT:    ret
123;
124; RV64I-LABEL: srli:
125; RV64I:       # %bb.0:
126; RV64I-NEXT:    srliw a0, a0, 8
127; RV64I-NEXT:    ret
128  %1 = lshr i32 %a, 8
129  ret i32 %1
130}
131
132define i32 @srai(i32 %a) nounwind {
133; RV32I-LABEL: srai:
134; RV32I:       # %bb.0:
135; RV32I-NEXT:    srai a0, a0, 9
136; RV32I-NEXT:    ret
137;
138; RV64I-LABEL: srai:
139; RV64I:       # %bb.0:
140; RV64I-NEXT:    sraiw a0, a0, 9
141; RV64I-NEXT:    ret
142  %1 = ashr i32 %a, 9
143  ret i32 %1
144}
145
146; Register-register instructions
147
148define i32 @add(i32 %a, i32 %b) nounwind {
149; RV32I-LABEL: add:
150; RV32I:       # %bb.0:
151; RV32I-NEXT:    add a0, a0, a1
152; RV32I-NEXT:    ret
153;
154; RV64I-LABEL: add:
155; RV64I:       # %bb.0:
156; RV64I-NEXT:    addw a0, a0, a1
157; RV64I-NEXT:    ret
158  %1 = add i32 %a, %b
159  ret i32 %1
160}
161
162define i32 @sub(i32 %a, i32 %b) nounwind {
163; RV32I-LABEL: sub:
164; RV32I:       # %bb.0:
165; RV32I-NEXT:    sub a0, a0, a1
166; RV32I-NEXT:    ret
167;
168; RV64I-LABEL: sub:
169; RV64I:       # %bb.0:
170; RV64I-NEXT:    subw a0, a0, a1
171; RV64I-NEXT:    ret
172  %1 = sub i32 %a, %b
173  ret i32 %1
174}
175
176define i32 @sll(i32 %a, i32 %b) nounwind {
177; RV32I-LABEL: sll:
178; RV32I:       # %bb.0:
179; RV32I-NEXT:    sll a0, a0, a1
180; RV32I-NEXT:    ret
181;
182; RV64I-LABEL: sll:
183; RV64I:       # %bb.0:
184; RV64I-NEXT:    sllw a0, a0, a1
185; RV64I-NEXT:    ret
186  %1 = shl i32 %a, %b
187  ret i32 %1
188}
189
190define i32 @slt(i32 %a, i32 %b) nounwind {
191; RV32I-LABEL: slt:
192; RV32I:       # %bb.0:
193; RV32I-NEXT:    slt a0, a0, a1
194; RV32I-NEXT:    ret
195;
196; RV64I-LABEL: slt:
197; RV64I:       # %bb.0:
198; RV64I-NEXT:    sext.w a1, a1
199; RV64I-NEXT:    sext.w a0, a0
200; RV64I-NEXT:    slt a0, a0, a1
201; RV64I-NEXT:    ret
202  %1 = icmp slt i32 %a, %b
203  %2 = zext i1 %1 to i32
204  ret i32 %2
205}
206
207define i32 @sltu(i32 %a, i32 %b) nounwind {
208; RV32I-LABEL: sltu:
209; RV32I:       # %bb.0:
210; RV32I-NEXT:    sltu a0, a0, a1
211; RV32I-NEXT:    ret
212;
213; RV64I-LABEL: sltu:
214; RV64I:       # %bb.0:
215; RV64I-NEXT:    sext.w a1, a1
216; RV64I-NEXT:    sext.w a0, a0
217; RV64I-NEXT:    sltu a0, a0, a1
218; RV64I-NEXT:    ret
219  %1 = icmp ult i32 %a, %b
220  %2 = zext i1 %1 to i32
221  ret i32 %2
222}
223
224define i32 @xor(i32 %a, i32 %b) nounwind {
225; RV32I-LABEL: xor:
226; RV32I:       # %bb.0:
227; RV32I-NEXT:    xor a0, a0, a1
228; RV32I-NEXT:    ret
229;
230; RV64I-LABEL: xor:
231; RV64I:       # %bb.0:
232; RV64I-NEXT:    xor a0, a0, a1
233; RV64I-NEXT:    ret
234  %1 = xor i32 %a, %b
235  ret i32 %1
236}
237
238define i32 @srl(i32 %a, i32 %b) nounwind {
239; RV32I-LABEL: srl:
240; RV32I:       # %bb.0:
241; RV32I-NEXT:    srl a0, a0, a1
242; RV32I-NEXT:    ret
243;
244; RV64I-LABEL: srl:
245; RV64I:       # %bb.0:
246; RV64I-NEXT:    srlw a0, a0, a1
247; RV64I-NEXT:    ret
248  %1 = lshr i32 %a, %b
249  ret i32 %1
250}
251
252define i32 @sra(i32 %a, i32 %b) nounwind {
253; RV32I-LABEL: sra:
254; RV32I:       # %bb.0:
255; RV32I-NEXT:    sra a0, a0, a1
256; RV32I-NEXT:    ret
257;
258; RV64I-LABEL: sra:
259; RV64I:       # %bb.0:
260; RV64I-NEXT:    sraw a0, a0, a1
261; RV64I-NEXT:    ret
262  %1 = ashr i32 %a, %b
263  ret i32 %1
264}
265
266define i32 @or(i32 %a, i32 %b) nounwind {
267; RV32I-LABEL: or:
268; RV32I:       # %bb.0:
269; RV32I-NEXT:    or a0, a0, a1
270; RV32I-NEXT:    ret
271;
272; RV64I-LABEL: or:
273; RV64I:       # %bb.0:
274; RV64I-NEXT:    or a0, a0, a1
275; RV64I-NEXT:    ret
276  %1 = or i32 %a, %b
277  ret i32 %1
278}
279
280define i32 @and(i32 %a, i32 %b) nounwind {
281; RV32I-LABEL: and:
282; RV32I:       # %bb.0:
283; RV32I-NEXT:    and a0, a0, a1
284; RV32I-NEXT:    ret
285;
286; RV64I-LABEL: and:
287; RV64I:       # %bb.0:
288; RV64I-NEXT:    and a0, a0, a1
289; RV64I-NEXT:    ret
290  %1 = and i32 %a, %b
291  ret i32 %1
292}
293