1; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s
2; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s
3; RUN: %if ptxas %{ llc < %s -march=nvptx -mcpu=sm_20 | %ptxas-verify %}
4; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_20 | %ptxas-verify %}
5
6;; These tests should run for all targets
7
8;;===-- Basic instruction selection tests ---------------------------------===;;
9
10
11;;; i64
12
13define i64 @add_i64(i64 %a, i64 %b) {
14; CHECK: add.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
15; CHECK: ret
16  %ret = add i64 %a, %b
17  ret i64 %ret
18}
19
20define i64 @sub_i64(i64 %a, i64 %b) {
21; CHECK: sub.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
22; CHECK: ret
23  %ret = sub i64 %a, %b
24  ret i64 %ret
25}
26
27define i64 @mul_i64(i64 %a, i64 %b) {
28; CHECK: mul.lo.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
29; CHECK: ret
30  %ret = mul i64 %a, %b
31  ret i64 %ret
32}
33
34define i64 @umul_lohi_i64(i64 %a) {
35; CHECK-LABEL: umul_lohi_i64(
36entry:
37  %0 = zext i64 %a to i128
38  %1 = mul i128 %0, 288
39; CHECK: mul.lo.{{u|s}}64
40; CHECK: mul.hi.{{u|s}}64
41  %2 = lshr i128 %1, 1
42  %3 = trunc i128 %2 to i64
43  ret i64 %3
44}
45
46define i64 @smul_lohi_i64(i64 %a) {
47; CHECK-LABEL: smul_lohi_i64(
48entry:
49  %0 = sext i64 %a to i128
50  %1 = mul i128 %0, 288
51; CHECK: mul.lo.{{u|s}}64
52; CHECK: mul.hi.{{u|s}}64
53  %2 = ashr i128 %1, 1
54  %3 = trunc i128 %2 to i64
55  ret i64 %3
56}
57
58define i64 @sdiv_i64(i64 %a, i64 %b) {
59; CHECK: div.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
60; CHECK: ret
61  %ret = sdiv i64 %a, %b
62  ret i64 %ret
63}
64
65define i64 @udiv_i64(i64 %a, i64 %b) {
66; CHECK: div.u64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
67; CHECK: ret
68  %ret = udiv i64 %a, %b
69  ret i64 %ret
70}
71
72define i64 @srem_i64(i64 %a, i64 %b) {
73; CHECK: rem.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
74; CHECK: ret
75  %ret = srem i64 %a, %b
76  ret i64 %ret
77}
78
79define i64 @urem_i64(i64 %a, i64 %b) {
80; CHECK: rem.u64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
81; CHECK: ret
82  %ret = urem i64 %a, %b
83  ret i64 %ret
84}
85
86define i64 @and_i64(i64 %a, i64 %b) {
87; CHECK: and.b64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
88; CHECK: ret
89  %ret = and i64 %a, %b
90  ret i64 %ret
91}
92
93define i64 @or_i64(i64 %a, i64 %b) {
94; CHECK: or.b64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
95; CHECK: ret
96  %ret = or i64 %a, %b
97  ret i64 %ret
98}
99
100define i64 @xor_i64(i64 %a, i64 %b) {
101; CHECK: xor.b64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %rd{{[0-9]+}}
102; CHECK: ret
103  %ret = xor i64 %a, %b
104  ret i64 %ret
105}
106
107define i64 @shl_i64(i64 %a, i64 %b) {
108; PTX requires 32-bit shift amount
109; CHECK: shl.b64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %r{{[0-9]+}}
110; CHECK: ret
111  %ret = shl i64 %a, %b
112  ret i64 %ret
113}
114
115define i64 @ashr_i64(i64 %a, i64 %b) {
116; PTX requires 32-bit shift amount
117; CHECK: shr.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %r{{[0-9]+}}
118; CHECK: ret
119  %ret = ashr i64 %a, %b
120  ret i64 %ret
121}
122
123define i64 @lshr_i64(i64 %a, i64 %b) {
124; PTX requires 32-bit shift amount
125; CHECK: shr.u64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, %r{{[0-9]+}}
126; CHECK: ret
127  %ret = lshr i64 %a, %b
128  ret i64 %ret
129}
130
131
132;;; i32
133
134define i32 @add_i32(i32 %a, i32 %b) {
135; CHECK: add.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
136; CHECK: ret
137  %ret = add i32 %a, %b
138  ret i32 %ret
139}
140
141define i32 @sub_i32(i32 %a, i32 %b) {
142; CHECK: sub.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
143; CHECK: ret
144  %ret = sub i32 %a, %b
145  ret i32 %ret
146}
147
148define i32 @mul_i32(i32 %a, i32 %b) {
149; CHECK: mul.lo.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
150; CHECK: ret
151  %ret = mul i32 %a, %b
152  ret i32 %ret
153}
154
155define i32 @sdiv_i32(i32 %a, i32 %b) {
156; CHECK: div.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
157; CHECK: ret
158  %ret = sdiv i32 %a, %b
159  ret i32 %ret
160}
161
162define i32 @udiv_i32(i32 %a, i32 %b) {
163; CHECK: div.u32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
164; CHECK: ret
165  %ret = udiv i32 %a, %b
166  ret i32 %ret
167}
168
169define i32 @srem_i32(i32 %a, i32 %b) {
170; CHECK: rem.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
171; CHECK: ret
172  %ret = srem i32 %a, %b
173  ret i32 %ret
174}
175
176define i32 @urem_i32(i32 %a, i32 %b) {
177; CHECK: rem.u32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
178; CHECK: ret
179  %ret = urem i32 %a, %b
180  ret i32 %ret
181}
182
183define i32 @and_i32(i32 %a, i32 %b) {
184; CHECK: and.b32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
185; CHECK: ret
186  %ret = and i32 %a, %b
187  ret i32 %ret
188}
189
190define i32 @or_i32(i32 %a, i32 %b) {
191; CHECK: or.b32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
192; CHECK: ret
193  %ret = or i32 %a, %b
194  ret i32 %ret
195}
196
197define i32 @xor_i32(i32 %a, i32 %b) {
198; CHECK: xor.b32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
199; CHECK: ret
200  %ret = xor i32 %a, %b
201  ret i32 %ret
202}
203
204define i32 @shl_i32(i32 %a, i32 %b) {
205; CHECK: shl.b32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
206; CHECK: ret
207  %ret = shl i32 %a, %b
208  ret i32 %ret
209}
210
211define i32 @ashr_i32(i32 %a, i32 %b) {
212; CHECK: shr.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
213; CHECK: ret
214  %ret = ashr i32 %a, %b
215  ret i32 %ret
216}
217
218define i32 @lshr_i32(i32 %a, i32 %b) {
219; CHECK: shr.u32 %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}
220; CHECK: ret
221  %ret = lshr i32 %a, %b
222  ret i32 %ret
223}
224
225;;; i16
226
227define i16 @add_i16(i16 %a, i16 %b) {
228; CHECK: add.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
229; CHECK: ret
230  %ret = add i16 %a, %b
231  ret i16 %ret
232}
233
234define i16 @sub_i16(i16 %a, i16 %b) {
235; CHECK: sub.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
236; CHECK: ret
237  %ret = sub i16 %a, %b
238  ret i16 %ret
239}
240
241define i16 @mul_i16(i16 %a, i16 %b) {
242; CHECK: mul.lo.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
243; CHECK: ret
244  %ret = mul i16 %a, %b
245  ret i16 %ret
246}
247
248define i16 @sdiv_i16(i16 %a, i16 %b) {
249; CHECK: div.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
250; CHECK: ret
251  %ret = sdiv i16 %a, %b
252  ret i16 %ret
253}
254
255define i16 @udiv_i16(i16 %a, i16 %b) {
256; CHECK: div.u16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
257; CHECK: ret
258  %ret = udiv i16 %a, %b
259  ret i16 %ret
260}
261
262define i16 @srem_i16(i16 %a, i16 %b) {
263; CHECK: rem.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
264; CHECK: ret
265  %ret = srem i16 %a, %b
266  ret i16 %ret
267}
268
269define i16 @urem_i16(i16 %a, i16 %b) {
270; CHECK: rem.u16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
271; CHECK: ret
272  %ret = urem i16 %a, %b
273  ret i16 %ret
274}
275
276define i16 @and_i16(i16 %a, i16 %b) {
277; CHECK: and.b16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
278; CHECK: ret
279  %ret = and i16 %a, %b
280  ret i16 %ret
281}
282
283define i16 @or_i16(i16 %a, i16 %b) {
284; CHECK: or.b16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
285; CHECK: ret
286  %ret = or i16 %a, %b
287  ret i16 %ret
288}
289
290define i16 @xor_i16(i16 %a, i16 %b) {
291; CHECK: xor.b16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %rs{{[0-9]+}}
292; CHECK: ret
293  %ret = xor i16 %a, %b
294  ret i16 %ret
295}
296
297define i16 @shl_i16(i16 %a, i16 %b) {
298; PTX requires 32-bit shift amount
299; CHECK: shl.b16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %r{{[0-9]+}}
300; CHECK: ret
301  %ret = shl i16 %a, %b
302  ret i16 %ret
303}
304
305define i16 @ashr_i16(i16 %a, i16 %b) {
306; PTX requires 32-bit shift amount
307; CHECK: shr.s16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %r{{[0-9]+}}
308; CHECK: ret
309  %ret = ashr i16 %a, %b
310  ret i16 %ret
311}
312
313define i16 @lshr_i16(i16 %a, i16 %b) {
314; PTX requires 32-bit shift amount
315; CHECK: shr.u16 %rs{{[0-9]+}}, %rs{{[0-9]+}}, %r{{[0-9]+}}
316; CHECK: ret
317  %ret = lshr i16 %a, %b
318  ret i16 %ret
319}
320