[llvm] [ARM] support -mlong-calls -fPIC on arm32 #39970 (PR #147313)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 01:56:17 PDT 2026


================
@@ -2438,19 +2438,33 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   auto PtrVt = getPointerTy(DAG.getDataLayout());
 
   if (Subtarget->genLongCalls()) {
-    assert((!isPositionIndependent() || TT.isOSWindows()) &&
-           "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.
+    bool isPIC = isPositionIndependent() && !TT.isOSWindows();
+
     if (isa<GlobalAddressSDNode>(Callee)) {
       if (Subtarget->genExecuteOnly()) {
+        // Execute-only forbids constant pools in .text, so use movw/movt.
+        // Note: execute-only may not support fPIC on ARM; this path is only
+        // reached for non-PIC targets.
         if (Subtarget->useMovt())
           ++NumMovwMovt;
         Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
                              DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
+      } else if (isPIC) {
+        // PIC without execute-only: use GOT-based addressing.
+        // DSO-local symbols use a plain PC-relative WrapperPIC;
+        // non-DSO-local symbols additionally load the address from the GOT.
+        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 {
----------------
smithp35 wrote:

It isn't necessary to support ROPI code generation as it didn't work beforehand. It would be good to give a user visible error message that ROPI is not compatible with the option though.

I also mentioned it as the code ROPI uses to access variables could be adapted to call non-preemptible functions without needing a GOT access. That is an optimisation though.

I think we're running into a case where the original implementation of `-mlong-calls` has some problems, like producing non-XO or non position independent code when `-mexecute-only` or `-fropi` is used. Adding `-fPIC` support doesn't make those limitations any worse, but it may mean more people use the option and run into these problems. While I don't think support needs to be added, we should error out if we know they are going to generate incorrect code.


https://github.com/llvm/llvm-project/pull/147313


More information about the llvm-commits mailing list