This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Fix verifier error when outlining indirect calls
ClosedPublic

Authored by olista01 on Oct 3 2018, 5:31 AM.

Details

Summary

The MachineOutliner for AArch64 transforms indirect calls into indirect
tail calls, replacing the call with the TCRETURNri pseudo-instruction.
This pseudo lowers to a BR, but has the isCall and isReturn flags set.

The problem is that TCRETURNri takes a tcGPR64 as the register argument,
to prevent indiret tail-calls from using caller-saved registers. The
indirect calls transformed by the outliner could use caller-saved
registers. This is fine, because the outliner ensures that the register
is available at all call sites. However, this causes a verifier failure
when the register is not in tcGPR64. The fix is to add a new
pseudo-instruction like TCRETURNri, but which accepts any GPR.

Diff Detail

Repository
rL LLVM

Event Timeline

olista01 created this revision.Oct 3 2018, 5:31 AM
olista01 edited reviewers, added: paquette; removed: jpaquette.Oct 4 2018, 1:47 AM

Are there no other ways to identify an outliner function, say a function flag or a needed pattern, so we can change the verifier instead, and not fail when called-saved regs are used?

I don't think adding a special case to the verifier makes sense, when it's easy enough to generate code which is valid by the normal rules.

I did consider the alternative of just generating a BR instruction directly, since the outliner runs very late so the isCall/isReturn flags are unlikely to be used in a later pass, but I'm not sure if the verifier would like that either.

I don't think adding a special case to the verifier makes sense, when it's easy enough to generate code which is valid by the normal rules.

I think this is probably really the only thing the outliner does that upsets the verifier. So, from that perspective, I think that this is fine.

OTOH, having a function flag or something like @rengolin suggested is probably a bit cleaner in the long term. I slightly prefer this position since it seems like it should be the verifier's responsibility to understand what to do with an outlined function. Also, if it does turn out that there are other weird cases, it'd be kind of overkill to add special outlining instructions everywhere just to appease the verifier.

So, if it's not too much overhead, I think that adding an outlined function flag or something would probably be better, but for the short-term I'm fine with this.

I did consider the alternative of just generating a BR instruction directly, since the outliner runs very late so the isCall/isReturn flags are unlikely to be used in a later pass, but I'm not sure if the verifier would like that either.

That's how it used to be, and the verifier didn't like that because the BR doesn't count as a terminator. :(

OTOH, having a function flag or something like @rengolin suggested is probably a bit cleaner in the long term. I slightly prefer this position since it seems like it should be the verifier's responsibility to understand what to do with an outlined function. Also, if it does turn out that there are other weird cases, it'd be kind of overkill to add special outlining instructions everywhere just to appease the verifier.

Yes, that's what I was worried about.

So, if it's not too much overhead, I think that adding an outlined function flag or something would probably be better, but for the short-term I'm fine with this.

SGTM, thanks!

paquette accepted this revision.Oct 4 2018, 10:59 AM

As long as you add a FIXME saying that we should move this responsibility over to the verifier, this LGTM.

This revision is now accepted and ready to land.Oct 4 2018, 10:59 AM
This revision was automatically updated to reflect the committed changes.