Skip to content

Commit b783aa8

Browse files
committed
[AArch64] Fix emitting an AdrpAddLdr LOH when there's a potential clobber of the
def of the adrp before the ldr. Apparently this pass used to have liveness analysis but it was removed for scompile time reasons. This workaround prevents the LOH from being emitted unless the ADD and LDR are adjacent. Fixes JuliaLang/julia#39820 Differential Revision: https://reviews.llvm.org/D97571
1 parent 8bfc141 commit b783aa8

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

llvm/lib/Target/AArch64/AArch64CollectLOH.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,37 @@ static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI,
419419
++NumADRPToLDR;
420420
}
421421
break;
422-
case MCLOH_AdrpAddLdr:
422+
case MCLOH_AdrpAddLdr: {
423+
// There is a possibility that the linker may try to rewrite:
424+
// adrp x0, @sym@PAGE
425+
// add x1, x0, @sym@PAGEOFF
426+
// [x0 = some other def]
427+
// ldr x2, [x1]
428+
// ...into...
429+
// adrp x0, @sym
430+
// nop
431+
// [x0 = some other def]
432+
// ldr x2, [x0]
433+
// ...if the offset to the symbol won't fit within a literal load.
434+
// This causes the load to use the result of the adrp, which in this
435+
// case has already been clobbered.
436+
// FIXME: Implement proper liveness tracking for all registers. For now,
437+
// don't emit the LOH if there are any instructions between the add and
438+
// the ldr.
439+
MachineInstr *AddMI = const_cast<MachineInstr *>(Info.MI1);
440+
const MachineInstr *LdrMI = Info.MI0;
441+
auto AddIt = MachineBasicBlock::iterator(AddMI);
442+
auto EndIt = AddMI->getParent()->end();
443+
if (AddMI->getIterator() == EndIt || LdrMI != &*next_nodbg(AddIt, EndIt))
444+
break;
445+
423446
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddLdr:\n"
424447
<< '\t' << MI << '\t' << *Info.MI1 << '\t'
425448
<< *Info.MI0);
426449
AFI.addLOHDirective(MCLOH_AdrpAddLdr, {&MI, Info.MI1, Info.MI0});
427450
++NumADDToLDR;
428451
break;
452+
}
429453
case MCLOH_AdrpAddStr:
430454
if (Info.MI1 != nullptr) {
431455
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddStr:\n"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# RUN: llc -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s
2+
--- |
3+
@sym2 = local_unnamed_addr global [10000000 x i32] zeroinitializer, align 8
4+
@sym = local_unnamed_addr global i32 zeroinitializer, align 8
5+
6+
define i32 @main() {
7+
ret i32 0
8+
}
9+
10+
...
11+
---
12+
name: main
13+
alignment: 4
14+
tracksRegLiveness: true
15+
liveins:
16+
- { reg: '$x22', virtual-reg: '' }
17+
- { reg: '$x21', virtual-reg: '' }
18+
body: |
19+
bb.0:
20+
liveins: $x21, $x22
21+
; Check we don't emit an loh here because there's a clobbering def of x8 before the ldr.
22+
; CHECK-LABEL: main
23+
; CHECK-NOT: MCLOH_AdrpAddLdr
24+
renamable $x8 = ADRP target-flags(aarch64-page) @sym
25+
renamable $x9 = ADDXri killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @sym, 0
26+
renamable $x8 = ADDXri killed renamable $x22, 1, 0
27+
$x9 = LDRXui $x9, 0
28+
RET undef $lr
29+
30+
...

0 commit comments

Comments
 (0)