Home | History | Annotate | Download | only in ARM
      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 
      4 define 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 
     29 define 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 
     54 define 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 
     79 define 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 
    104 define 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 
    129 define 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 
    150 define 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
    180 define 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.
    208 define 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 
    229 define 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 
    256 define 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 
    284 define 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 
    311 define 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