Skip to content

Commit 26d8927

Browse files
committed
[GlobalISel] Always direct-call IFuncs and Aliases (llvm#74902)
This is safe because for both cases, the use must be in the same TU as the definition, and they cannot be forward declared.
1 parent f6057ae commit 26d8927

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,12 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
144144
const Value *CalleeV = CB.getCalledOperand()->stripPointerCasts();
145145
if (const Function *F = dyn_cast<Function>(CalleeV))
146146
Info.Callee = MachineOperand::CreateGA(F, 0);
147-
else
147+
else if (isa<GlobalIFunc>(CalleeV) || isa<GlobalAlias>(CalleeV)) {
148+
// IR IFuncs and Aliases can't be forward declared (only defined), so the
149+
// callee must be in the same TU and therefore we can direct-call it without
150+
// worrying about it being out of range.
151+
Info.Callee = MachineOperand::CreateGA(cast<GlobalValue>(CalleeV), 0);
152+
} else
148153
Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
149154

150155
Register ReturnHintAlignReg;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -mtriple=aarch64-elf -global-isel -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
3+
4+
@foo_alias = alias ptr, ptr @callee
5+
6+
define internal ptr @callee() {
7+
; CHECK-LABEL: name: callee
8+
; CHECK: bb.1.entry:
9+
; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
10+
; CHECK-NEXT: $x0 = COPY [[C]](p0)
11+
; CHECK-NEXT: RET_ReallyLR implicit $x0
12+
entry:
13+
ret ptr null
14+
}
15+
16+
define void @caller() {
17+
; CHECK-LABEL: name: caller
18+
; CHECK: bb.1.entry:
19+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
20+
; CHECK-NEXT: BL @foo_alias, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $w0
21+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
22+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
23+
; CHECK-NEXT: RET_ReallyLR
24+
entry:
25+
%0 = call i32 @foo_alias()
26+
ret void
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -mtriple=aarch64-macho -global-isel -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
3+
; RUN: llc -mtriple=aarch64-elf -global-isel -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
4+
5+
@foo_ifunc = ifunc i32 (i32), ptr @foo_resolver
6+
7+
define internal ptr @foo_resolver() {
8+
; CHECK-LABEL: name: foo_resolver
9+
; CHECK: bb.1.entry:
10+
; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
11+
; CHECK-NEXT: $x0 = COPY [[C]](p0)
12+
; CHECK-NEXT: RET_ReallyLR implicit $x0
13+
entry:
14+
ret ptr null
15+
}
16+
17+
define void @caller() {
18+
; CHECK-LABEL: name: caller
19+
; CHECK: bb.1.entry:
20+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
21+
; CHECK-NEXT: BL @foo_ifunc, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $w0
22+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
23+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
24+
; CHECK-NEXT: RET_ReallyLR
25+
entry:
26+
%0 = call i32 @foo_ifunc()
27+
ret void
28+
}

0 commit comments

Comments
 (0)