IMAGE_REL_ARM_MOV32T relocations require that the movw/movt pair relocation is
not split up and reordered. We handle this in the ARM Hazard Recognizer by
tracking the previous machine instruction and the current one. If the previous
one is a mov.w of an address entity, scan through the rest of the instructions
in the function to only permit the paired mov.t. If only the low half of an
address is being loaded (i.e. mov.w without a mov.t) then the only downside of
this tracking is that we end up scanning the remainder of the function to detect
that no other instruction can be reordered around this point.
Details
- Reviewers
grosbach t.p.northover
Diff Detail
Event Timeline
Hi Saleem,
Apart from my feature flag comment, looks good. Though, I don't know the Windows ABI that well, you may wait for more specific comments.
cheers,
--renato
lib/Target/ARM/ARMHazardRecognizer.cpp | ||
---|---|---|
69 | Maybe we should set a feature flag for this somewhere a bit lower, and mark it true on Windows triples? |
lib/Target/ARM/ARMHazardRecognizer.cpp | ||
---|---|---|
69 | Might be useful ... as much as I dislike the check as it currently stands, I think that addressing that once more of the CG is in place might make it easier to come up with a nice way to describe this scenario. |
A thought has occurred to me. The implementation via the hazard feels like a hack, so...
These MOVW/MOVT pairs are going to be coming from t2MOVi32imm or similar. Might a better solution be to modify ExpandPseudoInst so that it creates a bundle of them (on Windows) instead of 2 completely separate instructions?
That might get rid of the need for the ConstantIslands and IT block change entirely.
Cheers.
Tim.
Hah, that was the first approach that I took. The problem ended up being that the psuedo-expansion occurred too early, and the instruction was still split up :-(. If there is a generic way to handle all the possible cases, that would most certainly be the preferred.
Hi Saleem,
Hah, that was the first approach that I took. The problem ended up being that the psuedo-expansion occurred too early, and the instruction was still split up :-(. If there is a generic way to handle all the possible cases, that would most certainly be the preferred.
Do you remember any examples of instructions in bundles being split?
Because my natural instinct is to say that would be a bug, regardless
of whether it's exercised at the moment or not.
(In the future TLSDESC support may produce similar bundles if it
follows AArch64 implementation. Passes that split bundles would be
just as much of an issue there too).
Cheers.
Tim.
Yes, the Constant Pool Island injection is one case where the instruction was split up even if I bundled them. Its quite possible that I did not get everything correct. The resultant MI would look something like this:
BUNDLE * %R0<def> = t2MOVi16 <ga:@"global">[TF=1], pred:14, pred:%noreg * %R0<def,tied1> = t2MOVTi16 %R0<tied0>, <ga:@"global">[TF=2], pred:14, pred:%noreg
This would then get split up as such:
%R0<def> = t2MOVi16 <ga:@"global">[TF=1], pred:14, pred:%noreg t2B <BB#3>, pred:14, pred:%noreg CONSTPOOL_ENTRY 1, <cp#1>, 4 %R0<def,tied1> = t2MOVTi16 %R0<tied0>, <ga:@"global">[TF=2], pred:14, pred:%noreg
While this is perfectly fine on other targets, on Windows, this must remain bundled as the relocation is applied to the consecutive 32-bits. The result is that the relocation would corrupt the instruction stream.
Unfortunately, I do not have a test case readily available which can demonstrate this.
I think everyone agrees that this is not a particularly pretty solution. Given that any case of the bundle being split up should be considered a bug, I think that there is no reason to hold up other changes on this. This addresses all but one case: the constant island pass. I've committed a change with the bundling approach with a bit more aggressive reorder prevention. The constant island handling will have to be addressed separately and we can discuss how to best handle that separately.
Maybe we should set a feature flag for this somewhere a bit lower, and mark it true on Windows triples?