blob: 27b3be09943df6822e7a5fbb7bcd02a2ae6bed06 [file] [log] [blame]
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +00001; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers
2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000014; CHECK-NEXT: .functype add_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000015; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000023; CHECK-NEXT: .functype sub_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000024; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000032; CHECK-NEXT: .functype and_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000033; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000041; CHECK-NEXT: .functype or_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000042; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000050; CHECK-NEXT: .functype xor_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000051; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000059; CHECK-NEXT: .functype xchg_i32 (i32, i32) -> (i32){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +000060; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000068; CHECK-NEXT: .functype cmpxchg_i32_loaded_value (i32, i32, i32) -> (i32){{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +000069; 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:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +000078; CHECK-NEXT: .functype cmpxchg_i32_success (i32, i32, i32) -> (i32){{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +000079; 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 Ahne8653bb2018-08-07 00:22:22 +000088; Unsupported instructions are expanded using cmpxchg with a loop.
89
90; CHECK-LABEL: nand_i32:
91; CHECK: loop
92; CHECK: i32.atomic.rmw.cmpxchg
93; CHECK: br_if 0
94; CHECK: end_loop
95define i32 @nand_i32(i32* %p, i32 %v) {
96 %old = atomicrmw nand i32* %p, i32 %v seq_cst
97 ret i32 %old
98}
99
100; CHECK-LABEL: max_i32:
101; CHECK: loop
102; CHECK: i32.atomic.rmw.cmpxchg
103; CHECK: br_if 0
104; CHECK: end_loop
105define i32 @max_i32(i32* %p, i32 %v) {
106 %old = atomicrmw max i32* %p, i32 %v seq_cst
107 ret i32 %old
108}
109
110; CHECK-LABEL: min_i32:
111; CHECK: loop
112; CHECK: i32.atomic.rmw.cmpxchg
113; CHECK: br_if 0
114; CHECK: end_loop
115define i32 @min_i32(i32* %p, i32 %v) {
116 %old = atomicrmw min i32* %p, i32 %v seq_cst
117 ret i32 %old
118}
119
120; CHECK-LABEL: umax_i32:
121; CHECK: loop
122; CHECK: i32.atomic.rmw.cmpxchg
123; CHECK: br_if 0
124; CHECK: end_loop
125define i32 @umax_i32(i32* %p, i32 %v) {
126 %old = atomicrmw umax i32* %p, i32 %v seq_cst
127 ret i32 %old
128}
129
130; CHECK-LABEL: umin_i32:
131; CHECK: loop
132; CHECK: i32.atomic.rmw.cmpxchg
133; CHECK: br_if 0
134; CHECK: end_loop
135define i32 @umin_i32(i32* %p, i32 %v) {
136 %old = atomicrmw umin i32* %p, i32 %v seq_cst
137 ret i32 %old
138}
139
Heejin Ahnfed73822018-07-09 22:30:51 +0000140;===----------------------------------------------------------------------------
141; Atomic read-modify-writes: 64-bit
142;===----------------------------------------------------------------------------
143
144; CHECK-LABEL: add_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000145; CHECK-NEXT: .functype add_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000146; CHECK: i64.atomic.rmw.add $push0=, 0($0), $1{{$}}
147; CHECK-NEXT: return $pop0{{$}}
148define i64 @add_i64(i64* %p, i64 %v) {
149 %old = atomicrmw add i64* %p, i64 %v seq_cst
150 ret i64 %old
151}
152
153; CHECK-LABEL: sub_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000154; CHECK-NEXT: .functype sub_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000155; CHECK: i64.atomic.rmw.sub $push0=, 0($0), $1{{$}}
156; CHECK-NEXT: return $pop0{{$}}
157define i64 @sub_i64(i64* %p, i64 %v) {
158 %old = atomicrmw sub i64* %p, i64 %v seq_cst
159 ret i64 %old
160}
161
162; CHECK-LABEL: and_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000163; CHECK-NEXT: .functype and_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000164; CHECK: i64.atomic.rmw.and $push0=, 0($0), $1{{$}}
165; CHECK-NEXT: return $pop0{{$}}
166define i64 @and_i64(i64* %p, i64 %v) {
167 %old = atomicrmw and i64* %p, i64 %v seq_cst
168 ret i64 %old
169}
170
171; CHECK-LABEL: or_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000172; CHECK-NEXT: .functype or_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000173; CHECK: i64.atomic.rmw.or $push0=, 0($0), $1{{$}}
174; CHECK-NEXT: return $pop0{{$}}
175define i64 @or_i64(i64* %p, i64 %v) {
176 %old = atomicrmw or i64* %p, i64 %v seq_cst
177 ret i64 %old
178}
179
180; CHECK-LABEL: xor_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000181; CHECK-NEXT: .functype xor_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000182; CHECK: i64.atomic.rmw.xor $push0=, 0($0), $1{{$}}
183; CHECK-NEXT: return $pop0{{$}}
184define i64 @xor_i64(i64* %p, i64 %v) {
185 %old = atomicrmw xor i64* %p, i64 %v seq_cst
186 ret i64 %old
187}
188
189; CHECK-LABEL: xchg_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000190; CHECK-NEXT: .functype xchg_i64 (i32, i64) -> (i64){{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000191; CHECK: i64.atomic.rmw.xchg $push0=, 0($0), $1{{$}}
192; CHECK-NEXT: return $pop0{{$}}
193define i64 @xchg_i64(i64* %p, i64 %v) {
194 %old = atomicrmw xchg i64* %p, i64 %v seq_cst
195 ret i64 %old
196}
197
Heejin Ahnb3724b72018-08-01 19:40:28 +0000198; CHECK-LABEL: cmpxchg_i64_loaded_value:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000199; CHECK-NEXT: .functype cmpxchg_i64_loaded_value (i32, i64, i64) -> (i64){{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000200; CHECK: i64.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
201; CHECK-NEXT: return $pop0{{$}}
202define i64 @cmpxchg_i64_loaded_value(i64* %p, i64 %exp, i64 %new) {
203 %pair = cmpxchg i64* %p, i64 %exp, i64 %new seq_cst seq_cst
204 %old = extractvalue { i64, i1 } %pair, 0
205 ret i64 %old
206}
207
208; CHECK-LABEL: cmpxchg_i64_success:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000209; CHECK-NEXT: .functype cmpxchg_i64_success (i32, i64, i64) -> (i32){{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000210; CHECK: i64.atomic.rmw.cmpxchg $push0=, 0($0), $1, $2{{$}}
211; CHECK-NEXT: i64.eq $push1=, $pop0, $1{{$}}
212; CHECK-NEXT: return $pop1{{$}}
213define i1 @cmpxchg_i64_success(i64* %p, i64 %exp, i64 %new) {
214 %pair = cmpxchg i64* %p, i64 %exp, i64 %new seq_cst seq_cst
215 %succ = extractvalue { i64, i1 } %pair, 1
216 ret i1 %succ
217}
218
Heejin Ahne8653bb2018-08-07 00:22:22 +0000219; Unsupported instructions are expanded using cmpxchg with a loop.
220
221; CHECK-LABEL: nand_i64:
222; CHECK: loop
223; CHECK: i64.atomic.rmw.cmpxchg
224; CHECK: br_if 0
225; CHECK: end_loop
226define i64 @nand_i64(i64* %p, i64 %v) {
227 %old = atomicrmw nand i64* %p, i64 %v seq_cst
228 ret i64 %old
229}
230
231; CHECK-LABEL: max_i64:
232; CHECK: loop
233; CHECK: i64.atomic.rmw.cmpxchg
234; CHECK: br_if 0
235; CHECK: end_loop
236define i64 @max_i64(i64* %p, i64 %v) {
237 %old = atomicrmw max i64* %p, i64 %v seq_cst
238 ret i64 %old
239}
240
241; CHECK-LABEL: min_i64:
242; CHECK: loop
243; CHECK: i64.atomic.rmw.cmpxchg
244; CHECK: br_if 0
245; CHECK: end_loop
246define i64 @min_i64(i64* %p, i64 %v) {
247 %old = atomicrmw min i64* %p, i64 %v seq_cst
248 ret i64 %old
249}
250
251; CHECK-LABEL: umax_i64:
252; CHECK: loop
253; CHECK: i64.atomic.rmw.cmpxchg
254; CHECK: br_if 0
255; CHECK: end_loop
256define i64 @umax_i64(i64* %p, i64 %v) {
257 %old = atomicrmw umax i64* %p, i64 %v seq_cst
258 ret i64 %old
259}
260
261; CHECK-LABEL: umin_i64:
262; CHECK: loop
263; CHECK: i64.atomic.rmw.cmpxchg
264; CHECK: br_if 0
265; CHECK: end_loop
266define i64 @umin_i64(i64* %p, i64 %v) {
267 %old = atomicrmw umin i64* %p, i64 %v seq_cst
268 ret i64 %old
269}
270
Heejin Ahnfed73822018-07-09 22:30:51 +0000271;===----------------------------------------------------------------------------
272; Atomic truncating & sign-extending RMWs
273;===----------------------------------------------------------------------------
274
275; add
276
277; CHECK-LABEL: add_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000278; CHECK-NEXT: .functype add_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000279; CHECK: i32.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000280; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
281; CHECK-NEXT: return $pop1{{$}}
282define i32 @add_sext_i8_i32(i8* %p, i32 %v) {
283 %t = trunc i32 %v to i8
284 %old = atomicrmw add i8* %p, i8 %t seq_cst
285 %e = sext i8 %old to i32
286 ret i32 %e
287}
288
289; CHECK-LABEL: add_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000290; CHECK-NEXT: .functype add_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000291; CHECK: i32.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000292; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
293; CHECK-NEXT: return $pop1{{$}}
294define i32 @add_sext_i16_i32(i16* %p, i32 %v) {
295 %t = trunc i32 %v to i16
296 %old = atomicrmw add i16* %p, i16 %t seq_cst
297 %e = sext i16 %old to i32
298 ret i32 %e
299}
300
301; CHECK-LABEL: add_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000302; CHECK-NEXT: .functype add_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000303; CHECK: i64.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000304; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
305; CHECK-NEXT: return $pop1{{$}}
306define i64 @add_sext_i8_i64(i8* %p, i64 %v) {
307 %t = trunc i64 %v to i8
308 %old = atomicrmw add i8* %p, i8 %t seq_cst
309 %e = sext i8 %old to i64
310 ret i64 %e
311}
312
313; CHECK-LABEL: add_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000314; CHECK-NEXT: .functype add_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000315; CHECK: i64.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000316; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
317; CHECK-NEXT: return $pop1{{$}}
318define i64 @add_sext_i16_i64(i16* %p, i64 %v) {
319 %t = trunc i64 %v to i16
320 %old = atomicrmw add i16* %p, i16 %t seq_cst
321 %e = sext i16 %old to i64
322 ret i64 %e
323}
324
Thomas Lively6a87dda2019-01-08 06:25:55 +0000325; 32->64 sext rmw gets selected as i32.atomic.rmw.add, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000326; CHECK-LABEL: add_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000327; CHECK-NEXT: .functype add_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000328; CHECK: i32.wrap_i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000329; CHECK: i32.atomic.rmw.add $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000330; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000331; CHECK-NEXT: return $pop2{{$}}
332define i64 @add_sext_i32_i64(i32* %p, i64 %v) {
333 %t = trunc i64 %v to i32
334 %old = atomicrmw add i32* %p, i32 %t seq_cst
335 %e = sext i32 %old to i64
336 ret i64 %e
337}
338
339; sub
340
341; CHECK-LABEL: sub_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000342; CHECK-NEXT: .functype sub_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000343; CHECK: i32.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000344; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
345; CHECK-NEXT: return $pop1{{$}}
346define i32 @sub_sext_i8_i32(i8* %p, i32 %v) {
347 %t = trunc i32 %v to i8
348 %old = atomicrmw sub i8* %p, i8 %t seq_cst
349 %e = sext i8 %old to i32
350 ret i32 %e
351}
352
353; CHECK-LABEL: sub_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000354; CHECK-NEXT: .functype sub_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000355; CHECK: i32.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000356; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
357; CHECK-NEXT: return $pop1{{$}}
358define i32 @sub_sext_i16_i32(i16* %p, i32 %v) {
359 %t = trunc i32 %v to i16
360 %old = atomicrmw sub i16* %p, i16 %t seq_cst
361 %e = sext i16 %old to i32
362 ret i32 %e
363}
364
365; CHECK-LABEL: sub_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000366; CHECK-NEXT: .functype sub_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000367; CHECK: i64.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000368; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
369; CHECK-NEXT: return $pop1{{$}}
370define i64 @sub_sext_i8_i64(i8* %p, i64 %v) {
371 %t = trunc i64 %v to i8
372 %old = atomicrmw sub i8* %p, i8 %t seq_cst
373 %e = sext i8 %old to i64
374 ret i64 %e
375}
376
377; CHECK-LABEL: sub_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000378; CHECK-NEXT: .functype sub_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000379; CHECK: i64.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000380; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
381; CHECK-NEXT: return $pop1{{$}}
382define i64 @sub_sext_i16_i64(i16* %p, i64 %v) {
383 %t = trunc i64 %v to i16
384 %old = atomicrmw sub i16* %p, i16 %t seq_cst
385 %e = sext i16 %old to i64
386 ret i64 %e
387}
388
Thomas Lively6a87dda2019-01-08 06:25:55 +0000389; 32->64 sext rmw gets selected as i32.atomic.rmw.sub, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000390; CHECK-LABEL: sub_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000391; CHECK-NEXT: .functype sub_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000392; CHECK: i32.wrap_i64 $push0=, $1
Heejin Ahnfed73822018-07-09 22:30:51 +0000393; CHECK: i32.atomic.rmw.sub $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000394; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000395; CHECK-NEXT: return $pop2{{$}}
396define i64 @sub_sext_i32_i64(i32* %p, i64 %v) {
397 %t = trunc i64 %v to i32
398 %old = atomicrmw sub i32* %p, i32 %t seq_cst
399 %e = sext i32 %old to i64
400 ret i64 %e
401}
402
403; and
404
405; CHECK-LABEL: and_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000406; CHECK-NEXT: .functype and_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000407; CHECK: i32.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000408; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
409; CHECK-NEXT: return $pop1{{$}}
410define i32 @and_sext_i8_i32(i8* %p, i32 %v) {
411 %t = trunc i32 %v to i8
412 %old = atomicrmw and i8* %p, i8 %t seq_cst
413 %e = sext i8 %old to i32
414 ret i32 %e
415}
416
417; CHECK-LABEL: and_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000418; CHECK-NEXT: .functype and_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000419; CHECK: i32.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000420; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
421; CHECK-NEXT: return $pop1{{$}}
422define i32 @and_sext_i16_i32(i16* %p, i32 %v) {
423 %t = trunc i32 %v to i16
424 %old = atomicrmw and i16* %p, i16 %t seq_cst
425 %e = sext i16 %old to i32
426 ret i32 %e
427}
428
429; CHECK-LABEL: and_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000430; CHECK-NEXT: .functype and_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000431; CHECK: i64.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000432; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
433; CHECK-NEXT: return $pop1{{$}}
434define i64 @and_sext_i8_i64(i8* %p, i64 %v) {
435 %t = trunc i64 %v to i8
436 %old = atomicrmw and i8* %p, i8 %t seq_cst
437 %e = sext i8 %old to i64
438 ret i64 %e
439}
440
441; CHECK-LABEL: and_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000442; CHECK-NEXT: .functype and_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000443; CHECK: i64.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000444; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
445; CHECK-NEXT: return $pop1{{$}}
446define i64 @and_sext_i16_i64(i16* %p, i64 %v) {
447 %t = trunc i64 %v to i16
448 %old = atomicrmw and i16* %p, i16 %t seq_cst
449 %e = sext i16 %old to i64
450 ret i64 %e
451}
452
Thomas Lively6a87dda2019-01-08 06:25:55 +0000453; 32->64 sext rmw gets selected as i32.atomic.rmw.and, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000454; CHECK-LABEL: and_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000455; CHECK-NEXT: .functype and_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000456; CHECK: i32.wrap_i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000457; CHECK: i32.atomic.rmw.and $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000458; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000459; CHECK-NEXT: return $pop2{{$}}
460define i64 @and_sext_i32_i64(i32* %p, i64 %v) {
461 %t = trunc i64 %v to i32
462 %old = atomicrmw and i32* %p, i32 %t seq_cst
463 %e = sext i32 %old to i64
464 ret i64 %e
465}
466
467; or
468
469; CHECK-LABEL: or_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000470; CHECK-NEXT: .functype or_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000471; CHECK: i32.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000472; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
473; CHECK-NEXT: return $pop1{{$}}
474define i32 @or_sext_i8_i32(i8* %p, i32 %v) {
475 %t = trunc i32 %v to i8
476 %old = atomicrmw or i8* %p, i8 %t seq_cst
477 %e = sext i8 %old to i32
478 ret i32 %e
479}
480
481; CHECK-LABEL: or_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000482; CHECK-NEXT: .functype or_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000483; CHECK: i32.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000484; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
485; CHECK-NEXT: return $pop1{{$}}
486define i32 @or_sext_i16_i32(i16* %p, i32 %v) {
487 %t = trunc i32 %v to i16
488 %old = atomicrmw or i16* %p, i16 %t seq_cst
489 %e = sext i16 %old to i32
490 ret i32 %e
491}
492
493; CHECK-LABEL: or_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000494; CHECK-NEXT: .functype or_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000495; CHECK: i64.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000496; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
497; CHECK-NEXT: return $pop1{{$}}
498define i64 @or_sext_i8_i64(i8* %p, i64 %v) {
499 %t = trunc i64 %v to i8
500 %old = atomicrmw or i8* %p, i8 %t seq_cst
501 %e = sext i8 %old to i64
502 ret i64 %e
503}
504
505; CHECK-LABEL: or_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000506; CHECK-NEXT: .functype or_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000507; CHECK: i64.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000508; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
509; CHECK-NEXT: return $pop1{{$}}
510define i64 @or_sext_i16_i64(i16* %p, i64 %v) {
511 %t = trunc i64 %v to i16
512 %old = atomicrmw or i16* %p, i16 %t seq_cst
513 %e = sext i16 %old to i64
514 ret i64 %e
515}
516
Thomas Lively6a87dda2019-01-08 06:25:55 +0000517; 32->64 sext rmw gets selected as i32.atomic.rmw.or, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000518; CHECK-LABEL: or_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000519; CHECK-NEXT: .functype or_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000520; CHECK: i32.wrap_i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000521; CHECK: i32.atomic.rmw.or $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000522; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000523; CHECK-NEXT: return $pop2{{$}}
524define i64 @or_sext_i32_i64(i32* %p, i64 %v) {
525 %t = trunc i64 %v to i32
526 %old = atomicrmw or i32* %p, i32 %t seq_cst
527 %e = sext i32 %old to i64
528 ret i64 %e
529}
530
531; xor
532
533; CHECK-LABEL: xor_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000534; CHECK-NEXT: .functype xor_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000535; CHECK: i32.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000536; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
537; CHECK-NEXT: return $pop1{{$}}
538define i32 @xor_sext_i8_i32(i8* %p, i32 %v) {
539 %t = trunc i32 %v to i8
540 %old = atomicrmw xor i8* %p, i8 %t seq_cst
541 %e = sext i8 %old to i32
542 ret i32 %e
543}
544
545; CHECK-LABEL: xor_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000546; CHECK-NEXT: .functype xor_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000547; CHECK: i32.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000548; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
549; CHECK-NEXT: return $pop1{{$}}
550define i32 @xor_sext_i16_i32(i16* %p, i32 %v) {
551 %t = trunc i32 %v to i16
552 %old = atomicrmw xor i16* %p, i16 %t seq_cst
553 %e = sext i16 %old to i32
554 ret i32 %e
555}
556
557; CHECK-LABEL: xor_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000558; CHECK-NEXT: .functype xor_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000559; CHECK: i64.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000560; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
561; CHECK-NEXT: return $pop1{{$}}
562define i64 @xor_sext_i8_i64(i8* %p, i64 %v) {
563 %t = trunc i64 %v to i8
564 %old = atomicrmw xor i8* %p, i8 %t seq_cst
565 %e = sext i8 %old to i64
566 ret i64 %e
567}
568
569; CHECK-LABEL: xor_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000570; CHECK-NEXT: .functype xor_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000571; CHECK: i64.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000572; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
573; CHECK-NEXT: return $pop1{{$}}
574define i64 @xor_sext_i16_i64(i16* %p, i64 %v) {
575 %t = trunc i64 %v to i16
576 %old = atomicrmw xor i16* %p, i16 %t seq_cst
577 %e = sext i16 %old to i64
578 ret i64 %e
579}
580
Thomas Lively6a87dda2019-01-08 06:25:55 +0000581; 32->64 sext rmw gets selected as i32.atomic.rmw.xor, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000582; CHECK-LABEL: xor_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000583; CHECK-NEXT: .functype xor_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000584; CHECK: i32.wrap_i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000585; CHECK: i32.atomic.rmw.xor $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000586; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000587; CHECK-NEXT: return $pop2{{$}}
588define i64 @xor_sext_i32_i64(i32* %p, i64 %v) {
589 %t = trunc i64 %v to i32
590 %old = atomicrmw xor i32* %p, i32 %t seq_cst
591 %e = sext i32 %old to i64
592 ret i64 %e
593}
594
595; xchg
596
597; CHECK-LABEL: xchg_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000598; CHECK-NEXT: .functype xchg_sext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000599; CHECK: i32.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000600; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
601; CHECK-NEXT: return $pop1{{$}}
602define i32 @xchg_sext_i8_i32(i8* %p, i32 %v) {
603 %t = trunc i32 %v to i8
604 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
605 %e = sext i8 %old to i32
606 ret i32 %e
607}
608
609; CHECK-LABEL: xchg_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000610; CHECK-NEXT: .functype xchg_sext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000611; CHECK: i32.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000612; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
613; CHECK-NEXT: return $pop1{{$}}
614define i32 @xchg_sext_i16_i32(i16* %p, i32 %v) {
615 %t = trunc i32 %v to i16
616 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
617 %e = sext i16 %old to i32
618 ret i32 %e
619}
620
621; CHECK-LABEL: xchg_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000622; CHECK-NEXT: .functype xchg_sext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000623; CHECK: i64.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000624; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
625; CHECK-NEXT: return $pop1{{$}}
626define i64 @xchg_sext_i8_i64(i8* %p, i64 %v) {
627 %t = trunc i64 %v to i8
628 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
629 %e = sext i8 %old to i64
630 ret i64 %e
631}
632
633; CHECK-LABEL: xchg_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000634; CHECK-NEXT: .functype xchg_sext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000635; CHECK: i64.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000636; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
637; CHECK-NEXT: return $pop1{{$}}
638define i64 @xchg_sext_i16_i64(i16* %p, i64 %v) {
639 %t = trunc i64 %v to i16
640 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
641 %e = sext i16 %old to i64
642 ret i64 %e
643}
644
Thomas Lively6a87dda2019-01-08 06:25:55 +0000645; 32->64 sext rmw gets selected as i32.atomic.rmw.xchg, i64.extend_i32_s
Heejin Ahnfed73822018-07-09 22:30:51 +0000646; CHECK-LABEL: xchg_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000647; CHECK-NEXT: .functype xchg_sext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000648; CHECK: i32.wrap_i64 $push0=, $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000649; CHECK: i32.atomic.rmw.xchg $push1=, 0($0), $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000650; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000651; CHECK-NEXT: return $pop2{{$}}
652define i64 @xchg_sext_i32_i64(i32* %p, i64 %v) {
653 %t = trunc i64 %v to i32
654 %old = atomicrmw xchg i32* %p, i32 %t seq_cst
655 %e = sext i32 %old to i64
656 ret i64 %e
657}
658
Heejin Ahnb3724b72018-08-01 19:40:28 +0000659; cmpxchg
660
661; CHECK-LABEL: cmpxchg_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000662; CHECK-NEXT: .functype cmpxchg_sext_i8_i32 (i32, i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000663; CHECK: i32.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000664; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
665; CHECK-NEXT: return $pop1{{$}}
666define i32 @cmpxchg_sext_i8_i32(i8* %p, i32 %exp, i32 %new) {
667 %exp_t = trunc i32 %exp to i8
668 %new_t = trunc i32 %new to i8
669 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
670 %old = extractvalue { i8, i1 } %pair, 0
671 %e = sext i8 %old to i32
672 ret i32 %e
673}
674
675; CHECK-LABEL: cmpxchg_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000676; CHECK-NEXT: .functype cmpxchg_sext_i16_i32 (i32, i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000677; CHECK: i32.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000678; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
679; CHECK-NEXT: return $pop1{{$}}
680define i32 @cmpxchg_sext_i16_i32(i16* %p, i32 %exp, i32 %new) {
681 %exp_t = trunc i32 %exp to i16
682 %new_t = trunc i32 %new to i16
683 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
684 %old = extractvalue { i16, i1 } %pair, 0
685 %e = sext i16 %old to i32
686 ret i32 %e
687}
688
689; CHECK-LABEL: cmpxchg_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000690; CHECK-NEXT: .functype cmpxchg_sext_i8_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000691; CHECK: i64.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000692; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
693; CHECK-NEXT: return $pop1{{$}}
694define i64 @cmpxchg_sext_i8_i64(i8* %p, i64 %exp, i64 %new) {
695 %exp_t = trunc i64 %exp to i8
696 %new_t = trunc i64 %new to i8
697 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
698 %old = extractvalue { i8, i1 } %pair, 0
699 %e = sext i8 %old to i64
700 ret i64 %e
701}
702
703; CHECK-LABEL: cmpxchg_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000704; CHECK-NEXT: .functype cmpxchg_sext_i16_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000705; CHECK: i64.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000706; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
707; CHECK-NEXT: return $pop1{{$}}
708define i64 @cmpxchg_sext_i16_i64(i16* %p, i64 %exp, i64 %new) {
709 %exp_t = trunc i64 %exp to i16
710 %new_t = trunc i64 %new to i16
711 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
712 %old = extractvalue { i16, i1 } %pair, 0
713 %e = sext i16 %old to i64
714 ret i64 %e
715}
716
Thomas Lively6a87dda2019-01-08 06:25:55 +0000717; 32->64 sext rmw gets selected as i32.atomic.rmw.cmpxchg, i64.extend_i32_s
Heejin Ahnb3724b72018-08-01 19:40:28 +0000718; CHECK-LABEL: cmpxchg_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000719; CHECK-NEXT: .functype cmpxchg_sext_i32_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000720; CHECK: i32.wrap_i64 $push1=, $1{{$}}
721; CHECK-NEXT: i32.wrap_i64 $push0=, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000722; CHECK-NEXT: i32.atomic.rmw.cmpxchg $push2=, 0($0), $pop1, $pop0{{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000723; CHECK-NEXT: i64.extend_i32_s $push3=, $pop2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +0000724; CHECK-NEXT: return $pop3{{$}}
725define i64 @cmpxchg_sext_i32_i64(i32* %p, i64 %exp, i64 %new) {
726 %exp_t = trunc i64 %exp to i32
727 %new_t = trunc i64 %new to i32
728 %pair = cmpxchg i32* %p, i32 %exp_t, i32 %new_t seq_cst seq_cst
729 %old = extractvalue { i32, i1 } %pair, 0
730 %e = sext i32 %old to i64
731 ret i64 %e
732}
733
Heejin Ahne8653bb2018-08-07 00:22:22 +0000734; Unsupported instructions are expanded using cmpxchg with a loop.
735; Here we take a nand as an example.
736
737; nand
738
739; CHECK-LABEL: nand_sext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000740; CHECK-NEXT: .functype nand_sext_i8_i32 (i32, i32) -> (i32){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +0000741; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +0000742; CHECK: i32.atomic.rmw8.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000743; CHECK: i32.extend8_s
744define i32 @nand_sext_i8_i32(i8* %p, i32 %v) {
745 %t = trunc i32 %v to i8
746 %old = atomicrmw nand i8* %p, i8 %t seq_cst
747 %e = sext i8 %old to i32
748 ret i32 %e
749}
750
751; CHECK-LABEL: nand_sext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000752; CHECK-NEXT: .functype nand_sext_i16_i32 (i32, i32) -> (i32){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +0000753; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +0000754; CHECK: i32.atomic.rmw16.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000755; CHECK: i32.extend16_s
756define i32 @nand_sext_i16_i32(i16* %p, i32 %v) {
757 %t = trunc i32 %v to i16
758 %old = atomicrmw nand i16* %p, i16 %t seq_cst
759 %e = sext i16 %old to i32
760 ret i32 %e
761}
762
Thomas Lively6a87dda2019-01-08 06:25:55 +0000763; FIXME Currently this cannot make use of i64.atomic.rmw8.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000764; CHECK-LABEL: nand_sext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000765; CHECK-NEXT: .functype nand_sext_i8_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +0000766; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +0000767; CHECK: i32.atomic.rmw8.cmpxchg_u
768; CHECK: i64.extend_i32_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000769; CHECK: i64.extend8_s
770define i64 @nand_sext_i8_i64(i8* %p, i64 %v) {
771 %t = trunc i64 %v to i8
772 %old = atomicrmw nand i8* %p, i8 %t seq_cst
773 %e = sext i8 %old to i64
774 ret i64 %e
775}
776
Thomas Lively6a87dda2019-01-08 06:25:55 +0000777; FIXME Currently this cannot make use of i64.atomic.rmw16.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000778; CHECK-LABEL: nand_sext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000779; CHECK-NEXT: .functype nand_sext_i16_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +0000780; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +0000781; CHECK: i32.atomic.rmw16.cmpxchg_u
782; CHECK: i64.extend_i32_u
Heejin Ahne8653bb2018-08-07 00:22:22 +0000783; CHECK: i64.extend16_s
784define i64 @nand_sext_i16_i64(i16* %p, i64 %v) {
785 %t = trunc i64 %v to i16
786 %old = atomicrmw nand i16* %p, i16 %t seq_cst
787 %e = sext i16 %old to i64
788 ret i64 %e
789}
790
Thomas Lively6a87dda2019-01-08 06:25:55 +0000791; 32->64 sext rmw gets selected as i32.atomic.rmw.nand, i64.extend_i32_s
Heejin Ahne8653bb2018-08-07 00:22:22 +0000792; CHECK-LABEL: nand_sext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000793; CHECK-NEXT: .functype nand_sext_i32_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +0000794; CHECK: loop
795; CHECK: i32.atomic.rmw.cmpxchg
Thomas Lively6a87dda2019-01-08 06:25:55 +0000796; CHECK: i64.extend_i32_s
Heejin Ahne8653bb2018-08-07 00:22:22 +0000797define i64 @nand_sext_i32_i64(i32* %p, i64 %v) {
798 %t = trunc i64 %v to i32
799 %old = atomicrmw nand i32* %p, i32 %t seq_cst
800 %e = sext i32 %old to i64
801 ret i64 %e
802}
803
Heejin Ahnfed73822018-07-09 22:30:51 +0000804;===----------------------------------------------------------------------------
805; Atomic truncating & zero-extending RMWs
806;===----------------------------------------------------------------------------
807
808; add
809
810; CHECK-LABEL: add_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000811; CHECK-NEXT: .functype add_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000812; CHECK: i32.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000813; CHECK-NEXT: return $pop0{{$}}
814define i32 @add_zext_i8_i32(i8* %p, i32 %v) {
815 %t = trunc i32 %v to i8
816 %old = atomicrmw add i8* %p, i8 %t seq_cst
817 %e = zext i8 %old to i32
818 ret i32 %e
819}
820
821; CHECK-LABEL: add_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000822; CHECK-NEXT: .functype add_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000823; CHECK: i32.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000824; CHECK-NEXT: return $pop0{{$}}
825define i32 @add_zext_i16_i32(i16* %p, i32 %v) {
826 %t = trunc i32 %v to i16
827 %old = atomicrmw add i16* %p, i16 %t seq_cst
828 %e = zext i16 %old to i32
829 ret i32 %e
830}
831
832; CHECK-LABEL: add_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000833; CHECK-NEXT: .functype add_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000834; CHECK: i64.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000835; CHECK-NEXT: return $pop0{{$}}
836define i64 @add_zext_i8_i64(i8* %p, i64 %v) {
837 %t = trunc i64 %v to i8
838 %old = atomicrmw add i8* %p, i8 %t seq_cst
839 %e = zext i8 %old to i64
840 ret i64 %e
841}
842
843; CHECK-LABEL: add_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000844; CHECK-NEXT: .functype add_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000845; CHECK: i64.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000846; CHECK-NEXT: return $pop0{{$}}
847define i64 @add_zext_i16_i64(i16* %p, i64 %v) {
848 %t = trunc i64 %v to i16
849 %old = atomicrmw add i16* %p, i16 %t seq_cst
850 %e = zext i16 %old to i64
851 ret i64 %e
852}
853
854; CHECK-LABEL: add_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000855; CHECK-NEXT: .functype add_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000856; CHECK: i64.atomic.rmw32.add_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000857; CHECK-NEXT: return $pop0{{$}}
858define i64 @add_zext_i32_i64(i32* %p, i64 %v) {
859 %t = trunc i64 %v to i32
860 %old = atomicrmw add i32* %p, i32 %t seq_cst
861 %e = zext i32 %old to i64
862 ret i64 %e
863}
864
865; sub
866
867; CHECK-LABEL: sub_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000868; CHECK-NEXT: .functype sub_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000869; CHECK: i32.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000870; CHECK-NEXT: return $pop0{{$}}
871define i32 @sub_zext_i8_i32(i8* %p, i32 %v) {
872 %t = trunc i32 %v to i8
873 %old = atomicrmw sub i8* %p, i8 %t seq_cst
874 %e = zext i8 %old to i32
875 ret i32 %e
876}
877
878; CHECK-LABEL: sub_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000879; CHECK-NEXT: .functype sub_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000880; CHECK: i32.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000881; CHECK-NEXT: return $pop0{{$}}
882define i32 @sub_zext_i16_i32(i16* %p, i32 %v) {
883 %t = trunc i32 %v to i16
884 %old = atomicrmw sub i16* %p, i16 %t seq_cst
885 %e = zext i16 %old to i32
886 ret i32 %e
887}
888
889; CHECK-LABEL: sub_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000890; CHECK-NEXT: .functype sub_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000891; CHECK: i64.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000892; CHECK-NEXT: return $pop0{{$}}
893define i64 @sub_zext_i8_i64(i8* %p, i64 %v) {
894 %t = trunc i64 %v to i8
895 %old = atomicrmw sub i8* %p, i8 %t seq_cst
896 %e = zext i8 %old to i64
897 ret i64 %e
898}
899
900; CHECK-LABEL: sub_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000901; CHECK-NEXT: .functype sub_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000902; CHECK: i64.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000903; CHECK-NEXT: return $pop0{{$}}
904define i64 @sub_zext_i16_i64(i16* %p, i64 %v) {
905 %t = trunc i64 %v to i16
906 %old = atomicrmw sub i16* %p, i16 %t seq_cst
907 %e = zext i16 %old to i64
908 ret i64 %e
909}
910
911; CHECK-LABEL: sub_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000912; CHECK-NEXT: .functype sub_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000913; CHECK: i64.atomic.rmw32.sub_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000914; CHECK-NEXT: return $pop0{{$}}
915define i64 @sub_zext_i32_i64(i32* %p, i64 %v) {
916 %t = trunc i64 %v to i32
917 %old = atomicrmw sub i32* %p, i32 %t seq_cst
918 %e = zext i32 %old to i64
919 ret i64 %e
920}
921
922; and
923
924; CHECK-LABEL: and_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000925; CHECK-NEXT: .functype and_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000926; CHECK: i32.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000927; CHECK-NEXT: return $pop0{{$}}
928define i32 @and_zext_i8_i32(i8* %p, i32 %v) {
929 %t = trunc i32 %v to i8
930 %old = atomicrmw and i8* %p, i8 %t seq_cst
931 %e = zext i8 %old to i32
932 ret i32 %e
933}
934
935; CHECK-LABEL: and_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000936; CHECK-NEXT: .functype and_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000937; CHECK: i32.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000938; CHECK-NEXT: return $pop0{{$}}
939define i32 @and_zext_i16_i32(i16* %p, i32 %v) {
940 %t = trunc i32 %v to i16
941 %old = atomicrmw and i16* %p, i16 %t seq_cst
942 %e = zext i16 %old to i32
943 ret i32 %e
944}
945
946; CHECK-LABEL: and_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000947; CHECK-NEXT: .functype and_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000948; CHECK: i64.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000949; CHECK-NEXT: return $pop0{{$}}
950define i64 @and_zext_i8_i64(i8* %p, i64 %v) {
951 %t = trunc i64 %v to i8
952 %old = atomicrmw and i8* %p, i8 %t seq_cst
953 %e = zext i8 %old to i64
954 ret i64 %e
955}
956
957; CHECK-LABEL: and_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000958; CHECK-NEXT: .functype and_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000959; CHECK: i64.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000960; CHECK-NEXT: return $pop0{{$}}
961define i64 @and_zext_i16_i64(i16* %p, i64 %v) {
962 %t = trunc i64 %v to i16
963 %old = atomicrmw and i16* %p, i16 %t seq_cst
964 %e = zext i16 %old to i64
965 ret i64 %e
966}
967
968; CHECK-LABEL: and_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000969; CHECK-NEXT: .functype and_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000970; CHECK: i64.atomic.rmw32.and_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000971; CHECK-NEXT: return $pop0{{$}}
972define i64 @and_zext_i32_i64(i32* %p, i64 %v) {
973 %t = trunc i64 %v to i32
974 %old = atomicrmw and i32* %p, i32 %t seq_cst
975 %e = zext i32 %old to i64
976 ret i64 %e
977}
978
979; or
980
981; CHECK-LABEL: or_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000982; CHECK-NEXT: .functype or_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000983; CHECK: i32.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000984; CHECK-NEXT: return $pop0{{$}}
985define i32 @or_zext_i8_i32(i8* %p, i32 %v) {
986 %t = trunc i32 %v to i8
987 %old = atomicrmw or i8* %p, i8 %t seq_cst
988 %e = zext i8 %old to i32
989 ret i32 %e
990}
991
992; CHECK-LABEL: or_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +0000993; CHECK-NEXT: .functype or_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +0000994; CHECK: i32.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +0000995; CHECK-NEXT: return $pop0{{$}}
996define i32 @or_zext_i16_i32(i16* %p, i32 %v) {
997 %t = trunc i32 %v to i16
998 %old = atomicrmw or i16* %p, i16 %t seq_cst
999 %e = zext i16 %old to i32
1000 ret i32 %e
1001}
1002
1003; CHECK-LABEL: or_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001004; CHECK-NEXT: .functype or_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001005; CHECK: i64.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001006; CHECK-NEXT: return $pop0{{$}}
1007define i64 @or_zext_i8_i64(i8* %p, i64 %v) {
1008 %t = trunc i64 %v to i8
1009 %old = atomicrmw or i8* %p, i8 %t seq_cst
1010 %e = zext i8 %old to i64
1011 ret i64 %e
1012}
1013
1014; CHECK-LABEL: or_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001015; CHECK-NEXT: .functype or_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001016; CHECK: i64.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001017; CHECK-NEXT: return $pop0{{$}}
1018define i64 @or_zext_i16_i64(i16* %p, i64 %v) {
1019 %t = trunc i64 %v to i16
1020 %old = atomicrmw or i16* %p, i16 %t seq_cst
1021 %e = zext i16 %old to i64
1022 ret i64 %e
1023}
1024
1025; CHECK-LABEL: or_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001026; CHECK-NEXT: .functype or_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001027; CHECK: i64.atomic.rmw32.or_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001028; CHECK-NEXT: return $pop0{{$}}
1029define i64 @or_zext_i32_i64(i32* %p, i64 %v) {
1030 %t = trunc i64 %v to i32
1031 %old = atomicrmw or i32* %p, i32 %t seq_cst
1032 %e = zext i32 %old to i64
1033 ret i64 %e
1034}
1035
1036; xor
1037
1038; CHECK-LABEL: xor_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001039; CHECK-NEXT: .functype xor_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001040; CHECK: i32.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001041; CHECK-NEXT: return $pop0{{$}}
1042define i32 @xor_zext_i8_i32(i8* %p, i32 %v) {
1043 %t = trunc i32 %v to i8
1044 %old = atomicrmw xor i8* %p, i8 %t seq_cst
1045 %e = zext i8 %old to i32
1046 ret i32 %e
1047}
1048
1049; CHECK-LABEL: xor_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001050; CHECK-NEXT: .functype xor_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001051; CHECK: i32.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001052; CHECK-NEXT: return $pop0{{$}}
1053define i32 @xor_zext_i16_i32(i16* %p, i32 %v) {
1054 %t = trunc i32 %v to i16
1055 %old = atomicrmw xor i16* %p, i16 %t seq_cst
1056 %e = zext i16 %old to i32
1057 ret i32 %e
1058}
1059
1060; CHECK-LABEL: xor_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001061; CHECK-NEXT: .functype xor_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001062; CHECK: i64.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001063; CHECK-NEXT: return $pop0{{$}}
1064define i64 @xor_zext_i8_i64(i8* %p, i64 %v) {
1065 %t = trunc i64 %v to i8
1066 %old = atomicrmw xor i8* %p, i8 %t seq_cst
1067 %e = zext i8 %old to i64
1068 ret i64 %e
1069}
1070
1071; CHECK-LABEL: xor_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001072; CHECK-NEXT: .functype xor_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001073; CHECK: i64.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001074; CHECK-NEXT: return $pop0{{$}}
1075define i64 @xor_zext_i16_i64(i16* %p, i64 %v) {
1076 %t = trunc i64 %v to i16
1077 %old = atomicrmw xor i16* %p, i16 %t seq_cst
1078 %e = zext i16 %old to i64
1079 ret i64 %e
1080}
1081
1082; CHECK-LABEL: xor_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001083; CHECK-NEXT: .functype xor_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001084; CHECK: i64.atomic.rmw32.xor_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001085; CHECK-NEXT: return $pop0{{$}}
1086define i64 @xor_zext_i32_i64(i32* %p, i64 %v) {
1087 %t = trunc i64 %v to i32
1088 %old = atomicrmw xor i32* %p, i32 %t seq_cst
1089 %e = zext i32 %old to i64
1090 ret i64 %e
1091}
1092
1093; xchg
1094
1095; CHECK-LABEL: xchg_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001096; CHECK-NEXT: .functype xchg_zext_i8_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001097; CHECK: i32.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001098; CHECK-NEXT: return $pop0{{$}}
1099define i32 @xchg_zext_i8_i32(i8* %p, i32 %v) {
1100 %t = trunc i32 %v to i8
1101 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
1102 %e = zext i8 %old to i32
1103 ret i32 %e
1104}
1105
1106; CHECK-LABEL: xchg_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001107; CHECK-NEXT: .functype xchg_zext_i16_i32 (i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001108; CHECK: i32.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001109; CHECK-NEXT: return $pop0{{$}}
1110define i32 @xchg_zext_i16_i32(i16* %p, i32 %v) {
1111 %t = trunc i32 %v to i16
1112 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
1113 %e = zext i16 %old to i32
1114 ret i32 %e
1115}
1116
1117; CHECK-LABEL: xchg_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001118; CHECK-NEXT: .functype xchg_zext_i8_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001119; CHECK: i64.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001120; CHECK-NEXT: return $pop0{{$}}
1121define i64 @xchg_zext_i8_i64(i8* %p, i64 %v) {
1122 %t = trunc i64 %v to i8
1123 %old = atomicrmw xchg i8* %p, i8 %t seq_cst
1124 %e = zext i8 %old to i64
1125 ret i64 %e
1126}
1127
1128; CHECK-LABEL: xchg_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001129; CHECK-NEXT: .functype xchg_zext_i16_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001130; CHECK: i64.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001131; CHECK-NEXT: return $pop0{{$}}
1132define i64 @xchg_zext_i16_i64(i16* %p, i64 %v) {
1133 %t = trunc i64 %v to i16
1134 %old = atomicrmw xchg i16* %p, i16 %t seq_cst
1135 %e = zext i16 %old to i64
1136 ret i64 %e
1137}
1138
1139; CHECK-LABEL: xchg_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001140; CHECK-NEXT: .functype xchg_zext_i32_i64 (i32, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001141; CHECK: i64.atomic.rmw32.xchg_u $push0=, 0($0), $1{{$}}
Heejin Ahnfed73822018-07-09 22:30:51 +00001142; CHECK-NEXT: return $pop0{{$}}
1143define i64 @xchg_zext_i32_i64(i32* %p, i64 %v) {
1144 %t = trunc i64 %v to i32
1145 %old = atomicrmw xchg i32* %p, i32 %t seq_cst
1146 %e = zext i32 %old to i64
1147 ret i64 %e
1148}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001149
1150; cmpxchg
1151
1152; CHECK-LABEL: cmpxchg_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001153; CHECK-NEXT: .functype cmpxchg_zext_i8_i32 (i32, i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001154; CHECK: i32.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001155; CHECK-NEXT: return $pop0{{$}}
1156define i32 @cmpxchg_zext_i8_i32(i8* %p, i32 %exp, i32 %new) {
1157 %exp_t = trunc i32 %exp to i8
1158 %new_t = trunc i32 %new to i8
1159 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
1160 %old = extractvalue { i8, i1 } %pair, 0
1161 %e = zext i8 %old to i32
1162 ret i32 %e
1163}
1164
1165; CHECK-LABEL: cmpxchg_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001166; CHECK-NEXT: .functype cmpxchg_zext_i16_i32 (i32, i32, i32) -> (i32){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001167; CHECK: i32.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001168; CHECK-NEXT: return $pop0{{$}}
1169define i32 @cmpxchg_zext_i16_i32(i16* %p, i32 %exp, i32 %new) {
1170 %exp_t = trunc i32 %exp to i16
1171 %new_t = trunc i32 %new to i16
1172 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
1173 %old = extractvalue { i16, i1 } %pair, 0
1174 %e = zext i16 %old to i32
1175 ret i32 %e
1176}
1177
1178; CHECK-LABEL: cmpxchg_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001179; CHECK-NEXT: .functype cmpxchg_zext_i8_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001180; CHECK: i64.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001181; CHECK-NEXT: return $pop0{{$}}
1182define i64 @cmpxchg_zext_i8_i64(i8* %p, i64 %exp, i64 %new) {
1183 %exp_t = trunc i64 %exp to i8
1184 %new_t = trunc i64 %new to i8
1185 %pair = cmpxchg i8* %p, i8 %exp_t, i8 %new_t seq_cst seq_cst
1186 %old = extractvalue { i8, i1 } %pair, 0
1187 %e = zext i8 %old to i64
1188 ret i64 %e
1189}
1190
1191; CHECK-LABEL: cmpxchg_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001192; CHECK-NEXT: .functype cmpxchg_zext_i16_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001193; CHECK: i64.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001194; CHECK-NEXT: return $pop0{{$}}
1195define i64 @cmpxchg_zext_i16_i64(i16* %p, i64 %exp, i64 %new) {
1196 %exp_t = trunc i64 %exp to i16
1197 %new_t = trunc i64 %new to i16
1198 %pair = cmpxchg i16* %p, i16 %exp_t, i16 %new_t seq_cst seq_cst
1199 %old = extractvalue { i16, i1 } %pair, 0
1200 %e = zext i16 %old to i64
1201 ret i64 %e
1202}
1203
1204; CHECK-LABEL: cmpxchg_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001205; CHECK-NEXT: .functype cmpxchg_zext_i32_i64 (i32, i64, i64) -> (i64){{$}}
Thomas Lively6a87dda2019-01-08 06:25:55 +00001206; CHECK: i64.atomic.rmw32.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
Heejin Ahnb3724b72018-08-01 19:40:28 +00001207; CHECK-NEXT: return $pop0{{$}}
1208define i64 @cmpxchg_zext_i32_i64(i32* %p, i64 %exp, i64 %new) {
1209 %exp_t = trunc i64 %exp to i32
1210 %new_t = trunc i64 %new to i32
1211 %pair = cmpxchg i32* %p, i32 %exp_t, i32 %new_t seq_cst seq_cst
1212 %old = extractvalue { i32, i1 } %pair, 0
1213 %e = zext i32 %old to i64
1214 ret i64 %e
1215}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001216
1217; Unsupported instructions are expanded using cmpxchg with a loop.
1218; Here we take a nand as an example.
1219
1220; nand
1221
1222; CHECK-LABEL: nand_zext_i8_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001223; CHECK-NEXT: .functype nand_zext_i8_i32 (i32, i32) -> (i32){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001224; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +00001225; CHECK: i32.atomic.rmw8.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001226define i32 @nand_zext_i8_i32(i8* %p, i32 %v) {
1227 %t = trunc i32 %v to i8
1228 %old = atomicrmw nand i8* %p, i8 %t seq_cst
1229 %e = zext i8 %old to i32
1230 ret i32 %e
1231}
1232
1233; CHECK-LABEL: nand_zext_i16_i32:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001234; CHECK-NEXT: .functype nand_zext_i16_i32 (i32, i32) -> (i32){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001235; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +00001236; CHECK: i32.atomic.rmw16.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001237define i32 @nand_zext_i16_i32(i16* %p, i32 %v) {
1238 %t = trunc i32 %v to i16
1239 %old = atomicrmw nand i16* %p, i16 %t seq_cst
1240 %e = zext i16 %old to i32
1241 ret i32 %e
1242}
1243
Thomas Lively6a87dda2019-01-08 06:25:55 +00001244; FIXME Currently this cannot make use of i64.atomic.rmw8.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001245; CHECK-LABEL: nand_zext_i8_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001246; CHECK-NEXT: .functype nand_zext_i8_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001247; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +00001248; CHECK: i32.atomic.rmw8.cmpxchg_u
1249; CHECK: i64.extend_i32_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001250define i64 @nand_zext_i8_i64(i8* %p, i64 %v) {
1251 %t = trunc i64 %v to i8
1252 %old = atomicrmw nand i8* %p, i8 %t seq_cst
1253 %e = zext i8 %old to i64
1254 ret i64 %e
1255}
1256
Thomas Lively6a87dda2019-01-08 06:25:55 +00001257; FIXME Currently this cannot make use of i64.atomic.rmw16.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001258; CHECK-LABEL: nand_zext_i16_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001259; CHECK-NEXT: .functype nand_zext_i16_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001260; CHECK: loop
Thomas Lively6a87dda2019-01-08 06:25:55 +00001261; CHECK: i32.atomic.rmw16.cmpxchg_u
1262; CHECK: i64.extend_i32_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001263define i64 @nand_zext_i16_i64(i16* %p, i64 %v) {
1264 %t = trunc i64 %v to i16
1265 %old = atomicrmw nand i16* %p, i16 %t seq_cst
1266 %e = zext i16 %old to i64
1267 ret i64 %e
1268}
1269
Thomas Lively6a87dda2019-01-08 06:25:55 +00001270; FIXME Currently this cannot make use of i64.atomic.rmw32.cmpxchg_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001271; CHECK-LABEL: nand_zext_i32_i64:
Wouter van Oortmerssen49482f82018-11-19 17:10:36 +00001272; CHECK-NEXT: .functype nand_zext_i32_i64 (i32, i64) -> (i64){{$}}
Heejin Ahne8653bb2018-08-07 00:22:22 +00001273; CHECK: loop
1274; CHECK: i32.atomic.rmw.cmpxchg
Thomas Lively6a87dda2019-01-08 06:25:55 +00001275; CHECK: i64.extend_i32_u
Heejin Ahne8653bb2018-08-07 00:22:22 +00001276define i64 @nand_zext_i32_i64(i32* %p, i64 %v) {
1277 %t = trunc i64 %v to i32
1278 %old = atomicrmw nand i32* %p, i32 %t seq_cst
1279 %e = zext i32 %old to i64
1280 ret i64 %e
1281}