It turns out greedy does quite a lot of "operation folding" to get more compact spill code.
It will turn
%0:ercr = LDA_spill ...
$crSat = COPY %0
into
$crSat = LDA_spill ...
This is problematic because we cannot directly reload into a $crSat register. I actually expected such folding to be illegal, because after all, $crSat is a reserved register. And usually, reserved registers just mean "don't you dare optimize me". But it's also true that this register is part of eRCR (which it needs to be in for some of our copy-propagation extensions to kick in), so I guess what greedy does is fair game.
I could change const TargetRegisterClass *canFoldCopy(...) to actually never fold into reserved registers, but that causes one X86 test to fail. At this point, I'd rather just constrain eRCR to eR before greedy, because it's anyway what we want: the classes are equivalent in terms of allocatable registers, and eR is easy to spill.
No QoR impact, which is expected, but you never know.
It turns out greedy does quite a lot of "operation folding" to get more compact spill code.
It will turn
into
This is problematic because we cannot directly reload into a
$crSat
register. I actually expected such folding to be illegal, because after all,$crSat
is a reserved register. And usually, reserved registers just mean "don't you dare optimize me". But it's also true that this register is part ofeRCR
(which it needs to be in for some of our copy-propagation extensions to kick in), so I guess what greedy does is fair game.I could change
const TargetRegisterClass *canFoldCopy(...)
to actually never fold into reserved registers, but that causes one X86 test to fail. At this point, I'd rather just constraineRCR
toeR
before greedy, because it's anyway what we want: the classes are equivalent in terms of allocatable registers, andeR
is easy to spill.No QoR impact, which is expected, but you never know.