This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Move SLS later in pass pipeline
ClosedPublic

Authored by olista01 on Aug 22 2023, 6:46 AM.

Details

Summary

Currently, the SLS hardening pass is run before the machine outliner,
which means that the outliner creates new functions and calls which do
not have the SLS hardening applied.

The fix for this is to move the SLS passes to after the outliner, as has
recently been done for the return address signing pass.

This also avoids a bug where the SLS outliner emits code with
instructions after a return, which the outliner doesn't correctly
handle.

This results in the heuristics used by the outliner being wrong, since
it doesn't know about the extra instructions the SLS pass will add to
every call and return. That's not a correctness problem, so I'll update
them in a separate patch.

Previous summary:

The SLS hardening pass inserts barrier instructions after return
instructions, so it was causing the machine outliner to fail to notice
return blocks, so it could outline at places where LR is live. The fix
for this is to check all terminator instructions when deciding if a
block ends in a return, not just the least one.

I think there's a deeper issue that we don't correctly track the
liveness of LR around function returns. This appears to be deliberate,
according to the comment on RET_ReallyLR in AArch64InstrInfo.td. I tried
changing this to make LR an implicit operand of all returns, but haven't
found a way to do that which doesn't cause a large number of MIR
verifier failures.

I think there's also an issue here that the outliner can create code
which does not have the SLS barrier instructions after a tail-call.
@Kristof, do you know if the SLS pass could be moved to after the
outliner to fix this, or does it need to happen as early as it does?

Diff Detail

Event Timeline

olista01 created this revision.Aug 22 2023, 6:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2023, 6:46 AM
olista01 requested review of this revision.Aug 22 2023, 6:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2023, 6:46 AM

I don't remember any reason why the SLS pass needs to run before the outliner.
It seems to me that indeed it may be easier to move to SLS pass to run after the outliner - i.e. run after any pass that may need to interpret the semantics of return instructions.

olista01 updated this revision to Diff 557769.Oct 19 2023, 1:59 AM
olista01 retitled this revision from [AArch64] Fix incorrect outlining with SLS-hardening to [AArch64] Move SLS later in pass pipeline.
olista01 edited the summary of this revision. (Show Details)
  • Move SLS pass later in the pass pipeline
kristof.beyls added inline comments.Oct 25 2023, 1:04 AM
llvm/lib/Target/AArch64/AArch64SLSHardening.cpp
225–227

I guess this change is a side-effect of moving the AArch64IndirectThunks pass later in the pipeline. But I cannot easily guess what exactly triggers this change in behavior. I wonder if you happen to know?

olista01 added inline comments.Oct 25 2023, 1:33 AM
llvm/lib/Target/AArch64/AArch64SLSHardening.cpp
225–227

IndirectThunks.h:84 has a comment explaining that it does not create the entry block, but I've not worked out where it was being created before.

kristof.beyls accepted this revision.Oct 25 2023, 1:36 AM

LGTM, thanks!

llvm/lib/Target/AArch64/AArch64SLSHardening.cpp
225–227

Thanks. I guess it doesn't really matter much.

This revision is now accepted and ready to land.Oct 25 2023, 1:36 AM
This revision was automatically updated to reflect the committed changes.