IPRA and conditionally reserved registers

Hi Kit,

I see you have been working on IPRA (⚙ D45308 [IPRA] Do not collect register usage information on functions that can be derefined), and would therefore like to bring up an issue with it I am looking into on SystemZ (see ⚙ D46232 [SystemZ, IPRA] determineCalleeSaves must always add return register and DP.).

I first realized that %r14, the return register, must be saved and restored with IPRA enabled, since otherwise the function can't return. This is a callee saved register so without IPRA this always gets saved, but if that is omitted and the function has no calls itself, we have to have a second check to add it with IPRA.

A related issue (the topic of this mail) is then the frame pointer (%r11). If caller uses FP, %r11 becomes reserved and is expected to never be allocated. But if callee does not have an FP, it is free to allocate it. So the Collector / Propagate passes transform the regmask on the call to express that %r11 is clobbered, but the problem is that the register allocator does not care about %r11 in caller, since it is reserved. This seems currently unhandled, and this is what I would like to ask about.

My first idea was to let callee always save/restore %r11, since it may be reserved in some caller. As Uli pointed out that is very conservative, and it seems to me also not be in agreement with IPRA, where the save/restore is generally done by caller as much as possible. So the question is how this should get handled in caller?

I would like to see RegUsageInfoPropagate compare the unmodified regmask with the updated one, and then make sure that any registers reserved in the current function being clobbered by the call as a result of IPRA (updated regmask), should now be copied to and from a virtual register around that call, but this is not being done. Am I missing something here?

So, in short, should these registers be saved/restored in caller, and if so how should this be done?


Attached is a test case where this happens on SystemZ.

bin/llc -mcpu=z13 -enable-ipra ./tc_ipra_fp.ll -o out.s

tc_ipra_fp.ll (883 Bytes)