1; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE 2; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE 3; RUN: llc < %s -mtriple=armebv7 -target-abi apcs | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE 4; RUN: llc < %s -mtriple=thumbebv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE 5; RUN: llc < %s -mtriple=armv7m--none-eabi | FileCheck %s --check-prefix=CHECK-M 6; RUN: llc < %s -mtriple=armv8m--none-eabi | FileCheck %s --check-prefix=CHECK-M 7 8define i64 @test1(ptr %ptr, i64 %val) { 9; CHECK-LABEL: test1: 10; CHECK: dmb {{ish$}} 11; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 12; CHECK-LE: adds [[REG3:(r[0-9]?[02468])]], [[REG1]] 13; CHECK-LE: adc [[REG4:(r[0-9]?[13579])]], [[REG2]] 14; CHECK-BE: adds [[REG4:(r[0-9]?[13579])]], [[REG2]] 15; CHECK-BE: adc [[REG3:(r[0-9]?[02468])]], [[REG1]] 16; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 17; CHECK: cmp 18; CHECK: bne 19; CHECK: dmb {{ish$}} 20 21; CHECK-THUMB-LABEL: test1: 22; CHECK-THUMB: dmb {{ish$}} 23; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 24; CHECK-THUMB-LE: adds.w [[REG3:[a-z0-9]+]], [[REG1]] 25; CHECK-THUMB-LE: adc.w [[REG4:[a-z0-9]+]], [[REG2]] 26; CHECK-THUMB-BE: adds.w [[REG4:[a-z0-9]+]], [[REG2]] 27; CHECK-THUMB-BE: adc.w [[REG3:[a-z0-9]+]], [[REG1]] 28; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 29; CHECK-THUMB: cmp 30; CHECK-THUMB: bne 31; CHECK-THUMB: dmb {{ish$}} 32 33; CHECK-M: __atomic_fetch_add_8 34 35 %r = atomicrmw add ptr %ptr, i64 %val seq_cst 36 ret i64 %r 37} 38 39define i64 @test2(ptr %ptr, i64 %val) { 40; CHECK-LABEL: test2: 41; CHECK: dmb {{ish$}} 42; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 43; CHECK-LE: subs [[REG3:(r[0-9]?[02468])]], [[REG1]] 44; CHECK-LE: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]] 45; CHECK-BE: subs [[REG4:(r[0-9]?[13579])]], [[REG2]] 46; CHECK-BE: sbc [[REG3:(r[0-9]?[02468])]], [[REG1]] 47; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 48; CHECK: cmp 49; CHECK: bne 50; CHECK: dmb {{ish$}} 51 52; CHECK-THUMB-LABEL: test2: 53; CHECK-THUMB: dmb {{ish$}} 54; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 55; CHECK-THUMB-LE: subs.w [[REG3:[a-z0-9]+]], [[REG1]] 56; CHECK-THUMB-LE: sbc.w [[REG4:[a-z0-9]+]], [[REG2]] 57; CHECK-THUMB-BE: subs.w [[REG4:[a-z0-9]+]], [[REG2]] 58; CHECK-THUMB-BE: sbc.w [[REG3:[a-z0-9]+]], [[REG1]] 59; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 60; CHECK-THUMB: cmp 61; CHECK-THUMB: bne 62; CHECK-THUMB: dmb {{ish$}} 63 64; CHECK-M: __atomic_fetch_sub_8 65 66 %r = atomicrmw sub ptr %ptr, i64 %val seq_cst 67 ret i64 %r 68} 69 70define i64 @test3(ptr %ptr, i64 %val) { 71; CHECK-LABEL: test3: 72; CHECK: dmb {{ish$}} 73; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 74; CHECK-LE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]], 75; CHECK-LE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]], 76; CHECK-BE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]], 77; CHECK-BE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]], 78; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 79; CHECK: cmp 80; CHECK: bne 81; CHECK: dmb {{ish$}} 82 83; CHECK-THUMB-LABEL: test3: 84; CHECK-THUMB: dmb {{ish$}} 85; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 86; CHECK-THUMB-LE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]], 87; CHECK-THUMB-LE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]], 88; CHECK-THUMB-BE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]], 89; CHECK-THUMB-BE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]], 90; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 91; CHECK-THUMB: cmp 92; CHECK-THUMB: bne 93; CHECK-THUMB: dmb {{ish$}} 94 95; CHECK-M: _atomic_fetch_and_8 96 97 %r = atomicrmw and ptr %ptr, i64 %val seq_cst 98 ret i64 %r 99} 100 101define i64 @test4(ptr %ptr, i64 %val) { 102; CHECK-LABEL: test4: 103; CHECK: dmb {{ish$}} 104; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 105; CHECK-LE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]], 106; CHECK-LE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]], 107; CHECK-BE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]], 108; CHECK-BE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]], 109; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 110; CHECK: cmp 111; CHECK: bne 112; CHECK: dmb {{ish$}} 113 114; CHECK-THUMB-LABEL: test4: 115; CHECK-THUMB: dmb {{ish$}} 116; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 117; CHECK-THUMB-LE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]], 118; CHECK-THUMB-LE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]], 119; CHECK-THUMB-BE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]], 120; CHECK-THUMB-BE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]], 121; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 122; CHECK-THUMB: cmp 123; CHECK-THUMB: bne 124; CHECK-THUMB: dmb {{ish$}} 125 126; CHECK-M: __atomic_fetch_or_8 127 128 %r = atomicrmw or ptr %ptr, i64 %val seq_cst 129 ret i64 %r 130} 131 132define i64 @test5(ptr %ptr, i64 %val) { 133; CHECK-LABEL: test5: 134; CHECK: dmb {{ish$}} 135; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 136; CHECK-LE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]], 137; CHECK-LE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]], 138; CHECK-BE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]], 139; CHECK-BE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]], 140; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 141; CHECK: cmp 142; CHECK: bne 143; CHECK: dmb {{ish$}} 144 145; CHECK-THUMB-LABEL: test5: 146; CHECK-THUMB: dmb {{ish$}} 147; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 148; CHECK-THUMB-LE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]], 149; CHECK-THUMB-LE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]], 150; CHECK-THUMB-BE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]], 151; CHECK-THUMB-BE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]], 152; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 153; CHECK-THUMB: cmp 154; CHECK-THUMB: bne 155; CHECK-THUMB: dmb {{ish$}} 156 157; CHECK-M: __atomic_fetch_xor_8 158 159 %r = atomicrmw xor ptr %ptr, i64 %val seq_cst 160 ret i64 %r 161} 162 163define i64 @test6(ptr %ptr, i64 %val) { 164; CHECK-LABEL: test6: 165; CHECK: dmb {{ish$}} 166; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 167; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 168; CHECK: cmp 169; CHECK: bne 170; CHECK: dmb {{ish$}} 171 172; CHECK-THUMB-LABEL: test6: 173; CHECK-THUMB: dmb {{ish$}} 174; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 175; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 176; CHECK-THUMB: cmp 177; CHECK-THUMB: bne 178; CHECK-THUMB: dmb {{ish$}} 179 180; CHECK-M: __atomic_exchange_8 181 182 %r = atomicrmw xchg ptr %ptr, i64 %val seq_cst 183 ret i64 %r 184} 185 186define i64 @test7(ptr %ptr, i64 %val1, i64 %val2) { 187; CHECK-LABEL: test7: 188; CHECK-DAG: mov [[VAL1LO:r[0-9]+]], r1 189; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 190; CHECK-LE-DAG: eor [[MISMATCH_LO:.*]], [[REG1]], [[VAL1LO]] 191; CHECK-LE-DAG: eor [[MISMATCH_HI:.*]], [[REG2]], r2 192; CHECK-BE-DAG: eor [[MISMATCH_LO:.*]], [[REG2]], r2 193; CHECK-BE-DAG: eor [[MISMATCH_HI:.*]], [[REG1]], r1 194; CHECK: orrs {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]] 195; CHECK: bne 196; CHECK-DAG: dmb {{ish$}} 197; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 198; CHECK: cmp 199; CHECK: beq 200; CHECK: dmb {{ish$}} 201 202; CHECK-THUMB-LABEL: test7: 203; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 204; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2 205; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3 206; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG1]], r2 207; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG2]], r3 208; CHECK-THUMB-LE: orrs.w {{.*}}, [[MISMATCH_LO]], [[MISMATCH_HI]] 209; CHECK-THUMB: bne 210; CHECK-THUMB: dmb {{ish$}} 211; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 212; CHECK-THUMB: cmp 213; CHECK-THUMB: beq 214; CHECK-THUMB: dmb {{ish$}} 215 216; CHECK-M: __atomic_compare_exchange_8 217 218 %pair = cmpxchg ptr %ptr, i64 %val1, i64 %val2 seq_cst seq_cst 219 %r = extractvalue { i64, i1 } %pair, 0 220 ret i64 %r 221} 222 223; Compiles down to a single ldrexd, except on M class devices where ldrexd 224; isn't supported. 225define i64 @test8(ptr %ptr) { 226; CHECK-LABEL: test8: 227; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 228; CHECK-NOT: strexd 229; CHECK: clrex 230; CHECK-NOT: strexd 231; CHECK: dmb {{ish$}} 232 233; CHECK-THUMB-LABEL: test8: 234; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 235; CHECK-THUMB-NOT: strexd 236; CHECK-THUMB: clrex 237; CHECK-THUMB-NOT: strexd 238; CHECK-THUMB: dmb {{ish$}} 239 240; CHECK-M: __atomic_load_8 241 242 %r = load atomic i64, ptr %ptr seq_cst, align 8 243 ret i64 %r 244} 245 246; Compiles down to atomicrmw xchg; there really isn't any more efficient 247; way to write it. Except on M class devices, where ldrexd/strexd aren't 248; supported. 249define void @test9(ptr %ptr, i64 %val) { 250; CHECK-LABEL: test9: 251; CHECK: dmb {{ish$}} 252; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 253; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 254; CHECK: cmp 255; CHECK: bne 256; CHECK: dmb {{ish$}} 257 258; CHECK-THUMB-LABEL: test9: 259; CHECK-THUMB: dmb {{ish$}} 260; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 261; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 262; CHECK-THUMB: cmp 263; CHECK-THUMB: bne 264; CHECK-THUMB: dmb {{ish$}} 265 266; CHECK-M: __atomic_store_8 267 268 store atomic i64 %val, ptr %ptr seq_cst, align 8 269 ret void 270} 271 272define i64 @test10(ptr %ptr, i64 %val) { 273; CHECK-LABEL: test10: 274; CHECK: dmb {{ish$}} 275; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 276; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 277; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 278; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 279; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 280; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 281; CHECK: movge [[OUT_HI]], [[REG2]] 282; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 283; CHECK: movge [[OUT_LO]], [[REG1]] 284; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 285; CHECK: cmp 286; CHECK: bne 287; CHECK: dmb {{ish$}} 288 289; CHECK-THUMB-LABEL: test10: 290; CHECK-THUMB: dmb {{ish$}} 291; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 292; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 293; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 294; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 295; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 296; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 297; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 298; CHECK-THUMB: itt ge 299; CHECK-THUMB: movge [[OUT_HI]], [[REG2]] 300; CHECK-THUMB: movge [[OUT_LO]], [[REG1]] 301; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 302; CHECK-THUMB: cmp 303; CHECK-THUMB: bne 304; CHECK-THUMB: dmb {{ish$}} 305 306; CHECK-M: __atomic_compare_exchange_8 307 308 %r = atomicrmw min ptr %ptr, i64 %val seq_cst 309 ret i64 %r 310} 311 312define i64 @test11(ptr %ptr, i64 %val) { 313; CHECK-LABEL: test11: 314; CHECK: dmb {{ish$}} 315; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 316; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 317; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 318; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 319; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 320; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 321; CHECK: movhs [[OUT_HI]], [[REG2]] 322; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 323; CHECK: movhs [[OUT_LO]], [[REG1]] 324; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 325; CHECK: cmp 326; CHECK: bne 327; CHECK: dmb {{ish$}} 328 329; CHECK-THUMB-LABEL: test11: 330; CHECK-THUMB: dmb {{ish$}} 331; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 332; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 333; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 334; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 335; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 336; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 337; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 338; CHECK-THUMB: itt hs 339; CHECK-THUMB: movhs [[OUT_HI]], [[REG2]] 340; CHECK-THUMB: movhs [[OUT_LO]], [[REG1]] 341; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 342; CHECK-THUMB: cmp 343; CHECK-THUMB: bne 344; CHECK-THUMB: dmb {{ish$}} 345 346; CHECK-M: __atomic_compare_exchange_8 347 348 %r = atomicrmw umin ptr %ptr, i64 %val seq_cst 349 ret i64 %r 350} 351 352define i64 @test12(ptr %ptr, i64 %val) { 353; CHECK-LABEL: test12: 354; CHECK: dmb {{ish$}} 355; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 356; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 357; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 358; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 359; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 360; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 361; CHECK: movlt [[OUT_HI]], [[REG2]] 362; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 363; CHECK: movlt [[OUT_LO]], [[REG1]] 364; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 365; CHECK: cmp 366; CHECK: bne 367; CHECK: dmb {{ish$}} 368 369; CHECK-THUMB-LABEL: test12: 370; CHECK-THUMB: dmb {{ish$}} 371; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 372; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 373; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 374; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 375; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 376; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 377; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 378; CHECK-THUMB: itt lt 379; CHECK-THUMB: movlt [[OUT_HI]], [[REG2]] 380; CHECK-THUMB: movlt [[OUT_LO]], [[REG1]] 381; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 382; CHECK-THUMB: cmp 383; CHECK-THUMB: bne 384; CHECK-THUMB: dmb {{ish$}} 385 386; CHECK-M: __atomic_compare_exchange_8 387 388 %r = atomicrmw max ptr %ptr, i64 %val seq_cst 389 ret i64 %r 390} 391 392define i64 @test13(ptr %ptr, i64 %val) { 393; CHECK-LABEL: test13: 394; CHECK: dmb {{ish$}} 395; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 396; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 397; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 398; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 399; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 400; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 401; CHECK: movlo [[OUT_HI]], [[REG2]] 402; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 403; CHECK: movlo [[OUT_LO]], [[REG1]] 404; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 405; CHECK: cmp 406; CHECK: bne 407; CHECK: dmb {{ish$}} 408 409; CHECK-THUMB-LABEL: test13: 410; CHECK-THUMB: dmb {{ish$}} 411; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 412; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 413; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 414; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 415; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 416; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 417; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 418; CHECK-THUMB: itt lo 419; CHECK-THUMB: movlo [[OUT_HI]], [[REG2]] 420; CHECK-THUMB: movlo [[OUT_LO]], [[REG1]] 421; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 422; CHECK-THUMB: cmp 423; CHECK-THUMB: bne 424; CHECK-THUMB: dmb {{ish$}} 425 426; CHECK-M: __atomic_compare_exchange_8 427 428 %r = atomicrmw umax ptr %ptr, i64 %val seq_cst 429 ret i64 %r 430} 431 432