OLD | NEW |
1 ; This tests each of the supported NaCl atomic instructions for every | 1 ; This tests each of the supported NaCl atomic instructions for every |
2 ; size allowed. | 2 ; size allowed. |
3 | 3 |
4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ | 4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ |
5 ; RUN: -allow-externally-defined-symbols | FileCheck %s | 5 ; RUN: -allow-externally-defined-symbols | FileCheck %s |
6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ | 6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ |
7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s | 7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s |
8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \ | 8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \ |
9 ; RUN: -allow-externally-defined-symbols | FileCheck %s | 9 ; RUN: -allow-externally-defined-symbols | FileCheck %s |
10 | 10 |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) | 239 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) |
240 ret void | 240 ret void |
241 } | 241 } |
242 ; CHECK-LABEL: test_atomic_store_64_const | 242 ; CHECK-LABEL: test_atomic_store_64_const |
243 ; CHECK: mov {{.*}},0x73ce2ff2 | 243 ; CHECK: mov {{.*}},0x73ce2ff2 |
244 ; CHECK: mov {{.*}},0xb3a | 244 ; CHECK: mov {{.*}},0xb3a |
245 ; CHECK: movq x{{.*}},QWORD | 245 ; CHECK: movq x{{.*}},QWORD |
246 ; CHECK: movq QWORD {{.*}},x{{.*}} | 246 ; CHECK: movq QWORD {{.*}},x{{.*}} |
247 ; CHECK: mfence | 247 ; CHECK: mfence |
248 ; ARM32-LABEL: test_atomic_store_64_const | 248 ; ARM32-LABEL: test_atomic_store_64_const |
249 ; ARM32: dmb | |
250 ; ARM32: movw [[T0:r[0-9]+]], #12274 | 249 ; ARM32: movw [[T0:r[0-9]+]], #12274 |
251 ; ARM32: movt [[T0]], #29646 | 250 ; ARM32: movt [[T0]], #29646 |
252 ; ARM32: movw r{{[0-9]+}}, #2874 | 251 ; ARM32: movw r{{[0-9]+}}, #2874 |
| 252 ; ARM32: dmb |
253 ; ARM32: .L[[RETRY:.*]]: | 253 ; ARM32: .L[[RETRY:.*]]: |
254 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] | 254 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] |
255 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] | 255 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] |
256 ; ARM32: cmp [[S]], #0 | 256 ; ARM32: cmp [[S]], #0 |
257 ; ARM32: bne .L[[RETRY]] | 257 ; ARM32: bne .L[[RETRY]] |
258 ; ARM32: dmb | 258 ; ARM32: dmb |
259 | 259 |
260 ;;; RMW | 260 ;;; RMW |
261 | 261 |
262 ;; add | 262 ;; add |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 ; CHECK: adc ecx,{{.*e.[^x]}} | 335 ; CHECK: adc ecx,{{.*e.[^x]}} |
336 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). | 336 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). |
337 ; It can be esi, edi, or ebp though, for example (so we need to be careful | 337 ; It can be esi, edi, or ebp though, for example (so we need to be careful |
338 ; about rejecting eb* and ed*.) | 338 ; about rejecting eb* and ed*.) |
339 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 339 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
340 ; CHECK: jne [[LABEL]] | 340 ; CHECK: jne [[LABEL]] |
341 ; ARM32-LABEL: test_atomic_rmw_add_64 | 341 ; ARM32-LABEL: test_atomic_rmw_add_64 |
342 ; ARM32: dmb | 342 ; ARM32: dmb |
343 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 343 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
344 ; ARM32: adds | 344 ; ARM32: adds |
345 ; ARM32-NEXT: adc | 345 ; ARM32: adc |
346 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 346 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
347 ; ARM32: bne | 347 ; ARM32: bne |
348 ; ARM32: dmb | 348 ; ARM32: dmb |
349 | 349 |
350 ; Same test as above, but with a global address to test FakeUse issues. | 350 ; Same test as above, but with a global address to test FakeUse issues. |
351 define internal i64 @test_atomic_rmw_add_64_global(i64 %v) { | 351 define internal i64 @test_atomic_rmw_add_64_global(i64 %v) { |
352 entry: | 352 entry: |
353 %ptr = bitcast [8 x i8]* @SzGlobal64 to i64* | 353 %ptr = bitcast [8 x i8]* @SzGlobal64 to i64* |
354 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) | 354 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) |
355 ret i64 %a | 355 ret i64 %a |
356 } | 356 } |
357 ; CHECK-LABEL: test_atomic_rmw_add_64_global | 357 ; CHECK-LABEL: test_atomic_rmw_add_64_global |
358 ; ARM32-LABEL: test_atomic_rmw_add_64_global | 358 ; ARM32-LABEL: test_atomic_rmw_add_64_global |
359 ; ARM32: dmb | 359 ; ARM32: dmb |
360 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 360 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
361 ; ARM32: adds | 361 ; ARM32: adds |
362 ; ARM32-NEXT: adc | 362 ; ARM32: adc |
363 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 363 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
364 ; ARM32: bne | 364 ; ARM32: bne |
365 ; ARM32: dmb | 365 ; ARM32: dmb |
366 | 366 |
367 ; Test with some more register pressure. When we have an alloca, ebp is | 367 ; Test with some more register pressure. When we have an alloca, ebp is |
368 ; used to manage the stack frame, so it cannot be used as a register either. | 368 ; used to manage the stack frame, so it cannot be used as a register either. |
369 declare void @use_ptr(i32 %iptr) | 369 declare void @use_ptr(i32 %iptr) |
370 | 370 |
371 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) { | 371 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) { |
372 entry: | 372 entry: |
(...skipping 20 matching lines...) Expand all Loading... |
393 ; It also cannot be ebp since we use that for alloca. Also make sure it's | 393 ; It also cannot be ebp since we use that for alloca. Also make sure it's |
394 ; not esp, since that's the stack pointer and mucking with it will break | 394 ; not esp, since that's the stack pointer and mucking with it will break |
395 ; the later use_ptr function call. | 395 ; the later use_ptr function call. |
396 ; That pretty much leaves esi, or edi as the only viable registers. | 396 ; That pretty much leaves esi, or edi as the only viable registers. |
397 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] | 397 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] |
398 ; CHECK: call {{.*}} R_{{.*}} use_ptr | 398 ; CHECK: call {{.*}} R_{{.*}} use_ptr |
399 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca | 399 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca |
400 ; ARM32: dmb | 400 ; ARM32: dmb |
401 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 401 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
402 ; ARM32: adds | 402 ; ARM32: adds |
403 ; ARM32-NEXT: adc | 403 ; ARM32: adc |
404 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 404 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
405 ; ARM32: bne | 405 ; ARM32: bne |
406 ; ARM32: dmb | 406 ; ARM32: dmb |
407 | 407 |
408 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) { | 408 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) { |
409 entry: | 409 entry: |
410 %ptr = inttoptr i32 %iptr to i32* | 410 %ptr = inttoptr i32 %iptr to i32* |
411 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) | 411 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) |
412 ret i32 %v | 412 ret i32 %v |
413 } | 413 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 450 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
451 ; CHECK: add ebx,{{.*e.[^x]}} | 451 ; CHECK: add ebx,{{.*e.[^x]}} |
452 ; CHECK: mov ecx,edx | 452 ; CHECK: mov ecx,edx |
453 ; CHECK: adc ecx,{{.*e.[^x]}} | 453 ; CHECK: adc ecx,{{.*e.[^x]}} |
454 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 454 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
455 ; CHECK: jne [[LABEL]] | 455 ; CHECK: jne [[LABEL]] |
456 ; ARM32-LABEL: test_atomic_rmw_add_64_loop | 456 ; ARM32-LABEL: test_atomic_rmw_add_64_loop |
457 ; ARM32: dmb | 457 ; ARM32: dmb |
458 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 458 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
459 ; ARM32: adds | 459 ; ARM32: adds |
460 ; ARM32-NEXT: adc | 460 ; ARM32: adc |
461 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 461 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
462 ; ARM32: bne | 462 ; ARM32: bne |
463 ; ARM32: dmb | 463 ; ARM32: dmb |
464 ; ARM32: b | 464 ; ARM32: b |
465 | 465 |
466 ;; sub | 466 ;; sub |
467 | 467 |
468 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { | 468 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { |
469 entry: | 469 entry: |
470 %trunc = trunc i32 %v to i8 | 470 %trunc = trunc i32 %v to i8 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 536 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
537 ; CHECK: sub ebx,{{.*e.[^x]}} | 537 ; CHECK: sub ebx,{{.*e.[^x]}} |
538 ; CHECK: mov ecx,edx | 538 ; CHECK: mov ecx,edx |
539 ; CHECK: sbb ecx,{{.*e.[^x]}} | 539 ; CHECK: sbb ecx,{{.*e.[^x]}} |
540 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 540 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
541 ; CHECK: jne [[LABEL]] | 541 ; CHECK: jne [[LABEL]] |
542 ; ARM32-LABEL: test_atomic_rmw_sub_64 | 542 ; ARM32-LABEL: test_atomic_rmw_sub_64 |
543 ; ARM32: dmb | 543 ; ARM32: dmb |
544 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 544 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
545 ; ARM32: subs | 545 ; ARM32: subs |
546 ; ARM32-NEXT: sbc | 546 ; ARM32: sbc |
547 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 547 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
548 ; ARM32: bne | 548 ; ARM32: bne |
549 ; ARM32: dmb | 549 ; ARM32: dmb |
550 | 550 |
551 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) { | 551 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) { |
552 entry: | 552 entry: |
553 %ptr = inttoptr i32 %iptr to i32* | 553 %ptr = inttoptr i32 %iptr to i32* |
554 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) | 554 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) |
555 ret i32 %v | 555 ret i32 %v |
556 } | 556 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) { | 595 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) { |
596 entry: | 596 entry: |
597 %trunc = trunc i32 %v to i8 | 597 %trunc = trunc i32 %v to i8 |
598 %ptr = bitcast [1 x i8]* @SzGlobal8 to i8* | 598 %ptr = bitcast [1 x i8]* @SzGlobal8 to i8* |
599 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) | 599 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) |
600 %a_ext = zext i8 %a to i32 | 600 %a_ext = zext i8 %a to i32 |
601 ret i32 %a_ext | 601 ret i32 %a_ext |
602 } | 602 } |
603 ; CHECK-LABEL: test_atomic_rmw_or_8_global | 603 ; CHECK-LABEL: test_atomic_rmw_or_8_global |
604 ; ARM32-LABEL: test_atomic_rmw_or_8_global | 604 ; ARM32-LABEL: test_atomic_rmw_or_8_global |
| 605 ; ARM32: dmb |
605 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8 | 606 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8 |
606 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8 | 607 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8 |
607 ; ARM32: dmb | |
608 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 608 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
609 ; ARM32: orr | 609 ; ARM32: orr |
610 ; ARM32: strexb | 610 ; ARM32: strexb |
611 ; ARM32: bne | 611 ; ARM32: bne |
612 ; ARM32: dmb | 612 ; ARM32: dmb |
613 | 613 |
614 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { | 614 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { |
615 entry: | 615 entry: |
616 %trunc = trunc i32 %v to i16 | 616 %trunc = trunc i32 %v to i16 |
617 %ptr = inttoptr i32 %iptr to i16* | 617 %ptr = inttoptr i32 %iptr to i16* |
(...skipping 18 matching lines...) Expand all Loading... |
636 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) { | 636 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) { |
637 entry: | 637 entry: |
638 %trunc = trunc i32 %v to i16 | 638 %trunc = trunc i32 %v to i16 |
639 %ptr = bitcast [2 x i8]* @SzGlobal16 to i16* | 639 %ptr = bitcast [2 x i8]* @SzGlobal16 to i16* |
640 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) | 640 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) |
641 %a_ext = zext i16 %a to i32 | 641 %a_ext = zext i16 %a to i32 |
642 ret i32 %a_ext | 642 ret i32 %a_ext |
643 } | 643 } |
644 ; CHECK-LABEL: test_atomic_rmw_or_16_global | 644 ; CHECK-LABEL: test_atomic_rmw_or_16_global |
645 ; ARM32-LABEL: test_atomic_rmw_or_16_global | 645 ; ARM32-LABEL: test_atomic_rmw_or_16_global |
| 646 ; ARM32: dmb |
646 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16 | 647 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16 |
647 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16 | 648 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16 |
648 ; ARM32: dmb | |
649 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 649 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
650 ; ARM32: orr | 650 ; ARM32: orr |
651 ; ARM32: strexh | 651 ; ARM32: strexh |
652 ; ARM32: bne | 652 ; ARM32: bne |
653 ; ARM32: dmb | 653 ; ARM32: dmb |
654 | 654 |
655 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { | 655 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { |
656 entry: | 656 entry: |
657 %ptr = inttoptr i32 %iptr to i32* | 657 %ptr = inttoptr i32 %iptr to i32* |
658 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) | 658 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
(...skipping 14 matching lines...) Expand all Loading... |
673 | 673 |
674 ; Same test as above, but with a global address to test FakeUse issues. | 674 ; Same test as above, but with a global address to test FakeUse issues. |
675 define internal i32 @test_atomic_rmw_or_32_global(i32 %v) { | 675 define internal i32 @test_atomic_rmw_or_32_global(i32 %v) { |
676 entry: | 676 entry: |
677 %ptr = bitcast [4 x i8]* @SzGlobal32 to i32* | 677 %ptr = bitcast [4 x i8]* @SzGlobal32 to i32* |
678 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) | 678 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
679 ret i32 %a | 679 ret i32 %a |
680 } | 680 } |
681 ; CHECK-LABEL: test_atomic_rmw_or_32_global | 681 ; CHECK-LABEL: test_atomic_rmw_or_32_global |
682 ; ARM32-LABEL: test_atomic_rmw_or_32_global | 682 ; ARM32-LABEL: test_atomic_rmw_or_32_global |
| 683 ; ARM32: dmb |
683 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32 | 684 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32 |
684 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32 | 685 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32 |
685 ; ARM32: dmb | |
686 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 686 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
687 ; ARM32: orr | 687 ; ARM32: orr |
688 ; ARM32: strex | 688 ; ARM32: strex |
689 ; ARM32: bne | 689 ; ARM32: bne |
690 ; ARM32: dmb | 690 ; ARM32: dmb |
691 | 691 |
692 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { | 692 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { |
693 entry: | 693 entry: |
694 %ptr = inttoptr i32 %iptr to i64* | 694 %ptr = inttoptr i32 %iptr to i64* |
695 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) | 695 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) |
696 ret i64 %a | 696 ret i64 %a |
697 } | 697 } |
698 ; CHECK-LABEL: test_atomic_rmw_or_64 | 698 ; CHECK-LABEL: test_atomic_rmw_or_64 |
699 ; CHECK: push ebx | 699 ; CHECK: push ebx |
700 ; CHECK: mov eax,DWORD PTR [{{.*}}] | 700 ; CHECK: mov eax,DWORD PTR [{{.*}}] |
701 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] | 701 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] |
702 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 702 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
703 ; CHECK: or ebx,{{.*e.[^x]}} | 703 ; CHECK: or ebx,{{.*e.[^x]}} |
704 ; CHECK: mov ecx,edx | 704 ; CHECK: mov ecx,edx |
705 ; CHECK: or ecx,{{.*e.[^x]}} | 705 ; CHECK: or ecx,{{.*e.[^x]}} |
706 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 706 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
707 ; CHECK: jne [[LABEL]] | 707 ; CHECK: jne [[LABEL]] |
708 ; ARM32-LABEL: test_atomic_rmw_or_64 | 708 ; ARM32-LABEL: test_atomic_rmw_or_64 |
709 ; ARM32: dmb | 709 ; ARM32: dmb |
710 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 710 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
711 ; ARM32: orr | 711 ; ARM32: orr |
712 ; ARM32-NEXT: orr | 712 ; ARM32: orr |
713 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 713 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
714 ; ARM32: bne | 714 ; ARM32: bne |
715 ; ARM32: dmb | 715 ; ARM32: dmb |
716 | 716 |
717 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) { | 717 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) { |
718 entry: | 718 entry: |
719 %ptr = inttoptr i32 %iptr to i32* | 719 %ptr = inttoptr i32 %iptr to i32* |
720 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) | 720 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
721 ret i32 %v | 721 ret i32 %v |
722 } | 722 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 812 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
813 ; CHECK: and ebx,{{.*e.[^x]}} | 813 ; CHECK: and ebx,{{.*e.[^x]}} |
814 ; CHECK: mov ecx,edx | 814 ; CHECK: mov ecx,edx |
815 ; CHECK: and ecx,{{.*e.[^x]}} | 815 ; CHECK: and ecx,{{.*e.[^x]}} |
816 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 816 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
817 ; CHECK: jne [[LABEL]] | 817 ; CHECK: jne [[LABEL]] |
818 ; ARM32-LABEL: test_atomic_rmw_and_64 | 818 ; ARM32-LABEL: test_atomic_rmw_and_64 |
819 ; ARM32: dmb | 819 ; ARM32: dmb |
820 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 820 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
821 ; ARM32: and | 821 ; ARM32: and |
822 ; ARM32-NEXT: and | 822 ; ARM32: and |
823 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 823 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
824 ; ARM32: bne | 824 ; ARM32: bne |
825 ; ARM32: dmb | 825 ; ARM32: dmb |
826 | 826 |
827 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) { | 827 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) { |
828 entry: | 828 entry: |
829 %ptr = inttoptr i32 %iptr to i32* | 829 %ptr = inttoptr i32 %iptr to i32* |
830 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) | 830 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) |
831 ret i32 %v | 831 ret i32 %v |
832 } | 832 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 ; CHECK: mov ebx,eax | 920 ; CHECK: mov ebx,eax |
921 ; CHECK: or ebx,{{.*e.[^x]}} | 921 ; CHECK: or ebx,{{.*e.[^x]}} |
922 ; CHECK: mov ecx,edx | 922 ; CHECK: mov ecx,edx |
923 ; CHECK: or ecx,{{.*e.[^x]}} | 923 ; CHECK: or ecx,{{.*e.[^x]}} |
924 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 924 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
925 ; CHECK: jne | 925 ; CHECK: jne |
926 ; ARM32-LABEL: test_atomic_rmw_xor_64 | 926 ; ARM32-LABEL: test_atomic_rmw_xor_64 |
927 ; ARM32: dmb | 927 ; ARM32: dmb |
928 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 928 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
929 ; ARM32: eor | 929 ; ARM32: eor |
930 ; ARM32-NEXT: eor | 930 ; ARM32: eor |
931 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 931 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
932 ; ARM32: bne | 932 ; ARM32: bne |
933 ; ARM32: dmb | 933 ; ARM32: dmb |
934 | 934 |
935 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) { | 935 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) { |
936 entry: | 936 entry: |
937 %ptr = inttoptr i32 %iptr to i32* | 937 %ptr = inttoptr i32 %iptr to i32* |
938 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) | 938 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) |
939 ret i32 %v | 939 ret i32 %v |
940 } | 940 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 } | 1060 } |
1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 | 1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 |
1062 ; CHECK: mov eax,{{.*}} | 1062 ; CHECK: mov eax,{{.*}} |
1063 ; Need to check that eax isn't used as the address register or the desired. | 1063 ; Need to check that eax isn't used as the address register or the desired. |
1064 ; since it is already used as the *expected* register. | 1064 ; since it is already used as the *expected* register. |
1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l | 1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l |
1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 | 1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 |
1067 ; ARM32: dmb | 1067 ; ARM32: dmb |
1068 ; ARM32: ldrexb | 1068 ; ARM32: ldrexb |
1069 ; ARM32: cmp | 1069 ; ARM32: cmp |
| 1070 ; ARM32: {{strb|mov}} |
1070 ; ARM32: strexbeq | 1071 ; ARM32: strexbeq |
1071 ; ARM32: {{strb|mov}}ne | |
1072 ; ARM32: cmpeq | 1072 ; ARM32: cmpeq |
1073 ; ARM32: bne | 1073 ; ARM32: bne |
1074 ; ARM32: dmb | 1074 ; ARM32: dmb |
1075 | 1075 |
1076 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, | 1076 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, |
1077 i32 %desired) { | 1077 i32 %desired) { |
1078 entry: | 1078 entry: |
1079 %trunc_exp = trunc i32 %expected to i16 | 1079 %trunc_exp = trunc i32 %expected to i16 |
1080 %trunc_des = trunc i32 %desired to i16 | 1080 %trunc_des = trunc i32 %desired to i16 |
1081 %ptr = inttoptr i32 %iptr to i16* | 1081 %ptr = inttoptr i32 %iptr to i16* |
1082 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, | 1082 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, |
1083 i16 %trunc_des, i32 6, i32 6) | 1083 i16 %trunc_des, i32 6, i32 6) |
1084 %old_ext = zext i16 %old to i32 | 1084 %old_ext = zext i16 %old to i32 |
1085 ret i32 %old_ext | 1085 ret i32 %old_ext |
1086 } | 1086 } |
1087 ; CHECK-LABEL: test_atomic_cmpxchg_16 | 1087 ; CHECK-LABEL: test_atomic_cmpxchg_16 |
1088 ; CHECK: mov {{ax|eax}},{{.*}} | 1088 ; CHECK: mov {{ax|eax}},{{.*}} |
1089 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x | 1089 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x |
1090 ; ARM32-LABEL: test_atomic_cmpxchg_16 | 1090 ; ARM32-LABEL: test_atomic_cmpxchg_16 |
1091 ; ARM32: dmb | 1091 ; ARM32: dmb |
1092 ; ARM32: ldrexh | 1092 ; ARM32: ldrexh |
1093 ; ARM32: cmp | 1093 ; ARM32: cmp |
| 1094 ; ARM32: {{strh|mov}} |
1094 ; ARM32: strexheq | 1095 ; ARM32: strexheq |
1095 ; ARM32: {{strh|mov}}ne | |
1096 ; ARM32: cmpeq | 1096 ; ARM32: cmpeq |
1097 ; ARM32: bne | 1097 ; ARM32: bne |
1098 ; ARM32: dmb | 1098 ; ARM32: dmb |
1099 | 1099 |
1100 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, | 1100 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, |
1101 i32 %desired) { | 1101 i32 %desired) { |
1102 entry: | 1102 entry: |
1103 %ptr = inttoptr i32 %iptr to i32* | 1103 %ptr = inttoptr i32 %iptr to i32* |
1104 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1104 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
1105 i32 %desired, i32 6, i32 6) | 1105 i32 %desired, i32 6, i32 6) |
1106 ret i32 %old | 1106 ret i32 %old |
1107 } | 1107 } |
1108 ; CHECK-LABEL: test_atomic_cmpxchg_32 | 1108 ; CHECK-LABEL: test_atomic_cmpxchg_32 |
1109 ; CHECK: mov eax,{{.*}} | 1109 ; CHECK: mov eax,{{.*}} |
1110 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} | 1110 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} |
1111 ; ARM32-LABEL: test_atomic_cmpxchg_32 | 1111 ; ARM32-LABEL: test_atomic_cmpxchg_32 |
1112 ; ARM32: dmb | 1112 ; ARM32: dmb |
1113 ; ARM32: ldrex | 1113 ; ARM32: ldrex |
1114 ; ARM32: cmp | 1114 ; ARM32: cmp |
| 1115 ; ARM32: {{str|mov}} |
1115 ; ARM32: strexeq | 1116 ; ARM32: strexeq |
1116 ; ARM32: {{str|mov}}ne | |
1117 ; ARM32: cmpeq | 1117 ; ARM32: cmpeq |
1118 ; ARM32: bne | 1118 ; ARM32: bne |
1119 ; ARM32: dmb | 1119 ; ARM32: dmb |
1120 | 1120 |
1121 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, | 1121 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, |
1122 i64 %desired) { | 1122 i64 %desired) { |
1123 entry: | 1123 entry: |
1124 %ptr = inttoptr i32 %iptr to i64* | 1124 %ptr = inttoptr i32 %iptr to i64* |
1125 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1125 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
1126 i64 %desired, i32 6, i32 6) | 1126 i64 %desired, i32 6, i32 6) |
1127 ret i64 %old | 1127 ret i64 %old |
1128 } | 1128 } |
1129 ; CHECK-LABEL: test_atomic_cmpxchg_64 | 1129 ; CHECK-LABEL: test_atomic_cmpxchg_64 |
1130 ; CHECK: push ebx | 1130 ; CHECK: push ebx |
1131 ; CHECK-DAG: mov edx | 1131 ; CHECK-DAG: mov edx |
1132 ; CHECK-DAG: mov eax | 1132 ; CHECK-DAG: mov eax |
1133 ; CHECK-DAG: mov ecx | 1133 ; CHECK-DAG: mov ecx |
1134 ; CHECK-DAG: mov ebx | 1134 ; CHECK-DAG: mov ebx |
1135 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1135 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
1136 ; edx and eax are already the return registers, so they don't actually | 1136 ; edx and eax are already the return registers, so they don't actually |
1137 ; need to be reshuffled via movs. The next test stores the result | 1137 ; need to be reshuffled via movs. The next test stores the result |
1138 ; somewhere, so in that case they do need to be mov'ed. | 1138 ; somewhere, so in that case they do need to be mov'ed. |
1139 ; ARM32-LABEL: test_atomic_cmpxchg_64 | 1139 ; ARM32-LABEL: test_atomic_cmpxchg_64 |
1140 ; ARM32: dmb | 1140 ; ARM32: dmb |
1141 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1141 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
1142 ; ARM32: cmp | 1142 ; ARM32: cmp |
1143 ; ARM32-NEXT: cmpeq | 1143 ; ARM32: cmpeq |
| 1144 ; ARM32: mov |
| 1145 ; ARM32: mov |
1144 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1146 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
1145 ; ARM32: {{str|mov}}ne | |
1146 ; ARM32: {{str|mov}}ne | |
1147 ; ARM32: cmpeq | 1147 ; ARM32: cmpeq |
1148 ; ARM32: bne | 1148 ; ARM32: bne |
1149 ; ARM32: dmb | 1149 ; ARM32: dmb |
1150 | 1150 |
1151 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { | 1151 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { |
1152 entry: | 1152 entry: |
1153 %ptr = inttoptr i32 %iptr to i64* | 1153 %ptr = inttoptr i32 %iptr to i64* |
1154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, | 1154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, |
1155 i64 %desired, i32 6, i32 6) | 1155 i64 %desired, i32 6, i32 6) |
1156 ret i64 %old | 1156 ret i64 %old |
1157 } | 1157 } |
1158 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef | 1158 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef |
1159 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1159 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
1160 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef | 1160 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef |
1161 ; ARM32: mov r{{[0-9]+}}, #0 | 1161 ; ARM32: mov r{{[0-9]+}}, #0 |
1162 ; ARM32: mov r{{[0-9]+}}, #0 | 1162 ; ARM32: mov r{{[0-9]+}}, #0 |
1163 ; ARM32: dmb | 1163 ; ARM32: dmb |
1164 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1164 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
1165 ; ARM32: cmp | 1165 ; ARM32: cmp |
1166 ; ARM32-NEXT: cmpeq | 1166 ; ARM32: cmpeq |
| 1167 ; ARM32: mov |
| 1168 ; ARM32: mov |
1167 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1169 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
1168 ; ARM32: {{str|mov}}ne | |
1169 ; ARM32: {{str|mov}}ne | |
1170 ; ARM32: cmpeq | 1170 ; ARM32: cmpeq |
1171 ; ARM32: bne | 1171 ; ARM32: bne |
1172 ; ARM32: dmb | 1172 ; ARM32: dmb |
1173 | 1173 |
1174 ; Test a case where %old really does need to be copied out of edx:eax. | 1174 ; Test a case where %old really does need to be copied out of edx:eax. |
1175 define internal void @test_atomic_cmpxchg_64_store( | 1175 define internal void @test_atomic_cmpxchg_64_store( |
1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { | 1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { |
1177 entry: | 1177 entry: |
1178 %ptr = inttoptr i32 %iptr to i64* | 1178 %ptr = inttoptr i32 %iptr to i64* |
1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
1180 i64 %desired, i32 6, i32 6) | 1180 i64 %desired, i32 6, i32 6) |
1181 %__6 = inttoptr i32 %ret_iptr to i64* | 1181 %__6 = inttoptr i32 %ret_iptr to i64* |
1182 store i64 %old, i64* %__6, align 1 | 1182 store i64 %old, i64* %__6, align 1 |
1183 ret void | 1183 ret void |
1184 } | 1184 } |
1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store | 1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store |
1186 ; CHECK: push ebx | 1186 ; CHECK: push ebx |
1187 ; CHECK-DAG: mov edx | 1187 ; CHECK-DAG: mov edx |
1188 ; CHECK-DAG: mov eax | 1188 ; CHECK-DAG: mov eax |
1189 ; CHECK-DAG: mov ecx | 1189 ; CHECK-DAG: mov ecx |
1190 ; CHECK-DAG: mov ebx | 1190 ; CHECK-DAG: mov ebx |
1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
1192 ; CHECK-DAG: mov {{.*}},edx | 1192 ; CHECK-DAG: mov {{.*}},edx |
1193 ; CHECK-DAG: mov {{.*}},eax | 1193 ; CHECK-DAG: mov {{.*}},eax |
1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store | 1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store |
1195 ; ARM32: dmb | 1195 ; ARM32: dmb |
1196 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1196 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
1197 ; ARM32: cmp | 1197 ; ARM32: cmp |
1198 ; ARM32-NEXT: cmpeq | 1198 ; ARM32: cmpeq |
| 1199 ; ARM32: mov |
| 1200 ; ARM32: mov |
1199 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1201 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
1200 ; ARM32: {{str|mov}}ne | |
1201 ; ARM32: {{str|mov}}ne | |
1202 ; ARM32: cmpeq | 1202 ; ARM32: cmpeq |
1203 ; ARM32: bne | 1203 ; ARM32: bne |
1204 ; ARM32: dmb | 1204 ; ARM32: dmb |
1205 ; ARM32: str | 1205 ; ARM32: str |
1206 ; ARM32: str | 1206 ; ARM32: str |
1207 | 1207 |
1208 ; Test with some more register pressure. When we have an alloca, ebp is | 1208 ; Test with some more register pressure. When we have an alloca, ebp is |
1209 ; used to manage the stack frame, so it cannot be used as a register either. | 1209 ; used to manage the stack frame, so it cannot be used as a register either. |
1210 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, | 1210 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, |
1211 i64 %desired) { | 1211 i64 %desired) { |
(...skipping 22 matching lines...) Expand all Loading... |
1234 ; It also cannot be ebp since we use that for alloca. Also make sure it's | 1234 ; It also cannot be ebp since we use that for alloca. Also make sure it's |
1235 ; not esp, since that's the stack pointer and mucking with it will break | 1235 ; not esp, since that's the stack pointer and mucking with it will break |
1236 ; the later use_ptr function call. | 1236 ; the later use_ptr function call. |
1237 ; That pretty much leaves esi, or edi as the only viable registers. | 1237 ; That pretty much leaves esi, or edi as the only viable registers. |
1238 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] | 1238 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] |
1239 ; CHECK: call {{.*}} R_{{.*}} use_ptr | 1239 ; CHECK: call {{.*}} R_{{.*}} use_ptr |
1240 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca | 1240 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca |
1241 ; ARM32: dmb | 1241 ; ARM32: dmb |
1242 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1242 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
1243 ; ARM32: cmp | 1243 ; ARM32: cmp |
1244 ; ARM32-NEXT: cmpeq | 1244 ; ARM32: cmpeq |
| 1245 ; ARM32: mov |
| 1246 ; ARM32: mov |
1245 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1247 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
1246 ; ARM32: {{str|mov}}ne | |
1247 ; ARM32: {{str|mov}}ne | |
1248 ; ARM32: cmpeq | 1248 ; ARM32: cmpeq |
1249 ; ARM32: bne | 1249 ; ARM32: bne |
1250 ; ARM32: dmb | 1250 ; ARM32: dmb |
1251 | 1251 |
1252 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, | 1252 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, |
1253 i32 %desired) { | 1253 i32 %desired) { |
1254 entry: | 1254 entry: |
1255 %ptr = inttoptr i32 %iptr to i32* | 1255 %ptr = inttoptr i32 %iptr to i32* |
1256 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1256 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
1257 i32 %desired, i32 6, i32 6) | 1257 i32 %desired, i32 6, i32 6) |
1258 ret i32 0 | 1258 ret i32 0 |
1259 } | 1259 } |
1260 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored | 1260 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored |
1261 ; CHECK: mov eax,{{.*}} | 1261 ; CHECK: mov eax,{{.*}} |
1262 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] | 1262 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] |
1263 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored | 1263 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored |
1264 ; ARM32: dmb | 1264 ; ARM32: dmb |
1265 ; ARM32: ldrex | 1265 ; ARM32: ldrex |
1266 ; ARM32: cmp | 1266 ; ARM32: cmp |
1267 ; ARM32: strexeq | 1267 ; ARM32: strexeq |
1268 ; ARM32: {{str|mov}}ne | |
1269 ; ARM32: cmpeq | 1268 ; ARM32: cmpeq |
1270 ; ARM32: bne | 1269 ; ARM32: bne |
1271 ; ARM32: dmb | 1270 ; ARM32: dmb |
1272 | 1271 |
1273 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, | 1272 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, |
1274 i64 %desired) { | 1273 i64 %desired) { |
1275 entry: | 1274 entry: |
1276 %ptr = inttoptr i32 %iptr to i64* | 1275 %ptr = inttoptr i32 %iptr to i64* |
1277 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1276 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
1278 i64 %desired, i32 6, i32 6) | 1277 i64 %desired, i32 6, i32 6) |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 br i1 %cmp, label %done, label %body | 1463 br i1 %cmp, label %done, label %body |
1465 done: | 1464 done: |
1466 ret void | 1465 ret void |
1467 } | 1466 } |
1468 ; O2-LABEL: test_cmpxchg8b_regalloc | 1467 ; O2-LABEL: test_cmpxchg8b_regalloc |
1469 ;;; eax and some other register will be used in the cmpxchg instruction. | 1468 ;;; eax and some other register will be used in the cmpxchg instruction. |
1470 ; O2: lock cmpxchg8b QWORD PTR | 1469 ; O2: lock cmpxchg8b QWORD PTR |
1471 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. | 1470 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. |
1472 ; O2-NOT: {{eax|ecx|edx|ebx}} | 1471 ; O2-NOT: {{eax|ecx|edx|ebx}} |
1473 ; O2: pop ebx | 1472 ; O2: pop ebx |
OLD | NEW |