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 | 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-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 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: 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. 223 define 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 244 define 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 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 [[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 342 define 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 391 define 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