Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
- G_LOAD had to be legal for all sizes you could extend from, even if registers didn't naturally hold those sizes.
- All sizes you could extend from had to be allocatable just in case the extend went missing (e.g. by optimization).
- At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we improve optimization of extends and truncates, this legality requirement would spread without considerable care w.r.t when certain combines were permitted.
- The SelectionDAG importer required some ugly and fragile pattern rewriting to translate patterns into this style.
This patch changes the representation to:
- (G_[SZ]EXTLOAD x)
- (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
It appears to me that quite universally orderings are called "less than" and "greater than" with well known LT and GT abbreviations, maybe it makes sense to stick to the widely used naming scheme?
Also, looks like "Smaller Than" actually performs <= rather than <, same true for "Larger Than" (>= instead of >), so that makes the names even more confusing.