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-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-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 [[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 299 define 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 348 define 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 397 define 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