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-DAG: dmb {{ish$}} 176; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 177; CHECK-LE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], [[VAL1LO]] 178; CHECK-LE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2 179; CHECK-BE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG2]], r2 180; CHECK-BE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG1]], r1 181; CHECK: orrs {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]] 182; CHECK: bne 183; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 184; CHECK: cmp 185; CHECK: bne 186; CHECK: dmb {{ish$}} 187 188; CHECK-THUMB-LABEL: test7: 189; CHECK-THUMB: dmb {{ish$}} 190; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 191; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2 192; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3 193; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG1]], r2 194; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG2]], r3 195; CHECK-THUMB-LE: orrs [[MISMATCH_HI]], [[MISMATCH_LO]] 196; CHECK-THUMB: bne 197; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 198; CHECK-THUMB: cmp 199; CHECK-THUMB: bne 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: dmb {{ish$}} 212 213; CHECK-THUMB-LABEL: test8: 214; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 215; CHECK-THUMB: dmb {{ish$}} 216 217 %r = load atomic i64* %ptr seq_cst, align 8 218 ret i64 %r 219} 220 221; Compiles down to atomicrmw xchg; there really isn't any more efficient 222; way to write it. 223define void @test9(i64* %ptr, i64 %val) { 224; CHECK-LABEL: test9: 225; CHECK: dmb {{ish$}} 226; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 227; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 228; CHECK: cmp 229; CHECK: bne 230; CHECK: dmb {{ish$}} 231 232; CHECK-THUMB-LABEL: test9: 233; CHECK-THUMB: dmb {{ish$}} 234; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 235; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 236; CHECK-THUMB: cmp 237; CHECK-THUMB: bne 238; CHECK-THUMB: dmb {{ish$}} 239 240 store atomic i64 %val, i64* %ptr seq_cst, align 8 241 ret void 242} 243 244define i64 @test10(i64* %ptr, i64 %val) { 245; CHECK-LABEL: test10: 246; CHECK: dmb {{ish$}} 247; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 248; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 249; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 250; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 251; CHECK-LE: cmp [[REG1]], r1 252; CHECK-BE: cmp [[REG2]], r2 253; CHECK: movwls [[CARRY_LO]], #1 254; CHECK-LE: cmp [[REG2]], r2 255; CHECK-BE: cmp [[REG1]], r1 256; CHECK: movwle [[CARRY_HI]], #1 257; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 258; CHECK: cmp [[CARRY_HI]], #0 259; CHECK: movne [[OUT_HI]], [[REG2]] 260; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 261; CHECK: movne [[OUT_LO]], [[REG1]] 262; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 263; CHECK: cmp 264; CHECK: bne 265; CHECK: dmb {{ish$}} 266 267; CHECK-THUMB-LABEL: test10: 268; CHECK-THUMB: dmb {{ish$}} 269; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 270; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0 271; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0 272; CHECK-THUMB-LE: cmp [[REG1]], r2 273; CHECK-THUMB-BE: cmp [[REG2]], r3 274; CHECK-THUMB: movls.w [[CARRY_LO]], #1 275; CHECK-THUMB-LE: cmp [[REG2]], r3 276; CHECK-THUMB-BE: cmp [[REG1]], r2 277; CHECK-THUMB: movle [[CARRY_HI]], #1 278; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 279; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 280; CHECK-THUMB: cmp [[CARRY_HI]], #0 281; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 282; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 283; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 284; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 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 [[CARRY_LO:[a-z0-9]+]], #0 298; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 299; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 300; CHECK-LE: cmp [[REG1]], r1 301; CHECK-BE: cmp [[REG2]], r2 302; CHECK: movwls [[CARRY_LO]], #1 303; CHECK-LE: cmp [[REG2]], r2 304; CHECK-BE: cmp [[REG1]], r1 305; CHECK: movwls [[CARRY_HI]], #1 306; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 307; CHECK: cmp [[CARRY_HI]], #0 308; CHECK: movne [[OUT_HI]], [[REG2]] 309; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 310; CHECK: movne [[OUT_LO]], [[REG1]] 311; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 312; CHECK: cmp 313; CHECK: bne 314; CHECK: dmb {{ish$}} 315 316; CHECK-THUMB-LABEL: test11: 317; CHECK-THUMB: dmb {{ish$}} 318; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 319; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 320; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 321; CHECK-THUMB-LE: cmp [[REG1]], r2 322; CHECK-THUMB-BE: cmp [[REG2]], r3 323; CHECK-THUMB: movls.w [[CARRY_LO]], #1 324; CHECK-THUMB-LE: cmp [[REG2]], r3 325; CHECK-THUMB-BE: cmp [[REG1]], r2 326; CHECK-THUMB: movls [[CARRY_HI]], #1 327; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 328; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 329; CHECK-THUMB: cmp [[CARRY_HI]], #0 330; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 331; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 332; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 333; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 334; CHECK-THUMB: cmp 335; CHECK-THUMB: bne 336; CHECK-THUMB: dmb {{ish$}} 337 338 %r = atomicrmw umin i64* %ptr, i64 %val seq_cst 339 ret i64 %r 340} 341 342define i64 @test12(i64* %ptr, i64 %val) { 343; CHECK-LABEL: test12: 344; CHECK: dmb {{ish$}} 345; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 346; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 347; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 348; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 349; CHECK-LE: cmp [[REG1]], r1 350; CHECK-BE: cmp [[REG2]], r2 351; CHECK: movwhi [[CARRY_LO]], #1 352; CHECK-LE: cmp [[REG2]], r2 353; CHECK-BE: cmp [[REG1]], r1 354; CHECK: movwgt [[CARRY_HI]], #1 355; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 356; CHECK: cmp [[CARRY_HI]], #0 357; CHECK: movne [[OUT_HI]], [[REG2]] 358; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 359; CHECK: movne [[OUT_LO]], [[REG1]] 360; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 361; CHECK: cmp 362; CHECK: bne 363; CHECK: dmb {{ish$}} 364 365; CHECK-THUMB-LABEL: test12: 366; CHECK-THUMB: dmb {{ish$}} 367; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 368; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 369; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 370; CHECK-THUMB-LE: cmp [[REG1]], r2 371; CHECK-THUMB-BE: cmp [[REG2]], r3 372; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 373; CHECK-THUMB-LE: cmp [[REG2]], r3 374; CHECK-THUMB-BE: cmp [[REG1]], r2 375; CHECK-THUMB: movgt [[CARRY_HI]], #1 376; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 377; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 378; CHECK-THUMB: cmp [[CARRY_HI]], #0 379; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 380; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 381; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 382; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 383; CHECK-THUMB: cmp 384; CHECK-THUMB: bne 385; CHECK-THUMB: dmb {{ish$}} 386 387 %r = atomicrmw max i64* %ptr, i64 %val seq_cst 388 ret i64 %r 389} 390 391define i64 @test13(i64* %ptr, i64 %val) { 392; CHECK-LABEL: test13: 393; CHECK: dmb {{ish$}} 394; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 395; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 396; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 397; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 398; CHECK-LE: cmp [[REG1]], r1 399; CHECK-BE: cmp [[REG2]], r2 400; CHECK: movwhi [[CARRY_LO]], #1 401; CHECK-LE: cmp [[REG2]], r2 402; CHECK-BE: cmp [[REG1]], r1 403; CHECK: movwhi [[CARRY_HI]], #1 404; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 405; CHECK: cmp [[CARRY_HI]], #0 406; CHECK: movne [[OUT_HI]], [[REG2]] 407; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 408; CHECK: movne [[OUT_LO]], [[REG1]] 409; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 410; CHECK: cmp 411; CHECK: bne 412; CHECK: dmb {{ish$}} 413 414; CHECK-THUMB-LABEL: test13: 415; CHECK-THUMB: dmb {{ish$}} 416; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 417; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 418; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 419; CHECK-THUMB-LE: cmp [[REG1]], r2 420; CHECK-THUMB-BE: cmp [[REG2]], r3 421; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 422; CHECK-THUMB-LE: cmp [[REG2]], r3 423; CHECK-THUMB-BE: cmp [[REG1]], r2 424; CHECK-THUMB: movhi [[CARRY_HI]], #1 425; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 426; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 427; CHECK-THUMB: cmp [[CARRY_HI]], #0 428; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 429; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 430; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 431; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 432; CHECK-THUMB: cmp 433; CHECK-THUMB: bne 434; CHECK-THUMB: dmb {{ish$}} 435 %r = atomicrmw umax i64* %ptr, i64 %val seq_cst 436 ret i64 %r 437} 438 439