Commit e76ac5c
Visit instruction arguments in reverse in register allocator when calculating last-use data
Summary:
(This is another attempt at fixing the issue papered over in D104499077.)
optimizeMoveSequence() caches register-to-spill moves and rewrites later stack operands to use the cached register. The bug is that a rewritten operand can be marked `lastUse` even when the same spill slot is read again later in the block. D104499077 makes this easy to hit by reusing one stripped value twice for the same runtime call, but the optimizer bug exists independently of that change.
[spill] = Move RDI
RSI = Move [spill] ; rewritten to RSI = Move RDI
RDX = Move [spill] ; still reads the spill later
Call ...
If the first reload carries `lastUse`, `optimizeMoveSequence()` deletes `[spill] = Move RDI` as dead immediately after rewriting `RSI = Move [spill]`. The later reload still reads `[spill]`, so the call runs with stale stack data.
The cause involves the same value being read from the same spill slot by multiple instructions in the same basic block. This is aa situation created by D102409172's tag stripping:
* D102409172 adds a strip_cache — when the same tagged value needs stripping for two call arguments, one `And` instruction is emitted and both call arguments become `LinkedOperand`s pointing to the same vreg output.
* After regalloc, if that vreg is spilled, both operands become stack-slot reads from the same physical location.
* After `rewriteCallInstrs` extracts them into separate `Move`s, you get two `Move`s reading the same spill slot.
* However, before the fix, the allocator iterates inputs in forward order while processing instructions in reverse. For `Call func, [spill], [spill]`: the first input is encountered first, def is not in the live set, so it gets `lastUse`. The second input finds def already live — no `lastUse`. So, after call rewriting, `lastUse` is on the chronologically first `Move` — exactly the wrong one for spill deletion.
The bug specifically triggers in the self-reload variant: when the spilled register happens to match one of the argument registers, producing `Move RDI, [spill]` (self-reload) followed by `Move RSI, [spill]`.
To deal with this we change the register allocator to visit instruction inputs in reverse (apparently) consistently with visiting instructions in reverse. Then `rewriteCallInstrs()` can correctly apply `lastUse` to the chronologically last `Move`.
Reviewed By: yoney
Differential Revision: D105856708
fbshipit-source-id: 60af6cbc087576f2c18796104c390ca538884ae01 parent 4cfd2b1 commit e76ac5c
3 files changed
Lines changed: 63 additions & 58 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1480 | 1480 | | |
1481 | 1481 | | |
1482 | 1482 | | |
1483 | | - | |
1484 | | - | |
1485 | | - | |
1486 | | - | |
1487 | 1483 | | |
1488 | 1484 | | |
1489 | 1485 | | |
| |||
1498 | 1494 | | |
1499 | 1495 | | |
1500 | 1496 | | |
1501 | | - | |
1502 | | - | |
1503 | | - | |
1504 | 1497 | | |
1505 | 1498 | | |
1506 | 1499 | | |
| |||
1511 | 1504 | | |
1512 | 1505 | | |
1513 | 1506 | | |
1514 | | - | |
1515 | | - | |
1516 | | - | |
1517 | | - | |
1518 | | - | |
1519 | | - | |
1520 | | - | |
| 1507 | + | |
| 1508 | + | |
1521 | 1509 | | |
1522 | 1510 | | |
1523 | 1511 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
468 | 468 | | |
469 | 469 | | |
470 | 470 | | |
471 | | - | |
472 | | - | |
473 | | - | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
474 | 480 | | |
475 | 481 | | |
476 | 482 | | |
| |||
480 | 486 | | |
481 | 487 | | |
482 | 488 | | |
483 | | - | |
| 489 | + | |
484 | 490 | | |
485 | 491 | | |
486 | 492 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
768 | 768 | | |
769 | 769 | | |
770 | 770 | | |
| 771 | + | |
771 | 772 | | |
772 | 773 | | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
773 | 778 | | |
774 | | - | |
| 779 | + | |
775 | 780 | | |
776 | 781 | | |
777 | 782 | | |
778 | 783 | | |
779 | | - | |
780 | | - | |
781 | | - | |
782 | | - | |
783 | | - | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
784 | 799 | | |
785 | 800 | | |
786 | 801 | | |
| |||
820 | 835 | | |
821 | 836 | | |
822 | 837 | | |
823 | | - | |
| 838 | + | |
824 | 839 | | |
825 | 840 | | |
826 | 841 | | |
827 | 842 | | |
828 | 843 | | |
829 | | - | |
| 844 | + | |
830 | 845 | | |
831 | 846 | | |
832 | | - | |
833 | | - | |
834 | | - | |
835 | | - | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
836 | 857 | | |
837 | 858 | | |
838 | 859 | | |
839 | 860 | | |
840 | | - | |
| 861 | + | |
841 | 862 | | |
842 | 863 | | |
843 | 864 | | |
844 | | - | |
| 865 | + | |
845 | 866 | | |
846 | 867 | | |
847 | 868 | | |
848 | 869 | | |
849 | 870 | | |
850 | | - | |
851 | | - | |
852 | | - | |
853 | | - | |
854 | | - | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
855 | 874 | | |
856 | 875 | | |
857 | | - | |
| 876 | + | |
858 | 877 | | |
859 | | - | |
860 | | - | |
861 | | - | |
862 | | - | |
863 | | - | |
| 878 | + | |
864 | 879 | | |
865 | 880 | | |
866 | 881 | | |
| |||
871 | 886 | | |
872 | 887 | | |
873 | 888 | | |
874 | | - | |
875 | | - | |
876 | | - | |
877 | | - | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
878 | 892 | | |
879 | 893 | | |
880 | 894 | | |
881 | 895 | | |
882 | 896 | | |
883 | 897 | | |
884 | | - | |
885 | | - | |
886 | | - | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
887 | 904 | | |
888 | 905 | | |
889 | 906 | | |
890 | | - | |
891 | | - | |
892 | | - | |
893 | | - | |
894 | | - | |
895 | | - | |
896 | | - | |
897 | | - | |
| 907 | + | |
| 908 | + | |
898 | 909 | | |
899 | 910 | | |
900 | 911 | | |
| |||
0 commit comments