[llvm] [ARM] mlong-calls generate PIC code using GOT #39970 (PR #147313)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 07:54:39 PDT 2025
https://github.com/jiangxuezhi created https://github.com/llvm/llvm-project/pull/147313
supoort -mlong-calls -fPIC using GOT
try fixing issuse https://github.com/llvm/llvm-project/issues/39970 and maybe helpful for soving the problem encourted in https://github.com/llvm/llvm-project/pull/142982
>From 33f64ac9794cd665d0aab83cc6221857f1b7c29b Mon Sep 17 00:00:00 2001
From: jiangxuezhi <jiangxuezhi2 at huawei.com>
Date: Mon, 7 Jul 2025 22:34:02 +0800
Subject: [PATCH] [ARM] mlong-calls generate PIC code using GOT #39970
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 16 +++++++++----
llvm/test/CodeGen/ARM/long-calls.ll | 32 +++++++++++++++++++++++++
2 files changed, 44 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/ARM/long-calls.ll
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2d73725291d11..b73a53cca84e3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2815,13 +2815,20 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
auto PtrVt = getPointerTy(DAG.getDataLayout());
if (Subtarget->genLongCalls()) {
- assert((!isPositionIndependent() || Subtarget->isTargetWindows()) &&
- "long-calls codegen is not position independent!");
// Handle a global address or an external symbol. If it's not one of
// those, the target's already in a register, so we don't need to do
// anything extra.
if (isa<GlobalAddressSDNode>(Callee)) {
- if (Subtarget->genExecuteOnly()) {
+ if (isPositionIndependent() && !Subtarget->isTargetWindows() &&
+ !Subtarget->genExecuteOnly()) {
+ SDValue G = DAG.getTargetGlobalAddress(
+ GVal, dl, PtrVt, 0, GVal->isDSOLocal() ? 0 : ARMII::MO_GOT);
+ Callee = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVt, G);
+ if (!GVal->isDSOLocal())
+ Callee =
+ DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
+ MachinePointerInfo::getGOT(DAG.getMachineFunction()));
+ } else if (Subtarget->genExecuteOnly()) {
if (Subtarget->useMovt())
++NumMovwMovt;
Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
@@ -2839,7 +2846,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
PtrVt, dl, DAG.getEntryNode(), Addr,
MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
}
- } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ } else if (ExternalSymbolSDNode *S =
+ dyn_cast<ExternalSymbolSDNode>(Callee)) {
const char *Sym = S->getSymbol();
if (Subtarget->genExecuteOnly()) {
diff --git a/llvm/test/CodeGen/ARM/long-calls.ll b/llvm/test/CodeGen/ARM/long-calls.ll
new file mode 100644
index 0000000000000..41763801fddd2
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/long-calls.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=armv7-unknown-linux-gnueabi -relocation-model pic -mattr=+long-calls -o - %s \
+; RUN: | FileCheck %s
+
+ at msg = private unnamed_addr constant [12 x i8] c"hello world\00", align 1
+
+declare i32 @puts(ptr)
+
+define void @test() {
+; CHECK-LABEL: test:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: .save {r11, lr}
+; CHECK-NEXT: push {r11, lr}
+; CHECK-NEXT: ldr r0, .LCPI0_0
+; CHECK-NEXT: ldr r1, .LCPI0_1
+; CHECK-NEXT: .LPC0_0:
+; CHECK-NEXT: add r0, pc, r0
+; CHECK-NEXT: .LPC0_1:
+; CHECK-NEXT: ldr r1, [pc, r1]
+; CHECK-NEXT: blx r1
+; CHECK-NEXT: pop {r11, pc}
+; CHECK-NEXT: .p2align 2
+; CHECK-NEXT: @ %bb.1:
+; CHECK-NEXT: .LCPI0_0:
+; CHECK-NEXT: .long .Lmsg-(.LPC0_0+8)
+; CHECK-NEXT: .LCPI0_1:
+; CHECK-NEXT: .Ltmp0:
+; CHECK-NEXT: .long puts(GOT_PREL)-(.LPC0_1+8-.Ltmp0)
+entry:
+ %call = call i32 @puts(ptr @msg)
+ ret void
+}
More information about the llvm-commits
mailing list