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.
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?