This is an archive of the discontinued LLVM Phabricator instance.

[x86/SLH] Completely rework how we sink post-load hardening past data invariant instructions to be both more correct and much more powerful.
ClosedPublic

Authored by chandlerc on Jul 16 2018, 7:43 AM.

Details

Summary

While testing, I continued to find issues with sinking post-load
hardening. Unfortunately, it was amazingly hard to create any useful
tests of this because we were mostly sinking across copies and other
loading instructions. The fact that we couldn't sink past normal
arithmetic was really a big oversight.

So first, I've ported roughly the same set of instructions from the data
invariant loads to also have their non-loading varieties understood to
be data invariant. I've also added a few instructions that came up so
often it again made testing complicated: inc, dec, and lea.

With this, I was able to shake out a few nasty bugs in the validity
checking. We need to restrict to hardening single-def instructions with
defined registers that match a particular form: GPRs that don't have
a NOREX constraint directly attached to their register class.

The (tiny!) test case included catches all of the issues I was seeing
(once we can sink the hardening at all) except for the NOREX issue. The
only test I have there is horrible. It is large, inexplicable, and
doesn't even produce an error unless you try to emit encodings. I can
keep looking for a way to test it, but I'm out of ideas really.

I'm asking Ben to take a quick look at this for sanity and then I'll land it.
I'll follow up with Craig to get a more thorough review, but without this we're
getting crashes everywhere.

Diff Detail

Repository
rL LLVM

Event Timeline

chandlerc created this revision.Jul 16 2018, 7:43 AM
bkramer accepted this revision.Jul 16 2018, 7:53 AM

This is fine, it's just that listing all of the instructions gives me a really bad feeling.

This revision is now accepted and ready to land.Jul 16 2018, 7:53 AM
This revision was automatically updated to reflect the committed changes.
craig.topper added inline comments.
llvm/trunk/lib/Target/X86/X86SpeculativeLoadHardening.cpp
938

Off the top of my head
-You probably want NOT and NEG in this list too.
-Pre-BMI2 shift instructions? Especially the shift by immediate since we don't have a BMI equivalent
-Rotate by variable and the pre-BMI2 rotate by immediate?
-SHLD/SHRD?
-Double width result multiplies?
-MOVZX/MOVSX?
-Maybe MOV32rr which is iselled explicitly to clear the upper 32-bits of GR64?

craig.topper added inline comments.Jul 16 2018, 2:42 PM
llvm/trunk/lib/Target/X86/X86SpeculativeLoadHardening.cpp
938

BTC/BTR/BTS as well.

As a quick change this looks ok, some thoughts for cleanup:

a) Comments match the code. You've changed a lot of code here, but none of the comments :)
b) Relatedly, function names match the code. Same comment.
c) I think the hardening of registers/loads/etc needs a better comment somewhere with what the plan is for the pass.

llvm/trunk/lib/Target/X86/X86SpeculativeLoadHardening.cpp
1266

Comment update? Mostly because they no longer match and while I think I know what you're going for - I'd really like every aspect of this if statement commented.