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-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 [[CARRY_LO:[a-z0-9]+]], #0 255; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 256; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 257; CHECK-LE: cmp [[REG1]], r1 258; CHECK-BE: cmp [[REG2]], r2 259; CHECK: movwls [[CARRY_LO]], #1 260; CHECK-LE: cmp [[REG2]], r2 261; CHECK-BE: cmp [[REG1]], r1 262; CHECK: movwle [[CARRY_HI]], #1 263; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 264; CHECK: cmp [[CARRY_HI]], #0 265; CHECK: movne [[OUT_HI]], [[REG2]] 266; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 267; CHECK: movne [[OUT_LO]], [[REG1]] 268; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 269; CHECK: cmp 270; CHECK: bne 271; CHECK: dmb {{ish$}} 272 273; CHECK-THUMB-LABEL: test10: 274; CHECK-THUMB: dmb {{ish$}} 275; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 276; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0 277; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0 278; CHECK-THUMB-LE: cmp [[REG1]], r2 279; CHECK-THUMB-BE: cmp [[REG2]], r3 280; CHECK-THUMB: movls.w [[CARRY_LO]], #1 281; CHECK-THUMB-LE: cmp [[REG2]], r3 282; CHECK-THUMB-BE: cmp [[REG1]], r2 283; CHECK-THUMB: movle [[CARRY_HI]], #1 284; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 285; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 286; CHECK-THUMB: cmp [[CARRY_HI]], #0 287; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 288; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 289; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 290; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 291; CHECK-THUMB: cmp 292; CHECK-THUMB: bne 293; CHECK-THUMB: dmb {{ish$}} 294 295 %r = atomicrmw min i64* %ptr, i64 %val seq_cst 296 ret i64 %r 297} 298 299define i64 @test11(i64* %ptr, i64 %val) { 300; CHECK-LABEL: test11: 301; CHECK: dmb {{ish$}} 302; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 303; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 304; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 305; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 306; CHECK-LE: cmp [[REG1]], r1 307; CHECK-BE: cmp [[REG2]], r2 308; CHECK: movwls [[CARRY_LO]], #1 309; CHECK-LE: cmp [[REG2]], r2 310; CHECK-BE: cmp [[REG1]], r1 311; CHECK: movwls [[CARRY_HI]], #1 312; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 313; CHECK: cmp [[CARRY_HI]], #0 314; CHECK: movne [[OUT_HI]], [[REG2]] 315; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 316; CHECK: movne [[OUT_LO]], [[REG1]] 317; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 318; CHECK: cmp 319; CHECK: bne 320; CHECK: dmb {{ish$}} 321 322; CHECK-THUMB-LABEL: test11: 323; CHECK-THUMB: dmb {{ish$}} 324; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 325; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 326; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 327; CHECK-THUMB-LE: cmp [[REG1]], r2 328; CHECK-THUMB-BE: cmp [[REG2]], r3 329; CHECK-THUMB: movls.w [[CARRY_LO]], #1 330; CHECK-THUMB-LE: cmp [[REG2]], r3 331; CHECK-THUMB-BE: cmp [[REG1]], r2 332; CHECK-THUMB: movls [[CARRY_HI]], #1 333; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 334; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 335; CHECK-THUMB: cmp [[CARRY_HI]], #0 336; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 337; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 338; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 339; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 340; CHECK-THUMB: cmp 341; CHECK-THUMB: bne 342; CHECK-THUMB: dmb {{ish$}} 343 344 %r = atomicrmw umin i64* %ptr, i64 %val seq_cst 345 ret i64 %r 346} 347 348define i64 @test12(i64* %ptr, i64 %val) { 349; CHECK-LABEL: test12: 350; CHECK: dmb {{ish$}} 351; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 352; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 353; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 354; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 355; CHECK-LE: cmp [[REG1]], r1 356; CHECK-BE: cmp [[REG2]], r2 357; CHECK: movwhi [[CARRY_LO]], #1 358; CHECK-LE: cmp [[REG2]], r2 359; CHECK-BE: cmp [[REG1]], r1 360; CHECK: movwgt [[CARRY_HI]], #1 361; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 362; CHECK: cmp [[CARRY_HI]], #0 363; CHECK: movne [[OUT_HI]], [[REG2]] 364; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 365; CHECK: movne [[OUT_LO]], [[REG1]] 366; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 367; CHECK: cmp 368; CHECK: bne 369; CHECK: dmb {{ish$}} 370 371; CHECK-THUMB-LABEL: test12: 372; CHECK-THUMB: dmb {{ish$}} 373; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 374; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 375; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 376; CHECK-THUMB-LE: cmp [[REG1]], r2 377; CHECK-THUMB-BE: cmp [[REG2]], r3 378; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 379; CHECK-THUMB-LE: cmp [[REG2]], r3 380; CHECK-THUMB-BE: cmp [[REG1]], r2 381; CHECK-THUMB: movgt [[CARRY_HI]], #1 382; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 383; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 384; CHECK-THUMB: cmp [[CARRY_HI]], #0 385; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 386; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 387; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 388; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 389; CHECK-THUMB: cmp 390; CHECK-THUMB: bne 391; CHECK-THUMB: dmb {{ish$}} 392 393 %r = atomicrmw max i64* %ptr, i64 %val seq_cst 394 ret i64 %r 395} 396 397define i64 @test13(i64* %ptr, i64 %val) { 398; CHECK-LABEL: test13: 399; CHECK: dmb {{ish$}} 400; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 401; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 402; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 403; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 404; CHECK-LE: cmp [[REG1]], r1 405; CHECK-BE: cmp [[REG2]], r2 406; CHECK: movwhi [[CARRY_LO]], #1 407; CHECK-LE: cmp [[REG2]], r2 408; CHECK-BE: cmp [[REG1]], r1 409; CHECK: movwhi [[CARRY_HI]], #1 410; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] 411; CHECK: cmp [[CARRY_HI]], #0 412; CHECK: movne [[OUT_HI]], [[REG2]] 413; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1 414; CHECK: movne [[OUT_LO]], [[REG1]] 415; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 416; CHECK: cmp 417; CHECK: bne 418; CHECK: dmb {{ish$}} 419 420; CHECK-THUMB-LABEL: test13: 421; CHECK-THUMB: dmb {{ish$}} 422; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 423; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 424; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 425; CHECK-THUMB-LE: cmp [[REG1]], r2 426; CHECK-THUMB-BE: cmp [[REG2]], r3 427; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 428; CHECK-THUMB-LE: cmp [[REG2]], r3 429; CHECK-THUMB-BE: cmp [[REG1]], r2 430; CHECK-THUMB: movhi [[CARRY_HI]], #1 431; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] 432; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 433; CHECK-THUMB: cmp [[CARRY_HI]], #0 434; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2 435; CHECK-THUMB: movne [[OUT_HI]], [[REG2]] 436; CHECK-THUMB: movne [[OUT_LO]], [[REG1]] 437; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 438; CHECK-THUMB: cmp 439; CHECK-THUMB: bne 440; CHECK-THUMB: dmb {{ish$}} 441 %r = atomicrmw umax i64* %ptr, i64 %val seq_cst 442 ret i64 %r 443} 444 445