This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Fix CollectLOH creating an AdrpAdd LOH when there's a live used reg between the two instructions.
ClosedPublic

Authored by aemerson on May 29 2020, 12:45 PM.

Details

Summary

If there's a pattern like:

$xA = ADRP foo @PAGE
[some killing use of reg Xb]
$Xb = ADDXri $Xa, 0, @PAGEOFF

CollectLOH would create an AdrpAdd LOH that resulted in the linker optimizing this sequence into:

$xB = ADR foo
[some killing use of reg $Xb]

... and therefore clobbers the live $Xb register that was used by the instruction in between.

This was discovered by a GlobalISel patch D78465 which broke up global variable accesses into two pseudos, which in some cases could be moved apart.

Diff Detail

Event Timeline

aemerson created this revision.May 29 2020, 12:45 PM
paquette added inline comments.Jun 1 2020, 10:03 AM
llvm/test/CodeGen/AArch64/loh-use-between-adrp-add.mir
27–30

Will this patch prevent us from making the LOH if we have something like this?

$add_def = ... stuff ...
$adrp_def = adrp  ...
$add_def = add ...

If I understand correctly, it looks like the patch doesn't check if the use is actually between the adrp and add?

aemerson updated this revision to Diff 267741.Jun 1 2020, 2:51 PM

Add a test case for a use before the ADRP.

aemerson marked an inline comment as done.Jun 1 2020, 2:57 PM
aemerson added inline comments.
llvm/test/CodeGen/AArch64/loh-use-between-adrp-add.mir
27–30

This change checks if the add def register has a use at the point of the ADRP, as it goes bottom up. Therefore if the use is before the ADRP, then OneUse won't be true because we haven't hit it yet. And having a def doesn't make sense because the def would be overwritten by the ADD.

paquette accepted this revision.Jun 1 2020, 3:25 PM

LGTM

This revision is now accepted and ready to land.Jun 1 2020, 3:25 PM
This revision was automatically updated to reflect the committed changes.

I believe this fix is incomplete and also needs to apply adrp/add/ldr sequences (and maybe others). We encountered this as a miscompilation while porting to Apple Silicon (https://github.com/JuliaLang/julia/issues/39820).

I believe this fix is incomplete and also needs to apply adrp/add/ldr sequences (and maybe others). We encountered this as a miscompilation while porting to Apple Silicon (https://github.com/JuliaLang/julia/issues/39820).

I'll take a look. Are you by any chance enabling GlobalISel at all? I assume this is with optimizations enabled?

I don't believe GlobalIsel is enabled. This is in debug mode, so
optimizations are enabled, but minimal. Thanks!