1; 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 3 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 67; 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 88;===---------------------------------------------------------------------------- 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 146; 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 167;===---------------------------------------------------------------------------- 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{{$}} 224; CHECK: i32.wrap/i64 $push0=, $1{{$}} 225; 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{{$}} 352; CHECK: i32.wrap/i64 $push0=, $1{{$}} 353; 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{{$}} 416; CHECK: i32.wrap/i64 $push0=, $1{{$}} 417; 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{{$}} 480; CHECK: i32.wrap/i64 $push0=, $1{{$}} 481; 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{{$}} 544; CHECK: i32.wrap/i64 $push0=, $1{{$}} 545; 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 555; 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 630;===---------------------------------------------------------------------------- 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} 975 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} 1042