Skip to content

Commit 9c9a4a2

Browse files
authored
[LOH] Don't emit AdrpAddStr when register could be clobbered (llvm#142849)
llvm@b783aa8 added a check to ensure an `AdrpAddLdr` LOH isn't created when there is an instruction between the `add` and `ldr` https://github.com/llvm/llvm-project/blob/50c5704dc000cc0af41a511aa44db03233edf0af/llvm/lib/Target/AArch64/AArch64CollectLOH.cpp#L419-L431 We need a similar check for `AdrpAddStr`. Although this technically isn't implemented in LLD, it could be in the future. https://github.com/llvm/llvm-project/blob/50c5704dc000cc0af41a511aa44db03233edf0af/lld/MachO/Arch/ARM64.cpp#L699-L702
1 parent 6f2ba47 commit 9c9a4a2

File tree

2 files changed

+48
-26
lines changed

2 files changed

+48
-26
lines changed

llvm/lib/Target/AArch64/AArch64CollectLOH.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,17 @@ static bool supportLoadFromLiteral(const MachineInstr &MI) {
247247
}
248248
}
249249

250+
/// Returns \p true if there are no non-debug instructions between \p First and
251+
/// \p Second
252+
static bool areInstructionsConsecutive(const MachineInstr *First,
253+
const MachineInstr *Second) {
254+
auto It = First->getIterator();
255+
auto EndIt = First->getParent()->instr_end();
256+
if (It == EndIt)
257+
return false;
258+
return next_nodbg(It, EndIt) == Second->getIterator();
259+
}
260+
250261
/// Number of GPR registers tracked by mapRegToGPRIndex()
251262
static const unsigned N_GPR_REGS = 31;
252263
/// Map register number to index from 0-30.
@@ -415,7 +426,7 @@ static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI,
415426
++NumADRPToLDR;
416427
}
417428
break;
418-
case MCLOH_AdrpAddLdr: {
429+
case MCLOH_AdrpAddLdr:
419430
// There is a possibility that the linker may try to rewrite:
420431
// adrp x0, @sym@PAGE
421432
// add x1, x0, @sym@PAGEOFF
@@ -432,28 +443,24 @@ static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI,
432443
// FIXME: Implement proper liveness tracking for all registers. For now,
433444
// don't emit the LOH if there are any instructions between the add and
434445
// the ldr.
435-
MachineInstr *AddMI = const_cast<MachineInstr *>(Info.MI1);
436-
const MachineInstr *LdrMI = Info.MI0;
437-
auto AddIt = MachineBasicBlock::iterator(AddMI);
438-
auto EndIt = AddMI->getParent()->end();
439-
if (AddMI->getIterator() == EndIt || LdrMI != &*next_nodbg(AddIt, EndIt))
446+
if (!areInstructionsConsecutive(Info.MI1, Info.MI0))
440447
break;
441-
442448
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddLdr:\n"
443449
<< '\t' << MI << '\t' << *Info.MI1 << '\t'
444450
<< *Info.MI0);
445451
AFI.addLOHDirective(MCLOH_AdrpAddLdr, {&MI, Info.MI1, Info.MI0});
446452
++NumADDToLDR;
447453
break;
448-
}
449454
case MCLOH_AdrpAddStr:
450-
if (Info.MI1 != nullptr) {
451-
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddStr:\n"
452-
<< '\t' << MI << '\t' << *Info.MI1 << '\t'
453-
<< *Info.MI0);
454-
AFI.addLOHDirective(MCLOH_AdrpAddStr, {&MI, Info.MI1, Info.MI0});
455-
++NumADDToSTR;
456-
}
455+
if (!Info.MI1)
456+
break;
457+
if (!areInstructionsConsecutive(Info.MI1, Info.MI0))
458+
break;
459+
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddStr:\n"
460+
<< '\t' << MI << '\t' << *Info.MI1 << '\t'
461+
<< *Info.MI0);
462+
AFI.addLOHDirective(MCLOH_AdrpAddStr, {&MI, Info.MI1, Info.MI0});
463+
++NumADDToSTR;
457464
break;
458465
case MCLOH_AdrpLdrGotLdr:
459466
LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGotLdr:\n"
Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
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
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 --implicit-check-not=MCLOH_
22
# REQUIRES: asserts
3+
4+
# Check that we don't emit LOHs when there is a clobbering def of x8.
35
--- |
46
@sym2 = local_unnamed_addr global [10000000 x i32] zeroinitializer, align 8
57
@sym = local_unnamed_addr global i32 zeroinitializer, align 8
68

7-
define i32 @main() {
8-
ret i32 0
9-
}
9+
define i32 @adrp_add_ldr() { ret i32 0 }
10+
define i32 @adrp_add_str() { ret i32 0 }
11+
...
12+
13+
---
14+
name: adrp_add_ldr
15+
alignment: 4
16+
tracksRegLiveness: true
17+
liveins:
18+
- { reg: '$x21', virtual-reg: '' }
19+
body: |
20+
bb.0:
21+
liveins: $x21
22+
renamable $x8 = ADRP target-flags(aarch64-page) @sym
23+
renamable $x9 = ADDXri killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @sym, 0
24+
renamable $x8 = ADDXri killed renamable $x21, 1, 0
25+
$x9 = LDRXui $x9, 0
1026
27+
RET undef $lr
1128
...
29+
1230
---
13-
name: main
31+
name: adrp_add_str
1432
alignment: 4
1533
tracksRegLiveness: true
1634
liveins:
@@ -19,13 +37,10 @@ liveins:
1937
body: |
2038
bb.0:
2139
liveins: $x21, $x22
22-
; Check we don't emit an loh here because there's a clobbering def of x8 before the ldr.
23-
; CHECK-LABEL: main
24-
; CHECK-NOT: MCLOH_AdrpAddLdr
2540
renamable $x8 = ADRP target-flags(aarch64-page) @sym
2641
renamable $x9 = ADDXri killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @sym, 0
27-
renamable $x8 = ADDXri killed renamable $x22, 1, 0
28-
$x9 = LDRXui $x9, 0
29-
RET undef $lr
42+
renamable $x8 = ADDXri killed renamable $x21, 1, 0
43+
STRXui $x22, $x9, 0
3044
45+
RET undef $lr
3146
...

0 commit comments

Comments
 (0)