I’ve identified a problem with running LOH analysis after the MachineOutliner. Since outlined function do not follow calling conversions, we can’t even be sure temporary registers don’t live across function calls.
In this example, the MachineOutliner creates the the thunk _OUTLINED_FUNCTION_0 and immediately moves x16 to the first argument of bar or goo.
_OUTLINED_FUNCTION_0:
adrp x19, _A@PAGE
add x19, x19, _A@PAGEOFF
ldr w20, [x19]
b _foo
...
bl _OUTLINED_FUNCTION_0
mov x0, x19
bl _bar
If we run LOH now, it will try to add an .loh AdrpAddLdr directive for the adrp, add, ldr triplet, which could turn into this in the linker.
nop
nop
ldr w20, [x19, <_A offset>]
This leaves x16 undefined.
I don’t think it’s reasonable to expect LOH to analyze register liveness across functions, so it’s probably best to keep LOH before the MachineOutliner. Instead, I think we should teach the MachineOutliner how to handle these LOH directives, instead of allowing the to block outlining. Either by removing LOH directives for outlined functions, or maybe analyzing whether they are valid and fixing them up if possible.