1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=wasm32-unknown-unknown < %s | FileCheck -check-prefix=WASM32 %s 3; RUN: llc -mtriple=wasm64-unknown-unknown < %s | FileCheck -check-prefix=WASM64 %s 4 5define i8 @atomicrmw_uinc_wrap_i8(ptr %ptr, i8 %val) { 6; WASM32-LABEL: atomicrmw_uinc_wrap_i8: 7; WASM32: .functype atomicrmw_uinc_wrap_i8 (i32, i32) -> (i32) 8; WASM32-NEXT: .local i32 9; WASM32-NEXT: # %bb.0: 10; WASM32-NEXT: local.get 0 11; WASM32-NEXT: i32.const 0 12; WASM32-NEXT: local.get 0 13; WASM32-NEXT: i32.load8_u 0 14; WASM32-NEXT: local.tee 2 15; WASM32-NEXT: i32.const 1 16; WASM32-NEXT: i32.add 17; WASM32-NEXT: local.get 2 18; WASM32-NEXT: local.get 1 19; WASM32-NEXT: i32.const 255 20; WASM32-NEXT: i32.and 21; WASM32-NEXT: i32.ge_u 22; WASM32-NEXT: i32.select 23; WASM32-NEXT: i32.store8 0 24; WASM32-NEXT: local.get 2 25; WASM32-NEXT: # fallthrough-return 26; 27; WASM64-LABEL: atomicrmw_uinc_wrap_i8: 28; WASM64: .functype atomicrmw_uinc_wrap_i8 (i64, i32) -> (i32) 29; WASM64-NEXT: .local i32 30; WASM64-NEXT: # %bb.0: 31; WASM64-NEXT: local.get 0 32; WASM64-NEXT: i32.const 0 33; WASM64-NEXT: local.get 0 34; WASM64-NEXT: i32.load8_u 0 35; WASM64-NEXT: local.tee 2 36; WASM64-NEXT: i32.const 1 37; WASM64-NEXT: i32.add 38; WASM64-NEXT: local.get 2 39; WASM64-NEXT: local.get 1 40; WASM64-NEXT: i32.const 255 41; WASM64-NEXT: i32.and 42; WASM64-NEXT: i32.ge_u 43; WASM64-NEXT: i32.select 44; WASM64-NEXT: i32.store8 0 45; WASM64-NEXT: local.get 2 46; WASM64-NEXT: # fallthrough-return 47 %result = atomicrmw uinc_wrap ptr %ptr, i8 %val seq_cst 48 ret i8 %result 49} 50 51define i16 @atomicrmw_uinc_wrap_i16(ptr %ptr, i16 %val) { 52; WASM32-LABEL: atomicrmw_uinc_wrap_i16: 53; WASM32: .functype atomicrmw_uinc_wrap_i16 (i32, i32) -> (i32) 54; WASM32-NEXT: .local i32 55; WASM32-NEXT: # %bb.0: 56; WASM32-NEXT: local.get 0 57; WASM32-NEXT: i32.const 0 58; WASM32-NEXT: local.get 0 59; WASM32-NEXT: i32.load16_u 0 60; WASM32-NEXT: local.tee 2 61; WASM32-NEXT: i32.const 1 62; WASM32-NEXT: i32.add 63; WASM32-NEXT: local.get 2 64; WASM32-NEXT: local.get 1 65; WASM32-NEXT: i32.const 65535 66; WASM32-NEXT: i32.and 67; WASM32-NEXT: i32.ge_u 68; WASM32-NEXT: i32.select 69; WASM32-NEXT: i32.store16 0 70; WASM32-NEXT: local.get 2 71; WASM32-NEXT: # fallthrough-return 72; 73; WASM64-LABEL: atomicrmw_uinc_wrap_i16: 74; WASM64: .functype atomicrmw_uinc_wrap_i16 (i64, i32) -> (i32) 75; WASM64-NEXT: .local i32 76; WASM64-NEXT: # %bb.0: 77; WASM64-NEXT: local.get 0 78; WASM64-NEXT: i32.const 0 79; WASM64-NEXT: local.get 0 80; WASM64-NEXT: i32.load16_u 0 81; WASM64-NEXT: local.tee 2 82; WASM64-NEXT: i32.const 1 83; WASM64-NEXT: i32.add 84; WASM64-NEXT: local.get 2 85; WASM64-NEXT: local.get 1 86; WASM64-NEXT: i32.const 65535 87; WASM64-NEXT: i32.and 88; WASM64-NEXT: i32.ge_u 89; WASM64-NEXT: i32.select 90; WASM64-NEXT: i32.store16 0 91; WASM64-NEXT: local.get 2 92; WASM64-NEXT: # fallthrough-return 93 %result = atomicrmw uinc_wrap ptr %ptr, i16 %val seq_cst 94 ret i16 %result 95} 96 97define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) { 98; WASM32-LABEL: atomicrmw_uinc_wrap_i32: 99; WASM32: .functype atomicrmw_uinc_wrap_i32 (i32, i32) -> (i32) 100; WASM32-NEXT: .local i32 101; WASM32-NEXT: # %bb.0: 102; WASM32-NEXT: local.get 0 103; WASM32-NEXT: i32.const 0 104; WASM32-NEXT: local.get 0 105; WASM32-NEXT: i32.load 0 106; WASM32-NEXT: local.tee 2 107; WASM32-NEXT: i32.const 1 108; WASM32-NEXT: i32.add 109; WASM32-NEXT: local.get 2 110; WASM32-NEXT: local.get 1 111; WASM32-NEXT: i32.ge_u 112; WASM32-NEXT: i32.select 113; WASM32-NEXT: i32.store 0 114; WASM32-NEXT: local.get 2 115; WASM32-NEXT: # fallthrough-return 116; 117; WASM64-LABEL: atomicrmw_uinc_wrap_i32: 118; WASM64: .functype atomicrmw_uinc_wrap_i32 (i64, i32) -> (i32) 119; WASM64-NEXT: .local i32 120; WASM64-NEXT: # %bb.0: 121; WASM64-NEXT: local.get 0 122; WASM64-NEXT: i32.const 0 123; WASM64-NEXT: local.get 0 124; WASM64-NEXT: i32.load 0 125; WASM64-NEXT: local.tee 2 126; WASM64-NEXT: i32.const 1 127; WASM64-NEXT: i32.add 128; WASM64-NEXT: local.get 2 129; WASM64-NEXT: local.get 1 130; WASM64-NEXT: i32.ge_u 131; WASM64-NEXT: i32.select 132; WASM64-NEXT: i32.store 0 133; WASM64-NEXT: local.get 2 134; WASM64-NEXT: # fallthrough-return 135 %result = atomicrmw uinc_wrap ptr %ptr, i32 %val seq_cst 136 ret i32 %result 137} 138 139define i64 @atomicrmw_uinc_wrap_i64(ptr %ptr, i64 %val) { 140; WASM32-LABEL: atomicrmw_uinc_wrap_i64: 141; WASM32: .functype atomicrmw_uinc_wrap_i64 (i32, i64) -> (i64) 142; WASM32-NEXT: .local i64 143; WASM32-NEXT: # %bb.0: 144; WASM32-NEXT: local.get 0 145; WASM32-NEXT: i64.const 0 146; WASM32-NEXT: local.get 0 147; WASM32-NEXT: i64.load 0 148; WASM32-NEXT: local.tee 2 149; WASM32-NEXT: i64.const 1 150; WASM32-NEXT: i64.add 151; WASM32-NEXT: local.get 2 152; WASM32-NEXT: local.get 1 153; WASM32-NEXT: i64.ge_u 154; WASM32-NEXT: i64.select 155; WASM32-NEXT: i64.store 0 156; WASM32-NEXT: local.get 2 157; WASM32-NEXT: # fallthrough-return 158; 159; WASM64-LABEL: atomicrmw_uinc_wrap_i64: 160; WASM64: .functype atomicrmw_uinc_wrap_i64 (i64, i64) -> (i64) 161; WASM64-NEXT: .local i64 162; WASM64-NEXT: # %bb.0: 163; WASM64-NEXT: local.get 0 164; WASM64-NEXT: i64.const 0 165; WASM64-NEXT: local.get 0 166; WASM64-NEXT: i64.load 0 167; WASM64-NEXT: local.tee 2 168; WASM64-NEXT: i64.const 1 169; WASM64-NEXT: i64.add 170; WASM64-NEXT: local.get 2 171; WASM64-NEXT: local.get 1 172; WASM64-NEXT: i64.ge_u 173; WASM64-NEXT: i64.select 174; WASM64-NEXT: i64.store 0 175; WASM64-NEXT: local.get 2 176; WASM64-NEXT: # fallthrough-return 177 %result = atomicrmw uinc_wrap ptr %ptr, i64 %val seq_cst 178 ret i64 %result 179} 180 181define i8 @atomicrmw_udec_wrap_i8(ptr %ptr, i8 %val) { 182; WASM32-LABEL: atomicrmw_udec_wrap_i8: 183; WASM32: .functype atomicrmw_udec_wrap_i8 (i32, i32) -> (i32) 184; WASM32-NEXT: .local i32 185; WASM32-NEXT: # %bb.0: 186; WASM32-NEXT: local.get 0 187; WASM32-NEXT: local.get 1 188; WASM32-NEXT: local.get 0 189; WASM32-NEXT: i32.load8_u 0 190; WASM32-NEXT: local.tee 2 191; WASM32-NEXT: i32.const -1 192; WASM32-NEXT: i32.add 193; WASM32-NEXT: local.get 2 194; WASM32-NEXT: local.get 1 195; WASM32-NEXT: i32.const 255 196; WASM32-NEXT: i32.and 197; WASM32-NEXT: i32.gt_u 198; WASM32-NEXT: i32.select 199; WASM32-NEXT: local.get 1 200; WASM32-NEXT: local.get 2 201; WASM32-NEXT: i32.select 202; WASM32-NEXT: i32.store8 0 203; WASM32-NEXT: local.get 2 204; WASM32-NEXT: # fallthrough-return 205; 206; WASM64-LABEL: atomicrmw_udec_wrap_i8: 207; WASM64: .functype atomicrmw_udec_wrap_i8 (i64, i32) -> (i32) 208; WASM64-NEXT: .local i32 209; WASM64-NEXT: # %bb.0: 210; WASM64-NEXT: local.get 0 211; WASM64-NEXT: local.get 1 212; WASM64-NEXT: local.get 0 213; WASM64-NEXT: i32.load8_u 0 214; WASM64-NEXT: local.tee 2 215; WASM64-NEXT: i32.const -1 216; WASM64-NEXT: i32.add 217; WASM64-NEXT: local.get 2 218; WASM64-NEXT: local.get 1 219; WASM64-NEXT: i32.const 255 220; WASM64-NEXT: i32.and 221; WASM64-NEXT: i32.gt_u 222; WASM64-NEXT: i32.select 223; WASM64-NEXT: local.get 1 224; WASM64-NEXT: local.get 2 225; WASM64-NEXT: i32.select 226; WASM64-NEXT: i32.store8 0 227; WASM64-NEXT: local.get 2 228; WASM64-NEXT: # fallthrough-return 229 %result = atomicrmw udec_wrap ptr %ptr, i8 %val seq_cst 230 ret i8 %result 231} 232 233define i16 @atomicrmw_udec_wrap_i16(ptr %ptr, i16 %val) { 234; WASM32-LABEL: atomicrmw_udec_wrap_i16: 235; WASM32: .functype atomicrmw_udec_wrap_i16 (i32, i32) -> (i32) 236; WASM32-NEXT: .local i32 237; WASM32-NEXT: # %bb.0: 238; WASM32-NEXT: local.get 0 239; WASM32-NEXT: local.get 1 240; WASM32-NEXT: local.get 0 241; WASM32-NEXT: i32.load16_u 0 242; WASM32-NEXT: local.tee 2 243; WASM32-NEXT: i32.const -1 244; WASM32-NEXT: i32.add 245; WASM32-NEXT: local.get 2 246; WASM32-NEXT: local.get 1 247; WASM32-NEXT: i32.const 65535 248; WASM32-NEXT: i32.and 249; WASM32-NEXT: i32.gt_u 250; WASM32-NEXT: i32.select 251; WASM32-NEXT: local.get 1 252; WASM32-NEXT: local.get 2 253; WASM32-NEXT: i32.select 254; WASM32-NEXT: i32.store16 0 255; WASM32-NEXT: local.get 2 256; WASM32-NEXT: # fallthrough-return 257; 258; WASM64-LABEL: atomicrmw_udec_wrap_i16: 259; WASM64: .functype atomicrmw_udec_wrap_i16 (i64, i32) -> (i32) 260; WASM64-NEXT: .local i32 261; WASM64-NEXT: # %bb.0: 262; WASM64-NEXT: local.get 0 263; WASM64-NEXT: local.get 1 264; WASM64-NEXT: local.get 0 265; WASM64-NEXT: i32.load16_u 0 266; WASM64-NEXT: local.tee 2 267; WASM64-NEXT: i32.const -1 268; WASM64-NEXT: i32.add 269; WASM64-NEXT: local.get 2 270; WASM64-NEXT: local.get 1 271; WASM64-NEXT: i32.const 65535 272; WASM64-NEXT: i32.and 273; WASM64-NEXT: i32.gt_u 274; WASM64-NEXT: i32.select 275; WASM64-NEXT: local.get 1 276; WASM64-NEXT: local.get 2 277; WASM64-NEXT: i32.select 278; WASM64-NEXT: i32.store16 0 279; WASM64-NEXT: local.get 2 280; WASM64-NEXT: # fallthrough-return 281 %result = atomicrmw udec_wrap ptr %ptr, i16 %val seq_cst 282 ret i16 %result 283} 284 285define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) { 286; WASM32-LABEL: atomicrmw_udec_wrap_i32: 287; WASM32: .functype atomicrmw_udec_wrap_i32 (i32, i32) -> (i32) 288; WASM32-NEXT: .local i32 289; WASM32-NEXT: # %bb.0: 290; WASM32-NEXT: local.get 0 291; WASM32-NEXT: local.get 1 292; WASM32-NEXT: local.get 0 293; WASM32-NEXT: i32.load 0 294; WASM32-NEXT: local.tee 2 295; WASM32-NEXT: i32.const -1 296; WASM32-NEXT: i32.add 297; WASM32-NEXT: local.get 2 298; WASM32-NEXT: local.get 1 299; WASM32-NEXT: i32.gt_u 300; WASM32-NEXT: i32.select 301; WASM32-NEXT: local.get 1 302; WASM32-NEXT: local.get 2 303; WASM32-NEXT: i32.select 304; WASM32-NEXT: i32.store 0 305; WASM32-NEXT: local.get 2 306; WASM32-NEXT: # fallthrough-return 307; 308; WASM64-LABEL: atomicrmw_udec_wrap_i32: 309; WASM64: .functype atomicrmw_udec_wrap_i32 (i64, i32) -> (i32) 310; WASM64-NEXT: .local i32 311; WASM64-NEXT: # %bb.0: 312; WASM64-NEXT: local.get 0 313; WASM64-NEXT: local.get 1 314; WASM64-NEXT: local.get 0 315; WASM64-NEXT: i32.load 0 316; WASM64-NEXT: local.tee 2 317; WASM64-NEXT: i32.const -1 318; WASM64-NEXT: i32.add 319; WASM64-NEXT: local.get 2 320; WASM64-NEXT: local.get 1 321; WASM64-NEXT: i32.gt_u 322; WASM64-NEXT: i32.select 323; WASM64-NEXT: local.get 1 324; WASM64-NEXT: local.get 2 325; WASM64-NEXT: i32.select 326; WASM64-NEXT: i32.store 0 327; WASM64-NEXT: local.get 2 328; WASM64-NEXT: # fallthrough-return 329 %result = atomicrmw udec_wrap ptr %ptr, i32 %val seq_cst 330 ret i32 %result 331} 332 333define i64 @atomicrmw_udec_wrap_i64(ptr %ptr, i64 %val) { 334; WASM32-LABEL: atomicrmw_udec_wrap_i64: 335; WASM32: .functype atomicrmw_udec_wrap_i64 (i32, i64) -> (i64) 336; WASM32-NEXT: .local i64 337; WASM32-NEXT: # %bb.0: 338; WASM32-NEXT: local.get 0 339; WASM32-NEXT: local.get 1 340; WASM32-NEXT: local.get 1 341; WASM32-NEXT: local.get 0 342; WASM32-NEXT: i64.load 0 343; WASM32-NEXT: local.tee 2 344; WASM32-NEXT: i64.const -1 345; WASM32-NEXT: i64.add 346; WASM32-NEXT: local.get 2 347; WASM32-NEXT: local.get 1 348; WASM32-NEXT: i64.gt_u 349; WASM32-NEXT: i64.select 350; WASM32-NEXT: local.get 2 351; WASM32-NEXT: i64.eqz 352; WASM32-NEXT: i64.select 353; WASM32-NEXT: i64.store 0 354; WASM32-NEXT: local.get 2 355; WASM32-NEXT: # fallthrough-return 356; 357; WASM64-LABEL: atomicrmw_udec_wrap_i64: 358; WASM64: .functype atomicrmw_udec_wrap_i64 (i64, i64) -> (i64) 359; WASM64-NEXT: .local i64 360; WASM64-NEXT: # %bb.0: 361; WASM64-NEXT: local.get 0 362; WASM64-NEXT: local.get 1 363; WASM64-NEXT: local.get 1 364; WASM64-NEXT: local.get 0 365; WASM64-NEXT: i64.load 0 366; WASM64-NEXT: local.tee 2 367; WASM64-NEXT: i64.const -1 368; WASM64-NEXT: i64.add 369; WASM64-NEXT: local.get 2 370; WASM64-NEXT: local.get 1 371; WASM64-NEXT: i64.gt_u 372; WASM64-NEXT: i64.select 373; WASM64-NEXT: local.get 2 374; WASM64-NEXT: i64.eqz 375; WASM64-NEXT: i64.select 376; WASM64-NEXT: i64.store 0 377; WASM64-NEXT: local.get 2 378; WASM64-NEXT: # fallthrough-return 379 %result = atomicrmw udec_wrap ptr %ptr, i64 %val seq_cst 380 ret i64 %result 381} 382