-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remat applied to updated value #3006
Comments
Sent to llvmdev: Ok, I've been tracking down a remat bug for over a week. I think I finally The bug is extremely subtle and nasty. Therefore this explanation is very This is with 2.3 plus a few extra patches (from upstream) that fix bugs My comments delimited with #####. The rest is llvm debug output (lots There's a sequence of instructions that looks like this before linear scan: 2800 %reg1591 = SUB64rr %reg1591, %reg1589, %EFLAGS<imp-def,dead> ; %reg1591 gets spilled by linear scan with all of the uses in the sequence
[2818,2966:1)[2966,7840:0) 0@2966 1@2818-(2966) 2@2810-(2818) 3@2802-(2810) +[2180,2182:0) Added new interval: %reg2559,0 = [2180,2182:0) 0@2180 It turns out that %reg1559 is ALSO spilled (remember it was reused so is not a
[2818,2966:3)[2966,3226:4) 0@2180 1@2802 2@2810 3@2818 4@2966 into: ADD64mr <fi#165>, 1, %reg0, 0, %reg1579, %mreg23<imp-def,dead> ; Virt folded mapped NewMI 0x9405f70: ADD64mr <fi#165>, 1, %reg0, 0, %reg1579, +[2820,2822:0) Added new interval: %reg2565,0 = [2820,2822:0) 0@2820 into: ADD64mr <fi#165>, 1, %reg0, 0, %reg1599, %mreg23<imp-def,dead> ; Virt folded mapped NewMI 0x98af530: ADD64mr <fi#165>, 1, %reg0, 0, into: %reg1191 = MOV64rm <fi#165>, 1, %reg0, 0 ; srcLine 0 Virt folded mapped NewMI 0x92459e0: %reg1191 = MOV64rm <fi#165>, 1, The remats identified above are all correct. Note that NO remats are defined %reg1579 (the other operand of the ADD64mr) is also spilled with a bunch of
[2766,2926:2)[2926,2934:1)[2934,7840:0) 0@2934 1@2926-(2934) 2@2766-(2926) %reg2613 (split reuses of the spilled %reg1579) is ALSO spilled:
[2766,2926:3)[2926,2934:4)[2934,2935:5) 0@2714 1@2718 2@2726 3@2766 4@2926 into: MOV64mr <fi#184>, 1, %reg0, 0, %reg1607 ; srcLine 0 Virt folded mapped NewMI 0x9883480: MOV64mr <fi#184>, 1, %reg0, 0, %reg1607 ; into: SUB64mr <fi#184>, 1, %reg0, 0, %reg1577, %mreg23<imp-def,dead> ; Virt folded mapped NewMI 0x93f7c90: SUB64mr <fi#184>, 1, %reg0, 0, into: ADD64mr <fi#184>, 1, %reg0, 0, %reg1584, %mreg23<imp-def,dead> ; Virt folded mapped NewMI 0x96dded0: ADD64mr <fi#184>, 1, %reg0, 0, %reg1584, into: ADD64mr <fi#184>, 1, %reg0, 0, %reg1599, %mreg23<imp-def,dead> ; Virt folded mapped NewMI 0x92450c0: ADD64mr <fi#184>, 1, %reg0, 0, %reg1599, %reg1618 is what we care about here. The final register map looks like this: [%reg2561 -> R12] [%reg2561 -> fi#165] Now LocalSpiller comes along to do its work. The code before the spiller runs [%reg2563 = remat $32] Now for the fun part. The spiller processes each instruction in our sequence Processing instruction 0x98662d0: %reg2563 = SUB64rr %reg2563, %reg1589, Processing operand %reg2563 Good, it got the remat for %reg2563. It goes on to process the spill of Processing instruction 0x99fdf10: MOV64mr <fi#165>, 1, %reg0, 0, %R12 ; Processing operand <fi#165> Ok, pretty straightforward. Let's ho on to the IMUL64: Processing instruction 0x947cf40: %reg2564 = IMUL64rm %reg2564, <fi#113>, Processing operand %reg2564 Again, this is good. There is NO remat for %reg2564. Now process the Processing instruction 0x99fe0c0: MOV64mr <fi#165>, 1, %reg0, 0, %R12 ; Processing operand <fi#165> Again, piece of cake. Now the ADD64: Processing instruction 0x9405f70: ADD64mr <fi#165>, 1, %reg0, 0, %reg2618, Unfolded instruction: ADD64mr <fi#165>, 1, %reg0, 0, %reg2618, To: %reg2559 = ADD64rr %reg2559, %reg2618, %mreg23<imp-def,dead> ; Virt folded mapped MI 0x99fdf90: %reg2559 = ADD64rm %reg2559, <fi#184>, Final folded: %reg2559 = ADD64rm %reg2559, <fi#184>, 1, %reg0, 0, Processing operand %reg2559 UH OH! When LocalSpiller unfolded the ADD64 it saw %reg2559. It then looked This is wrong because this value of %reg2559 is different from the value I believe one (not the only one!) problem is that VirtRegMap's remat map is Probably this is a very rare thing because it's rarer to spill registers that I believe that there's also a bug in unfolding. Rather than returning Either one of these fixes would make this particular bug go away. My feeling Does this all sound plausible? Are the proposed fixes the correct way to go?
|
I have a fix for this. I am packaging it up and will apply ASAP. |
David, ping? |
I've ported the fix to trunk and am testing now. |
Fixed with rev. 58255. |
Support stripping indirectly referenced DILocations from !llvm.loop m…
Extended Description
In SPEC CPU 2006 leslie3d, a value is spilled, split and one of the splits is spilled again. The value happens to be rematable and when the split interval is spilled two-address rewriting causes the enregistered value to be changed. But live interval analysis has outdated information and thinks it can insert a remat of the old value just after the new value is written to the register.
The text was updated successfully, but these errors were encountered: