blob: 3f138a2c002f714e75b769ca8e6ecee8b692d5a3 [file] [log] [blame]
Wouter van Oortmerssena90d24d2018-07-27 23:19:51 +00001; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
Heejin Ahnfed73822018-07-09 22:30:51 +00003
4; Test atomic RMW (read-modify-write) instructions are assembled properly.
5
6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7target triple = "wasm32-unknown-unknown"
8
9;===----------------------------------------------------------------------------
10; Atomic read-modify-writes: 32-bit
11;===----------------------------------------------------------------------------
12
13; CHECK-LABEL: add_i32:
14; CHECK-NEXT: .param i32, i32{{$}}
15; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
16; CHECK-NEXT: return $pop0{{$}}
17define i32 @add_i32(i32* %p, i32 %v) {
18 %old = atomicrmw add i32* %p, i32 %v seq_cst
19 ret i32 %old
20}
21
22; CHECK-LABEL: sub_i32:
23; CHECK-NEXT: .param i32, i32{{$}}
24; CHECK: i32.atomic.rmw.sub $push0=, 0($0), $1{{$}}
25; CHECK-NEXT: return $pop0{{$}}
26define i32 @sub_i32(i32* %p, i32 %v) {
27 %old = atomicrmw sub i32* %p, i32 %v seq_cst
28 ret i32 %old
29}
30
31; CHECK-LABEL: and_i32:
32; CHECK-NEXT: .param i32, i32{{$}}
33; CHECK: i32.atomic.rmw.and $push0=, 0($0), $1{{$}}
34; CHECK-NEXT: return $pop0{{$}}
35define i32 @and_i32(i32* %p, i32 %v) {
36 %old = atomicrmw and i32* %p, i32 %v seq_cst
37 ret i32 %old
38}
39
40; CHECK-LABEL: or_i32:
41; CHECK-NEXT: .param i32, i32{{$}}
42; CHECK: i32.atomic.rmw.or $push0=, 0($0), $1{{$}}
43; CHECK-NEXT: return $pop0{{$}}
44define i32 @or_i32(i32* %p, i32 %v) {
45 %old = atomicrmw or i32* %p, i32 %v seq_cst
46 ret i32 %old
47}
48
49; CHECK-LABEL: xor_i32:
50; CHECK-NEXT: .param i32, i32{{$}}
51; CHECK: i32.atomic.rmw.xor $push0=, 0($0), $1{{$}}
52; CHECK-NEXT: return $pop0{{$}}
53define i32 @xor_i32(i32* %p, i32 %v) {
54 %old = atomicrmw xor i32* %p, i32 %v seq_cst
55 ret i32 %old
56}
57
58; CHECK-LABEL: xchg_i32:
59; CHECK-NEXT: .param i32, i32{{$}}
60; CHECK: i32.atomic.rmw.xchg $push0=, 0($0), $1{{$}}
61; CHECK-NEXT: return $pop0{{$}}
62define i32 @xchg_i32(i32* %p, i32 %v) {
63 %old = atomicrmw xchg i32* %p, i32 %v seq_cst
64 ret i32 %old
65}
66
Heejin Ahnb3724b72018-08-01 19:40:28 +000067; CHECK-LABEL: cmpxchg_i32_loaded_value:
68; CHECK-NEXT: .param i32, i32, i32{{$}}
69; CHECK: i32.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
70; CHECK-NEXT: return $pop0{{$}}
71define i32 @cmpxchg_i32_loaded_value(i32* %p, i32 %exp, i32 %new) {
72 %pair = cmpxchg i32* %p, i32 %exp, i32 %new seq_cst seq_cst
73 %old = extractvalue { i32, i1 } %pair, 0
74 ret i32 %old
75}
76
77; CHECK-LABEL: cmpxchg_i32_success:
78; CHECK-NEXT: .param i32, i32, i32{{$}}
79; CHECK: i32.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
80; CHECK-NEXT: i32.eq $push1=, $pop0, $1{{$}}
81; CHECK-NEXT: return $pop1{{$}}
82define i1 @cmpxchg_i32_success(i32* %p, i32 %exp, i32 %new) {
83 %pair = cmpxchg i32* %p, i32 %exp, i32 %new seq_cst seq_cst
84 %succ = extractvalue { i32, i1 } %pair, 1
85 ret i1 %succ
86}
87
Heejin Ahnfed73822018-07-09 22:30:51 +000088;===----------------------------------------------------------------------------
89; Atomic read-modify-writes: 64-bit
90;===----------------------------------------------------------------------------
91
92; CHECK-LABEL: add_i64:
93; CHECK-NEXT: .param i32, i64{{$}}
94; CHECK: i64.atomic.rmw.add $push0=, 0($0), $1{{$}}
95; CHECK-NEXT: return $pop0{{$}}
96define i64 @add_i64(i64* %p, i64 %v) {
97 %old = atomicrmw add i64* %p, i64 %v seq_cst
98 ret i64 %old
99}
100
101; CHECK-LABEL: sub_i64:
102; CHECK-NEXT: .param i32, i64{{$}}
103; CHECK: i64.atomic.rmw.sub $push0=, 0($0), $1{{$}}
104; CHECK-NEXT: return $pop0{{$}}
105define i64 @sub_i64(i64* %p, i64 %v) {
106 %old = atomicrmw sub i64* %p, i64 %v seq_cst
107 ret i64 %old
108}
109
110; CHECK-LABEL: and_i64:
111; CHECK-NEXT: .param i32, i64{{$}}
112; CHECK: i64.atomic.rmw.and $push0=, 0($0), $1{{$}}
113; CHECK-NEXT: return $pop0{{$}}
114define i64 @and_i64(i64* %p, i64 %v) {
115 %old = atomicrmw and i64* %p, i64 %v seq_cst
116 ret i64 %old
117}
118
119; CHECK-LABEL: or_i64:
120; CHECK-NEXT: .param i32, i64{{$}}
121; CHECK: i64.atomic.rmw.or $push0=, 0($0), $1{{$}}
122; CHECK-NEXT: return $pop0{{$}}
123define i64 @or_i64(i64* %p, i64 %v) {
124 %old = atomicrmw or i64* %p, i64 %v seq_cst
125 ret i64 %old
126}
127
128; CHECK-LABEL: xor_i64:
129; CHECK-NEXT: .param i32, i64{{$}}
130; CHECK: i64.atomic.rmw.xor $push0=, 0($0), $1{{$}}
131; CHECK-NEXT: return $pop0{{$}}
132define i64 @xor_i64(i64* %p, i64 %v) {
133 %old = atomicrmw xor i64* %p, i64 %v seq_cst
134 ret i64 %old
135}
136
137; CHECK-LABEL: xchg_i64:
138; CHECK-NEXT: .param i32, i64{{$}}
139; CHECK: i64.atomic.rmw.xchg $push0=, 0($0), $1{{$}}
140; CHECK-NEXT: return $pop0{{$}}
141define i64 @xchg_i64(i64* %p, i64 %v) {
142 %old = atomicrmw xchg i64* %p, i64 %v seq_cst
143 ret i64 %old
144}
145
Heejin Ahnb3724b72018-08-01 19:40:28 +0000146; CHECK-LABEL: cmpxchg_i64_loaded_value:
147; CHECK-NEXT: .param i32, i64, i64{{$}}
148; CHECK: i64.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
149; CHECK-NEXT: return $pop0{{$}}
150define i64 @cmpxchg_i64_loaded_value(i64* %p, i64 %exp, i64 %new) {
151 %pair = cmpxchg i64* %p, i64 %exp, i64 %new seq_cst seq_cst
152 %old = extractvalue { i64, i1 } %pair, 0
153 ret i64 %old
154}
155
156; CHECK-LABEL: cmpxchg_i64_success:
157; CHECK-NEXT: .param i32, i64, i64{{$}}
158; CHECK: i64.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
159; CHECK-NEXT: i64.eq $push1=, $pop0, $1{{$}}
160; CHECK-NEXT: return $pop1{{$}}
161define i1 @cmpxchg_i64_success(i64* %p, i64 %exp, i64 %new) {
162 %pair = cmpxchg i64* %p, i64 %exp, i64 %new seq_cst seq_cst
163 %succ = extractvalue { i64, i1 } %pair, 1
164 ret i1 %succ
165}
166
Heejin Ahnfed73822018-07-09 22:30:51 +0000167;===----------------------------------------------------------------------------
168; Atomic truncating & sign-extending RMWs
169;===----------------------------------------------------------------------------
170
171; add
172
173; CHECK-LABEL: add_sext_i8_i32:
174; CHECK-NEXT: .param i32, i32{{$}}
175; CHECK: i32.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
176; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
177; CHECK-NEXT: return $pop1{{$}}
178define i32 @add_sext_i8_i32(i8* %p, i32 %v) {
179 %t = trunc i32 %v to i8
180 %old = atomicrmw add i8* %p, i8 %t seq_cst
181 %e = sext i8 %old to i32
182 ret i32 %e
183}
184
185; CHECK-LABEL: add_sext_i16_i32:
186; CHECK-NEXT: .param i32, i32{{$}}
187; CHECK: i32.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
188; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
189; CHECK-NEXT: return $pop1{{$}}
190define i32 @add_sext_i16_i32(i16* %p, i32 %v) {
191 %t = trunc i32 %v to i16
192 %old = atomicrmw add i16* %p, i16 %t seq_cst
193 %e = sext i16 %old to i32
194 ret i32 %e
195}
196
197; CHECK-LABEL: add_sext_i8_i64:
198; CHECK-NEXT: .param i32, i64{{$}}
199; CHECK: i64.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
200; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
201; CHECK-NEXT: return $pop1{{$}}
202define i64 @add_sext_i8_i64(i8* %p, i64 %v) {
203 %t = trunc i64 %v to i8
204 %old = atomicrmw add i8* %p, i8 %t seq_cst
205 %e = sext i8 %old to i64
206 ret i64 %e
207}
208
209; CHECK-LABEL: add_sext_i16_i64:
210; CHECK-NEXT: .param i32, i64{{$}}
211; CHECK: i64.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
212; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
213; CHECK-NEXT: return $pop1{{$}}
214define i64 @add_sext_i16_i64(i16* %p, i64 %v) {
215 %t = trunc i64 %v to i16
216 %old = atomicrmw add i16* %p, i16 %t seq_cst
217 %e = sext i16 %old to i64
218 ret i64 %e
219}
220
221; 32->64 sext rmw gets selected as i32.atomic.rmw.add, i64_extend_s/i32
222; CHECK-LABEL: add_sext_i32_i64:
223; CHECK-NEXT: .param i32, i64{{$}}
Heejin Ahn9ef850b2018-07-10 16:00:43 +0000224; CHECK: i32.wrap/i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000225; CHECK: i32.atomic.rmw.add $push1=, 0($0), $pop0{{$}}
226; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
227; CHECK-NEXT: return $pop2{{$}}
228define i64 @add_sext_i32_i64(i32* %p, i64 %v) {
229 %t = trunc i64 %v to i32
230 %old = atomicrmw add i32* %p, i32 %t seq_cst
231 %e = sext i32 %old to i64
232 ret i64 %e
233}
234
235; sub
236
237; CHECK-LABEL: sub_sext_i8_i32:
238; CHECK-NEXT: .param i32, i32{{$}}
239; CHECK: i32.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
240; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
241; CHECK-NEXT: return $pop1{{$}}
242define i32 @sub_sext_i8_i32(i8* %p, i32 %v) {
243 %t = trunc i32 %v to i8
244 %old = atomicrmw sub i8* %p, i8 %t seq_cst
245 %e = sext i8 %old to i32
246 ret i32 %e
247}
248
249; CHECK-LABEL: sub_sext_i16_i32:
250; CHECK-NEXT: .param i32, i32{{$}}
251; CHECK: i32.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
252; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
253; CHECK-NEXT: return $pop1{{$}}
254define i32 @sub_sext_i16_i32(i16* %p, i32 %v) {
255 %t = trunc i32 %v to i16
256 %old = atomicrmw sub i16* %p, i16 %t seq_cst
257 %e = sext i16 %old to i32
258 ret i32 %e
259}
260
261; CHECK-LABEL: sub_sext_i8_i64:
262; CHECK-NEXT: .param i32, i64{{$}}
263; CHECK: i64.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
264; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
265; CHECK-NEXT: return $pop1{{$}}
266define i64 @sub_sext_i8_i64(i8* %p, i64 %v) {
267 %t = trunc i64 %v to i8
268 %old = atomicrmw sub i8* %p, i8 %t seq_cst
269 %e = sext i8 %old to i64
270 ret i64 %e
271}
272
273; CHECK-LABEL: sub_sext_i16_i64:
274; CHECK-NEXT: .param i32, i64{{$}}
275; CHECK: i64.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
276; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
277; CHECK-NEXT: return $pop1{{$}}
278define i64 @sub_sext_i16_i64(i16* %p, i64 %v) {
279 %t = trunc i64 %v to i16
280 %old = atomicrmw sub i16* %p, i16 %t seq_cst
281 %e = sext i16 %old to i64
282 ret i64 %e
283}
284
285; 32->64 sext rmw gets selected as i32.atomic.rmw.sub, i64_extend_s/i32
286; CHECK-LABEL: sub_sext_i32_i64:
287; CHECK-NEXT: .param i32, i64{{$}}
288; CHECK: i32.wrap/i64 $push0=, $1
289; CHECK: i32.atomic.rmw.sub $push1=, 0($0), $pop0{{$}}
290; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
291; CHECK-NEXT: return $pop2{{$}}
292define i64 @sub_sext_i32_i64(i32* %p, i64 %v) {
293 %t = trunc i64 %v to i32
294 %old = atomicrmw sub i32* %p, i32 %t seq_cst
295 %e = sext i32 %old to i64
296 ret i64 %e
297}
298
299; and
300
301; CHECK-LABEL: and_sext_i8_i32:
302; CHECK-NEXT: .param i32, i32{{$}}
303; CHECK: i32.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
304; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
305; CHECK-NEXT: return $pop1{{$}}
306define i32 @and_sext_i8_i32(i8* %p, i32 %v) {
307 %t = trunc i32 %v to i8
308 %old = atomicrmw and i8* %p, i8 %t seq_cst
309 %e = sext i8 %old to i32
310 ret i32 %e
311}
312
313; CHECK-LABEL: and_sext_i16_i32:
314; CHECK-NEXT: .param i32, i32{{$}}
315; CHECK: i32.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
316; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
317; CHECK-NEXT: return $pop1{{$}}
318define i32 @and_sext_i16_i32(i16* %p, i32 %v) {
319 %t = trunc i32 %v to i16
320 %old = atomicrmw and i16* %p, i16 %t seq_cst
321 %e = sext i16 %old to i32
322 ret i32 %e
323}
324
325; CHECK-LABEL: and_sext_i8_i64:
326; CHECK-NEXT: .param i32, i64{{$}}
327; CHECK: i64.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
328; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
329; CHECK-NEXT: return $pop1{{$}}
330define i64 @and_sext_i8_i64(i8* %p, i64 %v) {
331 %t = trunc i64 %v to i8
332 %old = atomicrmw and i8* %p, i8 %t seq_cst
333 %e = sext i8 %old to i64
334 ret i64 %e
335}
336
337; CHECK-LABEL: and_sext_i16_i64:
338; CHECK-NEXT: .param i32, i64{{$}}
339; CHECK: i64.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
340; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
341; CHECK-NEXT: return $pop1{{$}}
342define i64 @and_sext_i16_i64(i16* %p, i64 %v) {
343 %t = trunc i64 %v to i16
344 %old = atomicrmw and i16* %p, i16 %t seq_cst
345 %e = sext i16 %old to i64
346 ret i64 %e
347}
348
349; 32->64 sext rmw gets selected as i32.atomic.rmw.and, i64_extend_s/i32
350; CHECK-LABEL: and_sext_i32_i64:
351; CHECK-NEXT: .param i32, i64{{$}}
Heejin Ahn9ef850b2018-07-10 16:00:43 +0000352; CHECK: i32.wrap/i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000353; CHECK: i32.atomic.rmw.and $push1=, 0($0), $pop0{{$}}
354; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
355; CHECK-NEXT: return $pop2{{$}}
356define i64 @and_sext_i32_i64(i32* %p, i64 %v) {
357 %t = trunc i64 %v to i32
358 %old = atomicrmw and i32* %p, i32 %t seq_cst
359 %e = sext i32 %old to i64
360 ret i64 %e
361}
362
363; or
364
365; CHECK-LABEL: or_sext_i8_i32:
366; CHECK-NEXT: .param i32, i32{{$}}
367; CHECK: i32.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
368; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
369; CHECK-NEXT: return $pop1{{$}}
370define i32 @or_sext_i8_i32(i8* %p, i32 %v) {
371 %t = trunc i32 %v to i8
372 %old = atomicrmw or i8* %p, i8 %t seq_cst
373 %e = sext i8 %old to i32
374 ret i32 %e
375}
376
377; CHECK-LABEL: or_sext_i16_i32:
378; CHECK-NEXT: .param i32, i32{{$}}
379; CHECK: i32.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
380; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
381; CHECK-NEXT: return $pop1{{$}}
382define i32 @or_sext_i16_i32(i16* %p, i32 %v) {
383 %t = trunc i32 %v to i16
384 %old = atomicrmw or i16* %p, i16 %t seq_cst
385 %e = sext i16 %old to i32
386 ret i32 %e
387}
388
389; CHECK-LABEL: or_sext_i8_i64:
390; CHECK-NEXT: .param i32, i64{{$}}
391; CHECK: i64.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
392; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
393; CHECK-NEXT: return $pop1{{$}}
394define i64 @or_sext_i8_i64(i8* %p, i64 %v) {
395 %t = trunc i64 %v to i8
396 %old = atomicrmw or i8* %p, i8 %t seq_cst
397 %e = sext i8 %old to i64
398 ret i64 %e
399}
400
401; CHECK-LABEL: or_sext_i16_i64:
402; CHECK-NEXT: .param i32, i64{{$}}
403; CHECK: i64.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
404; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
405; CHECK-NEXT: return $pop1{{$}}
406define i64 @or_sext_i16_i64(i16* %p, i64 %v) {
407 %t = trunc i64 %v to i16
408 %old = atomicrmw or i16* %p, i16 %t seq_cst
409 %e = sext i16 %old to i64
410 ret i64 %e
411}
412
413; 32->64 sext rmw gets selected as i32.atomic.rmw.or, i64_extend_s/i32
414; CHECK-LABEL: or_sext_i32_i64:
415; CHECK-NEXT: .param i32, i64{{$}}
Heejin Ahn9ef850b2018-07-10 16:00:43 +0000416; CHECK: i32.wrap/i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000417; CHECK: i32.atomic.rmw.or $push1=, 0($0), $pop0{{$}}
418; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
419; CHECK-NEXT: return $pop2{{$}}
420define i64 @or_sext_i32_i64(i32* %p, i64 %v) {
421 %t = trunc i64 %v to i32
422 %old = atomicrmw or i32* %p, i32 %t seq_cst
423 %e = sext i32 %old to i64
424 ret i64 %e
425}
426
427; xor
428
429; CHECK-LABEL: xor_sext_i8_i32:
430; CHECK-NEXT: .param i32, i32{{$}}
431; CHECK: i32.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
432; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
433; CHECK-NEXT: return $pop1{{$}}
434define i32 @xor_sext_i8_i32(i8* %p, i32 %v) {
435 %t = trunc i32 %v to i8
436 %old = atomicrmw xor i8* %p, i8 %t seq_cst
437 %e = sext i8 %old to i32
438 ret i32 %e
439}
440
441; CHECK-LABEL: xor_sext_i16_i32:
442; CHECK-NEXT: .param i32, i32{{$}}
443; CHECK: i32.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
444; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
445; CHECK-NEXT: return $pop1{{$}}
446define i32 @xor_sext_i16_i32(i16* %p, i32 %v) {
447 %t = trunc i32 %v to i16
448 %old = atomicrmw xor i16* %p, i16 %t seq_cst
449 %e = sext i16 %old to i32
450 ret i32 %e
451}
452
453; CHECK-LABEL: xor_sext_i8_i64:
454; CHECK-NEXT: .param i32, i64{{$}}
455; CHECK: i64.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
456; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
457; CHECK-NEXT: return $pop1{{$}}
458define i64 @xor_sext_i8_i64(i8* %p, i64 %v) {
459 %t = trunc i64 %v to i8
460 %old = atomicrmw xor i8* %p, i8 %t seq_cst
461 %e = sext i8 %old to i64
462 ret i64 %e
463}
464
465; CHECK-LABEL: xor_sext_i16_i64:
466; CHECK-NEXT: .param i32, i64{{$}}
467; CHECK: i64.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
468; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
469; CHECK-NEXT: return $pop1{{$}}
470define i64 @xor_sext_i16_i64(i16* %p, i64 %v) {
471 %t = trunc i64 %v to i16
472 %old = atomicrmw xor i16* %p, i16 %t seq_cst
473 %e = sext i16 %old to i64
474 ret i64 %e
475}
476
477; 32->64 sext rmw gets selected as i32.atomic.rmw.xor, i64_extend_s/i32
478; CHECK-LABEL: xor_sext_i32_i64:
479; CHECK-NEXT: .param i32, i64{{$}}
Heejin Ahn9ef850b2018-07-10 16:00:43 +0000480; CHECK: i32.wrap/i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000481; CHECK: i32.atomic.rmw.xor $push1=, 0($0), $pop0{{$}}
482; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
483; CHECK-NEXT: return $pop2{{$}}
484define i64 @xor_sext_i32_i64(i32* %p, i64 %v) {
485 %t = trunc i64 %v to i32
486 %old = atomicrmw xor i32* %p, i32 %t seq_cst
487 %e = sext i32 %old to i64
488 ret i64 %e
489}
490
491; xchg
492
493; CHECK-LABEL: xchg_sext_i8_i32:
494; CHECK-NEXT: .param i32, i32{{$}}
495; CHECK: i32.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
496; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
497; CHECK-NEXT: return $pop1{{$}}
498define i32 @xchg_sext_i8_i32(i8* %p, i32 %v) {
499 %t = trunc i32 %v to i8
500 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
501 %e = sext i8 %old to i32
502 ret i32 %e
503}
504
505; CHECK-LABEL: xchg_sext_i16_i32:
506; CHECK-NEXT: .param i32, i32{{$}}
507; CHECK: i32.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
508; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
509; CHECK-NEXT: return $pop1{{$}}
510define i32 @xchg_sext_i16_i32(i16* %p, i32 %v) {
511 %t = trunc i32 %v to i16
512 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
513 %e = sext i16 %old to i32
514 ret i32 %e
515}
516
517; CHECK-LABEL: xchg_sext_i8_i64:
518; CHECK-NEXT: .param i32, i64{{$}}
519; CHECK: i64.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
520; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
521; CHECK-NEXT: return $pop1{{$}}
522define i64 @xchg_sext_i8_i64(i8* %p, i64 %v) {
523 %t = trunc i64 %v to i8
524 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
525 %e = sext i8 %old to i64
526 ret i64 %e
527}
528
529; CHECK-LABEL: xchg_sext_i16_i64:
530; CHECK-NEXT: .param i32, i64{{$}}
531; CHECK: i64.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
532; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
533; CHECK-NEXT: return $pop1{{$}}
534define i64 @xchg_sext_i16_i64(i16* %p, i64 %v) {
535 %t = trunc i64 %v to i16
536 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
537 %e = sext i16 %old to i64
538 ret i64 %e
539}
540
541; 32->64 sext rmw gets selected as i32.atomic.rmw.xchg, i64_extend_s/i32
542; CHECK-LABEL: xchg_sext_i32_i64:
543; CHECK-NEXT: .param i32, i64{{$}}
Heejin Ahn9ef850b2018-07-10 16:00:43 +0000544; CHECK: i32.wrap/i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000545; CHECK: i32.atomic.rmw.xchg $push1=, 0($0), $pop0{{$}}
546; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
547; CHECK-NEXT: return $pop2{{$}}
548define i64 @xchg_sext_i32_i64(i32* %p, i64 %v) {
549 %t = trunc i64 %v to i32
550 %old = atomicrmw xchg i32* %p, i32 %t seq_cst
551 %e = sext i32 %old to i64
552 ret i64 %e
553}
554
Heejin Ahnb3724b72018-08-01 19:40:28 +0000555; cmpxchg
556
557; CHECK-LABEL: cmpxchg_sext_i8_i32:
558; CHECK-NEXT: .param i32, i32, i32{{$}}
559; CHECK: i32.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
560; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
561; CHECK-NEXT: return $pop1{{$}}
562define i32 @cmpxchg_sext_i8_i32(i8* %p, i32 %exp, i32 %new) {
563 %exp_t = trunc i32 %exp to i8
564 %new_t = trunc i32 %new to i8
565 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
566 %old = extractvalue { i8, i1 } %pair, 0
567 %e = sext i8 %old to i32
568 ret i32 %e
569}
570
571; CHECK-LABEL: cmpxchg_sext_i16_i32:
572; CHECK-NEXT: .param i32, i32, i32{{$}}
573; CHECK: i32.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
574; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
575; CHECK-NEXT: return $pop1{{$}}
576define i32 @cmpxchg_sext_i16_i32(i16* %p, i32 %exp, i32 %new) {
577 %exp_t = trunc i32 %exp to i16
578 %new_t = trunc i32 %new to i16
579 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
580 %old = extractvalue { i16, i1 } %pair, 0
581 %e = sext i16 %old to i32
582 ret i32 %e
583}
584
585; CHECK-LABEL: cmpxchg_sext_i8_i64:
586; CHECK-NEXT: .param i32, i64, i64{{$}}
587; CHECK: i64.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
588; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
589; CHECK-NEXT: return $pop1{{$}}
590define i64 @cmpxchg_sext_i8_i64(i8* %p, i64 %exp, i64 %new) {
591 %exp_t = trunc i64 %exp to i8
592 %new_t = trunc i64 %new to i8
593 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
594 %old = extractvalue { i8, i1 } %pair, 0
595 %e = sext i8 %old to i64
596 ret i64 %e
597}
598
599; CHECK-LABEL: cmpxchg_sext_i16_i64:
600; CHECK-NEXT: .param i32, i64, i64{{$}}
601; CHECK: i64.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
602; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
603; CHECK-NEXT: return $pop1{{$}}
604define i64 @cmpxchg_sext_i16_i64(i16* %p, i64 %exp, i64 %new) {
605 %exp_t = trunc i64 %exp to i16
606 %new_t = trunc i64 %new to i16
607 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
608 %old = extractvalue { i16, i1 } %pair, 0
609 %e = sext i16 %old to i64
610 ret i64 %e
611}
612
613; 32->64 sext rmw gets selected as i32.atomic.rmw.cmpxchg, i64_extend_s/i32
614; CHECK-LABEL: cmpxchg_sext_i32_i64:
615; CHECK-NEXT: .param i32, i64, i64{{$}}
616; CHECK: i32.wrap/i64 $push1=, $1{{$}}
617; CHECK-NEXT: i32.wrap/i64 $push0=, $2{{$}}
618; CHECK-NEXT: i32.atomic.rmw.cmpxchg $push2=, 0($0), $pop1, $pop0{{$}}
619; CHECK-NEXT: i64.extend_s/i32 $push3=, $pop2{{$}}
620; CHECK-NEXT: return $pop3{{$}}
621define i64 @cmpxchg_sext_i32_i64(i32* %p, i64 %exp, i64 %new) {
622 %exp_t = trunc i64 %exp to i32
623 %new_t = trunc i64 %new to i32
624 %pair = cmpxchg i32* %p, i32 %exp_t, i32 %new_t seq_cst seq_cst
625 %old = extractvalue { i32, i1 } %pair, 0
626 %e = sext i32 %old to i64
627 ret i64 %e
628}
629
Heejin Ahnfed73822018-07-09 22:30:51 +0000630;===----------------------------------------------------------------------------
631; Atomic truncating & zero-extending RMWs
632;===----------------------------------------------------------------------------
633
634; add
635
636; CHECK-LABEL: add_zext_i8_i32:
637; CHECK-NEXT: .param i32, i32{{$}}
638; CHECK: i32.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
639; CHECK-NEXT: return $pop0{{$}}
640define i32 @add_zext_i8_i32(i8* %p, i32 %v) {
641 %t = trunc i32 %v to i8
642 %old = atomicrmw add i8* %p, i8 %t seq_cst
643 %e = zext i8 %old to i32
644 ret i32 %e
645}
646
647; CHECK-LABEL: add_zext_i16_i32:
648; CHECK-NEXT: .param i32, i32{{$}}
649; CHECK: i32.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
650; CHECK-NEXT: return $pop0{{$}}
651define i32 @add_zext_i16_i32(i16* %p, i32 %v) {
652 %t = trunc i32 %v to i16
653 %old = atomicrmw add i16* %p, i16 %t seq_cst
654 %e = zext i16 %old to i32
655 ret i32 %e
656}
657
658; CHECK-LABEL: add_zext_i8_i64:
659; CHECK-NEXT: .param i32, i64{{$}}
660; CHECK: i64.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
661; CHECK-NEXT: return $pop0{{$}}
662define i64 @add_zext_i8_i64(i8* %p, i64 %v) {
663 %t = trunc i64 %v to i8
664 %old = atomicrmw add i8* %p, i8 %t seq_cst
665 %e = zext i8 %old to i64
666 ret i64 %e
667}
668
669; CHECK-LABEL: add_zext_i16_i64:
670; CHECK-NEXT: .param i32, i64{{$}}
671; CHECK: i64.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
672; CHECK-NEXT: return $pop0{{$}}
673define i64 @add_zext_i16_i64(i16* %p, i64 %v) {
674 %t = trunc i64 %v to i16
675 %old = atomicrmw add i16* %p, i16 %t seq_cst
676 %e = zext i16 %old to i64
677 ret i64 %e
678}
679
680; CHECK-LABEL: add_zext_i32_i64:
681; CHECK-NEXT: .param i32, i64{{$}}
682; CHECK: i64.atomic.rmw32_u.add $push0=, 0($0), $1{{$}}
683; CHECK-NEXT: return $pop0{{$}}
684define i64 @add_zext_i32_i64(i32* %p, i64 %v) {
685 %t = trunc i64 %v to i32
686 %old = atomicrmw add i32* %p, i32 %t seq_cst
687 %e = zext i32 %old to i64
688 ret i64 %e
689}
690
691; sub
692
693; CHECK-LABEL: sub_zext_i8_i32:
694; CHECK-NEXT: .param i32, i32{{$}}
695; CHECK: i32.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
696; CHECK-NEXT: return $pop0{{$}}
697define i32 @sub_zext_i8_i32(i8* %p, i32 %v) {
698 %t = trunc i32 %v to i8
699 %old = atomicrmw sub i8* %p, i8 %t seq_cst
700 %e = zext i8 %old to i32
701 ret i32 %e
702}
703
704; CHECK-LABEL: sub_zext_i16_i32:
705; CHECK-NEXT: .param i32, i32{{$}}
706; CHECK: i32.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
707; CHECK-NEXT: return $pop0{{$}}
708define i32 @sub_zext_i16_i32(i16* %p, i32 %v) {
709 %t = trunc i32 %v to i16
710 %old = atomicrmw sub i16* %p, i16 %t seq_cst
711 %e = zext i16 %old to i32
712 ret i32 %e
713}
714
715; CHECK-LABEL: sub_zext_i8_i64:
716; CHECK-NEXT: .param i32, i64{{$}}
717; CHECK: i64.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
718; CHECK-NEXT: return $pop0{{$}}
719define i64 @sub_zext_i8_i64(i8* %p, i64 %v) {
720 %t = trunc i64 %v to i8
721 %old = atomicrmw sub i8* %p, i8 %t seq_cst
722 %e = zext i8 %old to i64
723 ret i64 %e
724}
725
726; CHECK-LABEL: sub_zext_i16_i64:
727; CHECK-NEXT: .param i32, i64{{$}}
728; CHECK: i64.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
729; CHECK-NEXT: return $pop0{{$}}
730define i64 @sub_zext_i16_i64(i16* %p, i64 %v) {
731 %t = trunc i64 %v to i16
732 %old = atomicrmw sub i16* %p, i16 %t seq_cst
733 %e = zext i16 %old to i64
734 ret i64 %e
735}
736
737; CHECK-LABEL: sub_zext_i32_i64:
738; CHECK-NEXT: .param i32, i64{{$}}
739; CHECK: i64.atomic.rmw32_u.sub $push0=, 0($0), $1{{$}}
740; CHECK-NEXT: return $pop0{{$}}
741define i64 @sub_zext_i32_i64(i32* %p, i64 %v) {
742 %t = trunc i64 %v to i32
743 %old = atomicrmw sub i32* %p, i32 %t seq_cst
744 %e = zext i32 %old to i64
745 ret i64 %e
746}
747
748; and
749
750; CHECK-LABEL: and_zext_i8_i32:
751; CHECK-NEXT: .param i32, i32{{$}}
752; CHECK: i32.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
753; CHECK-NEXT: return $pop0{{$}}
754define i32 @and_zext_i8_i32(i8* %p, i32 %v) {
755 %t = trunc i32 %v to i8
756 %old = atomicrmw and i8* %p, i8 %t seq_cst
757 %e = zext i8 %old to i32
758 ret i32 %e
759}
760
761; CHECK-LABEL: and_zext_i16_i32:
762; CHECK-NEXT: .param i32, i32{{$}}
763; CHECK: i32.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
764; CHECK-NEXT: return $pop0{{$}}
765define i32 @and_zext_i16_i32(i16* %p, i32 %v) {
766 %t = trunc i32 %v to i16
767 %old = atomicrmw and i16* %p, i16 %t seq_cst
768 %e = zext i16 %old to i32
769 ret i32 %e
770}
771
772; CHECK-LABEL: and_zext_i8_i64:
773; CHECK-NEXT: .param i32, i64{{$}}
774; CHECK: i64.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
775; CHECK-NEXT: return $pop0{{$}}
776define i64 @and_zext_i8_i64(i8* %p, i64 %v) {
777 %t = trunc i64 %v to i8
778 %old = atomicrmw and i8* %p, i8 %t seq_cst
779 %e = zext i8 %old to i64
780 ret i64 %e
781}
782
783; CHECK-LABEL: and_zext_i16_i64:
784; CHECK-NEXT: .param i32, i64{{$}}
785; CHECK: i64.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
786; CHECK-NEXT: return $pop0{{$}}
787define i64 @and_zext_i16_i64(i16* %p, i64 %v) {
788 %t = trunc i64 %v to i16
789 %old = atomicrmw and i16* %p, i16 %t seq_cst
790 %e = zext i16 %old to i64
791 ret i64 %e
792}
793
794; CHECK-LABEL: and_zext_i32_i64:
795; CHECK-NEXT: .param i32, i64{{$}}
796; CHECK: i64.atomic.rmw32_u.and $push0=, 0($0), $1{{$}}
797; CHECK-NEXT: return $pop0{{$}}
798define i64 @and_zext_i32_i64(i32* %p, i64 %v) {
799 %t = trunc i64 %v to i32
800 %old = atomicrmw and i32* %p, i32 %t seq_cst
801 %e = zext i32 %old to i64
802 ret i64 %e
803}
804
805; or
806
807; CHECK-LABEL: or_zext_i8_i32:
808; CHECK-NEXT: .param i32, i32{{$}}
809; CHECK: i32.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
810; CHECK-NEXT: return $pop0{{$}}
811define i32 @or_zext_i8_i32(i8* %p, i32 %v) {
812 %t = trunc i32 %v to i8
813 %old = atomicrmw or i8* %p, i8 %t seq_cst
814 %e = zext i8 %old to i32
815 ret i32 %e
816}
817
818; CHECK-LABEL: or_zext_i16_i32:
819; CHECK-NEXT: .param i32, i32{{$}}
820; CHECK: i32.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
821; CHECK-NEXT: return $pop0{{$}}
822define i32 @or_zext_i16_i32(i16* %p, i32 %v) {
823 %t = trunc i32 %v to i16
824 %old = atomicrmw or i16* %p, i16 %t seq_cst
825 %e = zext i16 %old to i32
826 ret i32 %e
827}
828
829; CHECK-LABEL: or_zext_i8_i64:
830; CHECK-NEXT: .param i32, i64{{$}}
831; CHECK: i64.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
832; CHECK-NEXT: return $pop0{{$}}
833define i64 @or_zext_i8_i64(i8* %p, i64 %v) {
834 %t = trunc i64 %v to i8
835 %old = atomicrmw or i8* %p, i8 %t seq_cst
836 %e = zext i8 %old to i64
837 ret i64 %e
838}
839
840; CHECK-LABEL: or_zext_i16_i64:
841; CHECK-NEXT: .param i32, i64{{$}}
842; CHECK: i64.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
843; CHECK-NEXT: return $pop0{{$}}
844define i64 @or_zext_i16_i64(i16* %p, i64 %v) {
845 %t = trunc i64 %v to i16
846 %old = atomicrmw or i16* %p, i16 %t seq_cst
847 %e = zext i16 %old to i64
848 ret i64 %e
849}
850
851; CHECK-LABEL: or_zext_i32_i64:
852; CHECK-NEXT: .param i32, i64{{$}}
853; CHECK: i64.atomic.rmw32_u.or $push0=, 0($0), $1{{$}}
854; CHECK-NEXT: return $pop0{{$}}
855define i64 @or_zext_i32_i64(i32* %p, i64 %v) {
856 %t = trunc i64 %v to i32
857 %old = atomicrmw or i32* %p, i32 %t seq_cst
858 %e = zext i32 %old to i64
859 ret i64 %e
860}
861
862; xor
863
864; CHECK-LABEL: xor_zext_i8_i32:
865; CHECK-NEXT: .param i32, i32{{$}}
866; CHECK: i32.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
867; CHECK-NEXT: return $pop0{{$}}
868define i32 @xor_zext_i8_i32(i8* %p, i32 %v) {
869 %t = trunc i32 %v to i8
870 %old = atomicrmw xor i8* %p, i8 %t seq_cst
871 %e = zext i8 %old to i32
872 ret i32 %e
873}
874
875; CHECK-LABEL: xor_zext_i16_i32:
876; CHECK-NEXT: .param i32, i32{{$}}
877; CHECK: i32.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
878; CHECK-NEXT: return $pop0{{$}}
879define i32 @xor_zext_i16_i32(i16* %p, i32 %v) {
880 %t = trunc i32 %v to i16
881 %old = atomicrmw xor i16* %p, i16 %t seq_cst
882 %e = zext i16 %old to i32
883 ret i32 %e
884}
885
886; CHECK-LABEL: xor_zext_i8_i64:
887; CHECK-NEXT: .param i32, i64{{$}}
888; CHECK: i64.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
889; CHECK-NEXT: return $pop0{{$}}
890define i64 @xor_zext_i8_i64(i8* %p, i64 %v) {
891 %t = trunc i64 %v to i8
892 %old = atomicrmw xor i8* %p, i8 %t seq_cst
893 %e = zext i8 %old to i64
894 ret i64 %e
895}
896
897; CHECK-LABEL: xor_zext_i16_i64:
898; CHECK-NEXT: .param i32, i64{{$}}
899; CHECK: i64.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
900; CHECK-NEXT: return $pop0{{$}}
901define i64 @xor_zext_i16_i64(i16* %p, i64 %v) {
902 %t = trunc i64 %v to i16
903 %old = atomicrmw xor i16* %p, i16 %t seq_cst
904 %e = zext i16 %old to i64
905 ret i64 %e
906}
907
908; CHECK-LABEL: xor_zext_i32_i64:
909; CHECK-NEXT: .param i32, i64{{$}}
910; CHECK: i64.atomic.rmw32_u.xor $push0=, 0($0), $1{{$}}
911; CHECK-NEXT: return $pop0{{$}}
912define i64 @xor_zext_i32_i64(i32* %p, i64 %v) {
913 %t = trunc i64 %v to i32
914 %old = atomicrmw xor i32* %p, i32 %t seq_cst
915 %e = zext i32 %old to i64
916 ret i64 %e
917}
918
919; xchg
920
921; CHECK-LABEL: xchg_zext_i8_i32:
922; CHECK-NEXT: .param i32, i32{{$}}
923; CHECK: i32.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
924; CHECK-NEXT: return $pop0{{$}}
925define i32 @xchg_zext_i8_i32(i8* %p, i32 %v) {
926 %t = trunc i32 %v to i8
927 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
928 %e = zext i8 %old to i32
929 ret i32 %e
930}
931
932; CHECK-LABEL: xchg_zext_i16_i32:
933; CHECK-NEXT: .param i32, i32{{$}}
934; CHECK: i32.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
935; CHECK-NEXT: return $pop0{{$}}
936define i32 @xchg_zext_i16_i32(i16* %p, i32 %v) {
937 %t = trunc i32 %v to i16
938 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
939 %e = zext i16 %old to i32
940 ret i32 %e
941}
942
943; CHECK-LABEL: xchg_zext_i8_i64:
944; CHECK-NEXT: .param i32, i64{{$}}
945; CHECK: i64.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
946; CHECK-NEXT: return $pop0{{$}}
947define i64 @xchg_zext_i8_i64(i8* %p, i64 %v) {
948 %t = trunc i64 %v to i8
949 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
950 %e = zext i8 %old to i64
951 ret i64 %e
952}
953
954; CHECK-LABEL: xchg_zext_i16_i64:
955; CHECK-NEXT: .param i32, i64{{$}}
956; CHECK: i64.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
957; CHECK-NEXT: return $pop0{{$}}
958define i64 @xchg_zext_i16_i64(i16* %p, i64 %v) {
959 %t = trunc i64 %v to i16
960 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
961 %e = zext i16 %old to i64
962 ret i64 %e
963}
964
965; CHECK-LABEL: xchg_zext_i32_i64:
966; CHECK-NEXT: .param i32, i64{{$}}
967; CHECK: i64.atomic.rmw32_u.xchg $push0=, 0($0), $1{{$}}
968; CHECK-NEXT: return $pop0{{$}}
969define i64 @xchg_zext_i32_i64(i32* %p, i64 %v) {
970 %t = trunc i64 %v to i32
971 %old = atomicrmw xchg i32* %p, i32 %t seq_cst
972 %e = zext i32 %old to i64
973 ret i64 %e
974}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000975
976; cmpxchg
977
978; CHECK-LABEL: cmpxchg_zext_i8_i32:
979; CHECK-NEXT: .param i32, i32, i32{{$}}
980; CHECK: i32.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
981; CHECK-NEXT: return $pop0{{$}}
982define i32 @cmpxchg_zext_i8_i32(i8* %p, i32 %exp, i32 %new) {
983 %exp_t = trunc i32 %exp to i8
984 %new_t = trunc i32 %new to i8
985 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
986 %old = extractvalue { i8, i1 } %pair, 0
987 %e = zext i8 %old to i32
988 ret i32 %e
989}
990
991; CHECK-LABEL: cmpxchg_zext_i16_i32:
992; CHECK-NEXT: .param i32, i32, i32{{$}}
993; CHECK: i32.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
994; CHECK-NEXT: return $pop0{{$}}
995define i32 @cmpxchg_zext_i16_i32(i16* %p, i32 %exp, i32 %new) {
996 %exp_t = trunc i32 %exp to i16
997 %new_t = trunc i32 %new to i16
998 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
999 %old = extractvalue { i16, i1 } %pair, 0
1000 %e = zext i16 %old to i32
1001 ret i32 %e
1002}
1003
1004; CHECK-LABEL: cmpxchg_zext_i8_i64:
1005; CHECK-NEXT: .param i32, i64, i64{{$}}
1006; CHECK: i64.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1007; CHECK-NEXT: return $pop0{{$}}
1008define i64 @cmpxchg_zext_i8_i64(i8* %p, i64 %exp, i64 %new) {
1009 %exp_t = trunc i64 %exp to i8
1010 %new_t = trunc i64 %new to i8
1011 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
1012 %old = extractvalue { i8, i1 } %pair, 0
1013 %e = zext i8 %old to i64
1014 ret i64 %e
1015}
1016
1017; CHECK-LABEL: cmpxchg_zext_i16_i64:
1018; CHECK-NEXT: .param i32, i64, i64{{$}}
1019; CHECK: i64.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1020; CHECK-NEXT: return $pop0{{$}}
1021define i64 @cmpxchg_zext_i16_i64(i16* %p, i64 %exp, i64 %new) {
1022 %exp_t = trunc i64 %exp to i16
1023 %new_t = trunc i64 %new to i16
1024 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
1025 %old = extractvalue { i16, i1 } %pair, 0
1026 %e = zext i16 %old to i64
1027 ret i64 %e
1028}
1029
1030; CHECK-LABEL: cmpxchg_zext_i32_i64:
1031; CHECK-NEXT: .param i32, i64, i64{{$}}
1032; CHECK: i64.atomic.rmw32_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1033; CHECK-NEXT: return $pop0{{$}}
1034define i64 @cmpxchg_zext_i32_i64(i32* %p, i64 %exp, i64 %new) {
1035 %exp_t = trunc i64 %exp to i32
1036 %new_t = trunc i64 %new to i32
1037 %pair = cmpxchg i32* %p, i32 %exp_t, i32 %new_t seq_cst seq_cst
1038 %old = extractvalue { i32, i1 } %pair, 0
1039 %e = zext i32 %old to i64
1040 ret i64 %e
1041}