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