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 6 define 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 35 define 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 64 define 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 93 define 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 122 define 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 151 define 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 172 define 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 208 define 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. 229 define 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 250 define 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 293 define 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 336 define 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 379 define 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