1; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s 2; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB 3 4define i64 @test1(i64* %ptr, i64 %val) { 5; CHECK: test1: 6; CHECK: dmb ish 7; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 8; CHECK: adds [[REG3:(r[0-9]?[02468])]], [[REG1]] 9; CHECK: adc [[REG4:(r[0-9]?[13579])]], [[REG2]] 10; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 11; CHECK: cmp 12; CHECK: bne 13; CHECK: dmb ish 14 15; CHECK-THUMB: test1: 16; CHECK-THUMB: dmb ish 17; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 18; CHECK-THUMB: adds.w [[REG3:[a-z0-9]+]], [[REG1]] 19; CHECK-THUMB: adc.w [[REG4:[a-z0-9]+]], [[REG2]] 20; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 21; CHECK-THUMB: cmp 22; CHECK-THUMB: bne 23; CHECK-THUMB: dmb ish 24 25 %r = atomicrmw add i64* %ptr, i64 %val seq_cst 26 ret i64 %r 27} 28 29define i64 @test2(i64* %ptr, i64 %val) { 30; CHECK: test2: 31; CHECK: dmb ish 32; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 33; CHECK: subs [[REG3:(r[0-9]?[02468])]], [[REG1]] 34; CHECK: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]] 35; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 36; CHECK: cmp 37; CHECK: bne 38; CHECK: dmb ish 39 40; CHECK-THUMB: test2: 41; CHECK-THUMB: dmb ish 42; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 43; CHECK-THUMB: subs.w [[REG3:[a-z0-9]+]], [[REG1]] 44; CHECK-THUMB: sbc.w [[REG4:[a-z0-9]+]], [[REG2]] 45; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 46; CHECK-THUMB: cmp 47; CHECK-THUMB: bne 48; CHECK-THUMB: dmb ish 49 50 %r = atomicrmw sub i64* %ptr, i64 %val seq_cst 51 ret i64 %r 52} 53 54define i64 @test3(i64* %ptr, i64 %val) { 55; CHECK: test3: 56; CHECK: dmb ish 57; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 58; CHECK: and [[REG3:(r[0-9]?[02468])]], [[REG1]] 59; CHECK: and [[REG4:(r[0-9]?[13579])]], [[REG2]] 60; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 61; CHECK: cmp 62; CHECK: bne 63; CHECK: dmb ish 64 65; CHECK-THUMB: test3: 66; CHECK-THUMB: dmb ish 67; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 68; CHECK-THUMB: and.w [[REG3:[a-z0-9]+]], [[REG1]] 69; CHECK-THUMB: and.w [[REG4:[a-z0-9]+]], [[REG2]] 70; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 71; CHECK-THUMB: cmp 72; CHECK-THUMB: bne 73; CHECK-THUMB: dmb ish 74 75 %r = atomicrmw and i64* %ptr, i64 %val seq_cst 76 ret i64 %r 77} 78 79define i64 @test4(i64* %ptr, i64 %val) { 80; CHECK: test4: 81; CHECK: dmb ish 82; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 83; CHECK: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] 84; CHECK: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] 85; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 86; CHECK: cmp 87; CHECK: bne 88; CHECK: dmb ish 89 90; CHECK-THUMB: test4: 91; CHECK-THUMB: dmb ish 92; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 93; CHECK-THUMB: orr.w [[REG3:[a-z0-9]+]], [[REG1]] 94; CHECK-THUMB: orr.w [[REG4:[a-z0-9]+]], [[REG2]] 95; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 96; CHECK-THUMB: cmp 97; CHECK-THUMB: bne 98; CHECK-THUMB: dmb ish 99 100 %r = atomicrmw or i64* %ptr, i64 %val seq_cst 101 ret i64 %r 102} 103 104define i64 @test5(i64* %ptr, i64 %val) { 105; CHECK: test5: 106; CHECK: dmb ish 107; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 108; CHECK: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] 109; CHECK: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] 110; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 111; CHECK: cmp 112; CHECK: bne 113; CHECK: dmb ish 114 115; CHECK-THUMB: test5: 116; CHECK-THUMB: dmb ish 117; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 118; CHECK-THUMB: eor.w [[REG3:[a-z0-9]+]], [[REG1]] 119; CHECK-THUMB: eor.w [[REG4:[a-z0-9]+]], [[REG2]] 120; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 121; CHECK-THUMB: cmp 122; CHECK-THUMB: bne 123; CHECK-THUMB: dmb ish 124 125 %r = atomicrmw xor i64* %ptr, i64 %val seq_cst 126 ret i64 %r 127} 128 129define i64 @test6(i64* %ptr, i64 %val) { 130; CHECK: test6: 131; CHECK: dmb ish 132; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 133; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 134; CHECK: cmp 135; CHECK: bne 136; CHECK: dmb ish 137 138; CHECK-THUMB: test6: 139; CHECK-THUMB: dmb ish 140; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 141; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 142; CHECK-THUMB: cmp 143; CHECK-THUMB: bne 144; CHECK-THUMB: dmb ish 145 146 %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst 147 ret i64 %r 148} 149 150define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) { 151; CHECK: test7: 152; CHECK: dmb ish 153; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 154; CHECK: cmp [[REG1]] 155; CHECK: cmpeq [[REG2]] 156; CHECK: bne 157; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 158; CHECK: cmp 159; CHECK: bne 160; CHECK: dmb ish 161 162; CHECK-THUMB: test7: 163; CHECK-THUMB: dmb ish 164; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 165; CHECK-THUMB: cmp [[REG1]] 166; CHECK-THUMB: it eq 167; CHECK-THUMB: cmpeq [[REG2]] 168; CHECK-THUMB: bne 169; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 170; CHECK-THUMB: cmp 171; CHECK-THUMB: bne 172; CHECK-THUMB: dmb ish 173 174 %r = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst 175 ret i64 %r 176} 177 178; Compiles down to cmpxchg 179; FIXME: Should compile to a single ldrexd 180define i64 @test8(i64* %ptr) { 181; CHECK: test8: 182; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 183; CHECK: cmp [[REG1]] 184; CHECK: cmpeq [[REG2]] 185; CHECK: bne 186; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 187; CHECK: cmp 188; CHECK: bne 189; CHECK: dmb ish 190 191; CHECK-THUMB: test8: 192; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 193; CHECK-THUMB: cmp [[REG1]] 194; CHECK-THUMB: it eq 195; CHECK-THUMB: cmpeq [[REG2]] 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 %r = load atomic i64* %ptr seq_cst, align 8 203 ret i64 %r 204} 205 206; Compiles down to atomicrmw xchg; there really isn't any more efficient 207; way to write it. 208define void @test9(i64* %ptr, i64 %val) { 209; CHECK: test9: 210; CHECK: dmb ish 211; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 212; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} 213; CHECK: cmp 214; CHECK: bne 215; CHECK: dmb ish 216 217; CHECK-THUMB: test9: 218; CHECK-THUMB: dmb ish 219; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 220; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} 221; CHECK-THUMB: cmp 222; CHECK-THUMB: bne 223; CHECK-THUMB: dmb ish 224 225 store atomic i64 %val, i64* %ptr seq_cst, align 8 226 ret void 227} 228 229define i64 @test10(i64* %ptr, i64 %val) { 230; CHECK: test10: 231; CHECK: dmb ish 232; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 233; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] 234; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] 235; CHECK: blt 236; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 237; CHECK: cmp 238; CHECK: bne 239; CHECK: dmb ish 240 241; CHECK-THUMB: test10: 242; CHECK-THUMB: dmb ish 243; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 244; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] 245; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] 246; CHECK-THUMB: blt 247; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 248; CHECK-THUMB: cmp 249; CHECK-THUMB: bne 250; CHECK-THUMB: dmb ish 251 252 %r = atomicrmw min i64* %ptr, i64 %val seq_cst 253 ret i64 %r 254} 255 256define i64 @test11(i64* %ptr, i64 %val) { 257; CHECK: test11: 258; CHECK: dmb ish 259; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 260; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] 261; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] 262; CHECK: blo 263; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 264; CHECK: cmp 265; CHECK: bne 266; CHECK: dmb ish 267 268 269; CHECK-THUMB: test11: 270; CHECK-THUMB: dmb ish 271; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 272; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] 273; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] 274; CHECK-THUMB: blo 275; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 276; CHECK-THUMB: cmp 277; CHECK-THUMB: bne 278; CHECK-THUMB: dmb ish 279 280 %r = atomicrmw umin i64* %ptr, i64 %val seq_cst 281 ret i64 %r 282} 283 284define i64 @test12(i64* %ptr, i64 %val) { 285; CHECK: test12: 286; CHECK: dmb ish 287; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 288; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] 289; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] 290; CHECK: bge 291; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 292; CHECK: cmp 293; CHECK: bne 294; CHECK: dmb ish 295 296; CHECK-THUMB: test12: 297; CHECK-THUMB: dmb ish 298; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 299; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] 300; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] 301; CHECK-THUMB: bge 302; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 303; CHECK-THUMB: cmp 304; CHECK-THUMB: bne 305; CHECK-THUMB: dmb ish 306 307 %r = atomicrmw max i64* %ptr, i64 %val seq_cst 308 ret i64 %r 309} 310 311define i64 @test13(i64* %ptr, i64 %val) { 312; CHECK: test13: 313; CHECK: dmb ish 314; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] 315; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] 316; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] 317; CHECK: bhs 318; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 319; CHECK: cmp 320; CHECK: bne 321; CHECK: dmb ish 322 323; CHECK-THUMB: test13: 324; CHECK-THUMB: dmb ish 325; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] 326; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] 327; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] 328; CHECK-THUMB: bhs 329; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] 330; CHECK-THUMB: cmp 331; CHECK-THUMB: bne 332; CHECK-THUMB: dmb ish 333 %r = atomicrmw umax i64* %ptr, i64 %val seq_cst 334 ret i64 %r 335} 336 337