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(i64* %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 i64* %ptr, i64 %val seq_cst 36 ret i64 %r 37} 38 39define i64 @test2(i64* %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 i64* %ptr, i64 %val seq_cst 67 ret i64 %r 68} 69 70define i64 @test3(i64* %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 i64* %ptr, i64 %val seq_cst 98 ret i64 %r 99} 100 101define i64 @test4(i64* %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 i64* %ptr, i64 %val seq_cst 129 ret i64 %r 130} 131 132define i64 @test5(i64* %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 i64* %ptr, i64 %val seq_cst 160 ret i64 %r 161} 162 163define i64 @test6(i64* %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 i64* %ptr, i64 %val seq_cst 183 ret i64 %r 184} 185 186define i64 @test7(i64* %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 i64* %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(i64* %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, i64* %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(i64* %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, i64* %ptr seq_cst, align 8 269 ret void 270} 271 272define i64 @test10(i64* %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: mov [[CMP:[a-z0-9]+]], #0 282; CHECK: movwge [[CMP]], #1 283; CHECK: cmp [[CMP]], #0 284; CHECK: movne [[OUT_HI]], [[REG2]] 285; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 286; CHECK: movne [[OUT_LO]], [[REG1]] 287; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 288; CHECK: cmp 289; CHECK: bne 290; CHECK: dmb {{ish$}} 291 292; CHECK-THUMB-LABEL: test10: 293; CHECK-THUMB: dmb {{ish$}} 294; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 295; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 296; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 297; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 298; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 299; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 300; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0 301; CHECK-THUMB: movge.w [[CMP]], #1 302; CHECK-THUMB: cmp.w [[CMP]], #0 303; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 304; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 305; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 306; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 307; CHECK-THUMB: cmp 308; CHECK-THUMB: bne 309; CHECK-THUMB: dmb {{ish$}} 310 311; CHECK-M: __atomic_compare_exchange_8 312 313 %r = atomicrmw min i64* %ptr, i64 %val seq_cst 314 ret i64 %r 315} 316 317define i64 @test11(i64* %ptr, i64 %val) { 318; CHECK-LABEL: test11: 319; CHECK: dmb {{ish$}} 320; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 321; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 322; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 323; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 324; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 325; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 326; CHECK: mov [[CMP:[a-z0-9]+]], #0 327; CHECK: movwhs [[CMP]], #1 328; CHECK: cmp [[CMP]], #0 329; CHECK: movne [[OUT_HI]], [[REG2]] 330; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 331; CHECK: movne [[OUT_LO]], [[REG1]] 332; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 333; CHECK: cmp 334; CHECK: bne 335; CHECK: dmb {{ish$}} 336 337; CHECK-THUMB-LABEL: test11: 338; CHECK-THUMB: dmb {{ish$}} 339; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 340; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 341; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 342; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 343; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 344; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 345; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0 346; CHECK-THUMB: movhs.w [[CMP]], #1 347; CHECK-THUMB: cmp.w [[CMP]], #0 348; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 349; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 350; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 351; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 352; CHECK-THUMB: cmp 353; CHECK-THUMB: bne 354; CHECK-THUMB: dmb {{ish$}} 355 356; CHECK-M: __atomic_compare_exchange_8 357 358 %r = atomicrmw umin i64* %ptr, i64 %val seq_cst 359 ret i64 %r 360} 361 362define i64 @test12(i64* %ptr, i64 %val) { 363; CHECK-LABEL: test12: 364; CHECK: dmb {{ish$}} 365; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 366; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 367; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 368; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 369; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 370; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 371; CHECK: mov [[CMP:[a-z0-9]+]], #0 372; CHECK: movwlt [[CMP]], #1 373; CHECK: cmp [[CMP]], #0 374; CHECK: movne [[OUT_HI]], [[REG2]] 375; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 376; CHECK: movne [[OUT_LO]], [[REG1]] 377; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 378; CHECK: cmp 379; CHECK: bne 380; CHECK: dmb {{ish$}} 381 382; CHECK-THUMB-LABEL: test12: 383; CHECK-THUMB: dmb {{ish$}} 384; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 385; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 386; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 387; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 388; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 389; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 390; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0 391; CHECK-THUMB: movlt.w [[CMP]], #1 392; CHECK-THUMB: cmp.w [[CMP]], #0 393; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 394; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 395; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 396; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 397; CHECK-THUMB: cmp 398; CHECK-THUMB: bne 399; CHECK-THUMB: dmb {{ish$}} 400 401; CHECK-M: __atomic_compare_exchange_8 402 403 %r = atomicrmw max i64* %ptr, i64 %val seq_cst 404 ret i64 %r 405} 406 407define i64 @test13(i64* %ptr, i64 %val) { 408; CHECK-LABEL: test13: 409; CHECK: dmb {{ish$}} 410; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 411; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 412; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]] 413; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]] 414; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]] 415; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]] 416; CHECK: mov [[CMP:[a-z0-9]+]], #0 417; CHECK: movwlo [[CMP]], #1 418; CHECK: cmp [[CMP]], #0 419; CHECK: movne [[OUT_HI]], [[REG2]] 420; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 421; CHECK: movne [[OUT_LO]], [[REG1]] 422; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 423; CHECK: cmp 424; CHECK: bne 425; CHECK: dmb {{ish$}} 426 427; CHECK-THUMB-LABEL: test13: 428; CHECK-THUMB: dmb {{ish$}} 429; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 430; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 431; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]] 432; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]] 433; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]] 434; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]] 435; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0 436; CHECK-THUMB: movlo.w [[CMP]], #1 437; CHECK-THUMB: cmp.w [[CMP]], #0 438; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 439; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 440; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 441; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]] 442; CHECK-THUMB: cmp 443; CHECK-THUMB: bne 444; CHECK-THUMB: dmb {{ish$}} 445 446; CHECK-M: __atomic_compare_exchange_8 447 448 %r = atomicrmw umax i64* %ptr, i64 %val seq_cst 449 ret i64 %r 450} 451 452