blob: 29bf787863d5f502e150b8871537518c9fcf0697 [file] [log] [blame]
Dan Gohmanb7c24002016-05-21 00:21:56 +00001; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
Dan Gohmana01e8bd2016-05-14 02:15:47 +00002
3; Test that basic 128-bit integer operations assemble as expected.
4
5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6target triple = "wasm32-unknown-unknown"
7
8declare i128 @llvm.ctlz.i128(i128, i1)
9declare i128 @llvm.cttz.i128(i128, i1)
10declare i128 @llvm.ctpop.i128(i128)
11
12; CHECK-LABEL: add128:
13; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
14; CHECK-NOT: .result
15; CHECK: i64.add
16; CHECK: i64.store
17; CHECK: i64.add
18; CHECK: i64.store
19; CHECK-NEXT: return{{$}}
20define i128 @add128(i128 %x, i128 %y) {
21 %a = add i128 %x, %y
22 ret i128 %a
23}
24
25; CHECK-LABEL: sub128:
26; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
27; CHECK-NOT: .result
28; CHECK: i64.sub
29; CHECK: i64.store
30; CHECK: i64.sub
31; CHECK: i64.store
32; CHECK-NEXT: return{{$}}
33define i128 @sub128(i128 %x, i128 %y) {
34 %a = sub i128 %x, %y
35 ret i128 %a
36}
37
38; CHECK-LABEL: mul128:
39; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
40; CHECK-NOT: .result
41; CHECK: call __multi3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
42; CHECK: return{{$}}
43define i128 @mul128(i128 %x, i128 %y) {
44 %a = mul i128 %x, %y
45 ret i128 %a
46}
47
48; CHECK-LABEL: sdiv128:
49; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
50; CHECK-NOT: .result
51; CHECK: call __divti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
52; CHECK: return{{$}}
53define i128 @sdiv128(i128 %x, i128 %y) {
54 %a = sdiv i128 %x, %y
55 ret i128 %a
56}
57
58; CHECK-LABEL: udiv128:
59; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
60; CHECK-NOT: .result
61; CHECK: call __udivti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
62; CHECK: return{{$}}
63define i128 @udiv128(i128 %x, i128 %y) {
64 %a = udiv i128 %x, %y
65 ret i128 %a
66}
67
68; CHECK-LABEL: srem128:
69; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
70; CHECK-NOT: .result
71; CHECK: call __modti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
72; CHECK: return{{$}}
73define i128 @srem128(i128 %x, i128 %y) {
74 %a = srem i128 %x, %y
75 ret i128 %a
76}
77
78; CHECK-LABEL: urem128:
79; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
80; CHECK-NOT: .result
81; CHECK: call __umodti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
82; CHECK: return{{$}}
83define i128 @urem128(i128 %x, i128 %y) {
84 %a = urem i128 %x, %y
85 ret i128 %a
86}
87
88; CHECK-LABEL: and128:
89; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
90; CHECK-NOT: .result
91; CHECK: i64.and
92; CHECK: i64.store
93; CHECK: i64.and
94; CHECK: i64.store
95; CHECK-NEXT: return{{$}}
96define i128 @and128(i128 %x, i128 %y) {
97 %a = and i128 %x, %y
98 ret i128 %a
99}
100
101; CHECK-LABEL: or128:
102; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
103; CHECK-NOT: .result
104; CHECK: i64.or
105; CHECK: i64.store
106; CHECK: i64.or
107; CHECK: i64.store
108; CHECK-NEXT: return{{$}}
109define i128 @or128(i128 %x, i128 %y) {
110 %a = or i128 %x, %y
111 ret i128 %a
112}
113
114; CHECK-LABEL: xor128:
115; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
116; CHECK-NOT: .result
117; CHECK: i64.xor
118; CHECK: i64.store
119; CHECK: i64.xor
120; CHECK: i64.store
121; CHECK-NEXT: return{{$}}
122define i128 @xor128(i128 %x, i128 %y) {
123 %a = xor i128 %x, %y
124 ret i128 %a
125}
126
127; CHECK-LABEL: shl128:
128; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
129; CHECK-NOT: .result
130; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
131; CHECK: return{{$}}
132define i128 @shl128(i128 %x, i128 %y) {
133 %a = shl i128 %x, %y
134 ret i128 %a
135}
136
137; CHECK-LABEL: shr128:
138; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
139; CHECK-NOT: .result
140; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
141; CHECK: return{{$}}
142define i128 @shr128(i128 %x, i128 %y) {
143 %a = lshr i128 %x, %y
144 ret i128 %a
145}
146
147; CHECK-LABEL: sar128:
148; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
149; CHECK-NOT: .result
150; CHECK: call __ashrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
151; CHECK: return{{$}}
152define i128 @sar128(i128 %x, i128 %y) {
153 %a = ashr i128 %x, %y
154 ret i128 %a
155}
156
157; CHECK-LABEL: clz128:
158; CHECK-NEXT: .param i32, i64, i64{{$}}
159; CHECK-NOT: .result
160; CHECK: i64.clz
161; CHECK: i64.clz
162; CHECK: return{{$}}
163define i128 @clz128(i128 %x) {
164 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 false)
165 ret i128 %a
166}
167
168; CHECK-LABEL: clz128_zero_undef:
169; CHECK-NEXT: .param i32, i64, i64{{$}}
170; CHECK-NOT: .result
171; CHECK: i64.clz
172; CHECK: i64.clz
173; CHECK: return{{$}}
174define i128 @clz128_zero_undef(i128 %x) {
175 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 true)
176 ret i128 %a
177}
178
179; CHECK-LABEL: ctz128:
180; CHECK-NEXT: .param i32, i64, i64{{$}}
181; CHECK-NOT: .result
182; CHECK: i64.ctz
183; CHECK: i64.ctz
184; CHECK: return{{$}}
185define i128 @ctz128(i128 %x) {
186 %a = call i128 @llvm.cttz.i128(i128 %x, i1 false)
187 ret i128 %a
188}
189
190; CHECK-LABEL: ctz128_zero_undef:
191; CHECK-NEXT: .param i32, i64, i64{{$}}
192; CHECK-NOT: .result
193; CHECK: i64.ctz
194; CHECK: i64.ctz
195; CHECK: return{{$}}
196define i128 @ctz128_zero_undef(i128 %x) {
197 %a = call i128 @llvm.cttz.i128(i128 %x, i1 true)
198 ret i128 %a
199}
200
201; CHECK-LABEL: popcnt128:
202; CHECK-NEXT: .param i32, i64, i64{{$}}
203; CHECK-NOT: .result
204; CHECK: i64.popcnt
205; CHECK: i64.popcnt
206; CHECK: return{{$}}
207define i128 @popcnt128(i128 %x) {
208 %a = call i128 @llvm.ctpop.i128(i128 %x)
209 ret i128 %a
210}
211
212; CHECK-LABEL: eqz128:
213; CHECK-NEXT: .param i64, i64{{$}}
214; CHECK-NEXT: .result i32{{$}}
215; CHECK: i64.or
216; CHECK: i64.eqz
217; CHECK: return $
218define i32 @eqz128(i128 %x) {
219 %a = icmp eq i128 %x, 0
220 %b = zext i1 %a to i32
221 ret i32 %b
222}
223
224; CHECK-LABEL: rotl:
225; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
226; CHECK-NOT: .result
227; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
228; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
229; CHECK: return{{$}}
230define i128 @rotl(i128 %x, i128 %y) {
231 %z = sub i128 128, %y
232 %b = shl i128 %x, %y
233 %c = lshr i128 %x, %z
234 %d = or i128 %b, %c
235 ret i128 %d
236}
237
238; CHECK-LABEL: masked_rotl:
239; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
240; CHECK-NOT: .result
241; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
242; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
243; CHECK: return{{$}}
244define i128 @masked_rotl(i128 %x, i128 %y) {
245 %a = and i128 %y, 127
246 %z = sub i128 128, %a
247 %b = shl i128 %x, %a
248 %c = lshr i128 %x, %z
249 %d = or i128 %b, %c
250 ret i128 %d
251}
252
253; CHECK-LABEL: rotr:
254; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
255; CHECK-NOT: .result
256; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
257; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
258; CHECK: return{{$}}
259define i128 @rotr(i128 %x, i128 %y) {
260 %z = sub i128 128, %y
261 %b = lshr i128 %x, %y
262 %c = shl i128 %x, %z
263 %d = or i128 %b, %c
264 ret i128 %d
265}
266
267; CHECK-LABEL: masked_rotr:
268; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
269; CHECK-NOT: .result
270; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
271; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
272; CHECK: return{{$}}
273define i128 @masked_rotr(i128 %x, i128 %y) {
274 %a = and i128 %y, 127
275 %z = sub i128 128, %a
276 %b = lshr i128 %x, %a
277 %c = shl i128 %x, %z
278 %d = or i128 %b, %c
279 ret i128 %d
280}