-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LoongArch] Fix GOT usage for non-dso_local
function calls in large code model
#117134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-loongarch Author: wanglei (wangleiat) ChangesThis commit fixes an issue in the large code model where non-dso_local function calls did not use the GOT as expected in PIC mode. Instead, direct PC-relative access was incorrectly applied, leading to linker errors when building shared libraries. For Cherry-picked from #117099, used for fix linker errors when bulding shared libraries with large code model. Full diff: https://github.com/llvm/llvm-project/pull/117134.diff 5 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index c136f5b3e515d7..e680dda7374d07 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -721,7 +721,7 @@ bool LoongArchExpandPseudo::expandFunctionCALL(
IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
Register AddrReg = IsTailCall ? LoongArch::R19 : LoongArch::R1;
- bool UseGOT = Func.isGlobal() && !Func.getGlobal()->isDSOLocal();
+ bool UseGOT = Func.getTargetFlags() == LoongArchII::MO_CALL_PLT;
unsigned MO = UseGOT ? LoongArchII::MO_GOT_PC_HI : LoongArchII::MO_PCREL_LO;
unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
expandLargeAddressLoad(MBB, MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
diff --git a/llvm/test/CodeGen/LoongArch/code-models.ll b/llvm/test/CodeGen/LoongArch/code-models.ll
index 4b2b72afaee171..4eb1e5e596fd3f 100644
--- a/llvm/test/CodeGen/LoongArch/code-models.ll
+++ b/llvm/test/CodeGen/LoongArch/code-models.ll
@@ -82,11 +82,11 @@ define void @call_external_sym(ptr %dst) {
; LARGE-NEXT: .cfi_offset 1, -8
; LARGE-NEXT: ori $a2, $zero, 1000
; LARGE-NEXT: move $a1, $zero
-; LARGE-NEXT: pcalau12i $ra, %pc_hi20(memset)
-; LARGE-NEXT: addi.d $t8, $zero, %pc_lo12(memset)
-; LARGE-NEXT: lu32i.d $t8, %pc64_lo20(memset)
-; LARGE-NEXT: lu52i.d $t8, $t8, %pc64_hi12(memset)
-; LARGE-NEXT: add.d $ra, $t8, $ra
+; LARGE-NEXT: pcalau12i $ra, %got_pc_hi20(memset)
+; LARGE-NEXT: addi.d $t8, $zero, %got_pc_lo12(memset)
+; LARGE-NEXT: lu32i.d $t8, %got64_pc_lo20(memset)
+; LARGE-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(memset)
+; LARGE-NEXT: ldx.d $ra, $t8, $ra
; LARGE-NEXT: jirl $ra, $ra, 0
; LARGE-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
; LARGE-NEXT: addi.d $sp, $sp, 16
diff --git a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
index ed1a24e82b4e46..29348fe0d641ed 100644
--- a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
+++ b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
@@ -282,11 +282,11 @@ define void @test_la_tls_ld(i32 signext %n) {
; LA64LARGE-NEXT: .LBB3_1: # %loop
; LA64LARGE-NEXT: # =>This Inner Loop Header: Depth=1
; LA64LARGE-NEXT: move $a0, $s0
-; LA64LARGE-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LA64LARGE-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LA64LARGE-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LA64LARGE-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LA64LARGE-NEXT: add.d $ra, $t8, $ra
+; LA64LARGE-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LA64LARGE-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LA64LARGE-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LA64LARGE-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LA64LARGE-NEXT: ldx.d $ra, $t8, $ra
; LA64LARGE-NEXT: jirl $ra, $ra, 0
; LA64LARGE-NEXT: ld.w $zero, $a0, 0
; LA64LARGE-NEXT: addi.w $s1, $s1, 1
@@ -448,11 +448,11 @@ define void @test_la_tls_gd(i32 signext %n) nounwind {
; LA64LARGE-NEXT: .LBB5_1: # %loop
; LA64LARGE-NEXT: # =>This Inner Loop Header: Depth=1
; LA64LARGE-NEXT: move $a0, $s0
-; LA64LARGE-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LA64LARGE-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LA64LARGE-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LA64LARGE-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LA64LARGE-NEXT: add.d $ra, $t8, $ra
+; LA64LARGE-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LA64LARGE-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LA64LARGE-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LA64LARGE-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LA64LARGE-NEXT: ldx.d $ra, $t8, $ra
; LA64LARGE-NEXT: jirl $ra, $ra, 0
; LA64LARGE-NEXT: ld.w $zero, $a0, 0
; LA64LARGE-NEXT: addi.w $s1, $s1, 1
diff --git a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll b/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
index 6a15d3a9cda307..75f494f32e476b 100644
--- a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
+++ b/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
@@ -105,11 +105,11 @@ define void @foo() nounwind {
; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(gd)
; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(gd)
; LARGE_NO_SCH-NEXT: add.d $a0, $t8, $a0
-; LARGE_NO_SCH-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: add.d $ra, $t8, $ra
+; LARGE_NO_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: ldx.d $ra, $t8, $ra
; LARGE_NO_SCH-NEXT: jirl $ra, $ra, 0
; LARGE_NO_SCH-NEXT: ld.d $zero, $a0, 0
; LARGE_NO_SCH-NEXT: pcalau12i $a0, %ld_pc_hi20(ld)
@@ -117,11 +117,11 @@ define void @foo() nounwind {
; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(ld)
; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(ld)
; LARGE_NO_SCH-NEXT: add.d $a0, $t8, $a0
-; LARGE_NO_SCH-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LARGE_NO_SCH-NEXT: add.d $ra, $t8, $ra
+; LARGE_NO_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LARGE_NO_SCH-NEXT: ldx.d $ra, $t8, $ra
; LARGE_NO_SCH-NEXT: jirl $ra, $ra, 0
; LARGE_NO_SCH-NEXT: pcalau12i $a1, %ie_pc_hi20(ie)
; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie)
@@ -162,11 +162,11 @@ define void @foo() nounwind {
; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(gd)
; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(gd)
; LARGE_SCH-NEXT: add.d $a0, $t8, $a0
-; LARGE_SCH-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LARGE_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LARGE_SCH-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LARGE_SCH-NEXT: add.d $ra, $t8, $ra
+; LARGE_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LARGE_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LARGE_SCH-NEXT: ldx.d $ra, $t8, $ra
; LARGE_SCH-NEXT: jirl $ra, $ra, 0
; LARGE_SCH-NEXT: ld.d $zero, $a0, 0
; LARGE_SCH-NEXT: pcalau12i $a0, %ld_pc_hi20(ld)
@@ -174,11 +174,11 @@ define void @foo() nounwind {
; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(ld)
; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(ld)
; LARGE_SCH-NEXT: add.d $a0, $t8, $a0
-; LARGE_SCH-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LARGE_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LARGE_SCH-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LARGE_SCH-NEXT: add.d $ra, $t8, $ra
+; LARGE_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LARGE_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LARGE_SCH-NEXT: ldx.d $ra, $t8, $ra
; LARGE_SCH-NEXT: jirl $ra, $ra, 0
; LARGE_SCH-NEXT: pcalau12i $a1, %ie_pc_hi20(ie)
; LARGE_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie)
diff --git a/llvm/test/CodeGen/LoongArch/tls-models.ll b/llvm/test/CodeGen/LoongArch/tls-models.ll
index bb89794d1c843c..04600ffeb37ee7 100644
--- a/llvm/test/CodeGen/LoongArch/tls-models.ll
+++ b/llvm/test/CodeGen/LoongArch/tls-models.ll
@@ -55,11 +55,11 @@ define ptr @f1() nounwind {
; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(unspecified)
; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(unspecified)
; LA64LARGEPIC-NEXT: add.d $a0, $t8, $a0
-; LA64LARGEPIC-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LA64LARGEPIC-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LA64LARGEPIC-NEXT: add.d $ra, $t8, $ra
+; LA64LARGEPIC-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LA64LARGEPIC-NEXT: ldx.d $ra, $t8, $ra
; LA64LARGEPIC-NEXT: jirl $ra, $ra, 0
; LA64LARGEPIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
; LA64LARGEPIC-NEXT: addi.d $sp, $sp, 16
@@ -169,11 +169,11 @@ define ptr @f2() nounwind {
; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(ld)
; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(ld)
; LA64LARGEPIC-NEXT: add.d $a0, $t8, $a0
-; LA64LARGEPIC-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr)
-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr)
-; LA64LARGEPIC-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr)
-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr)
-; LA64LARGEPIC-NEXT: add.d $ra, $t8, $ra
+; LA64LARGEPIC-NEXT: pcalau12i $ra, %got_pc_hi20(__tls_get_addr)
+; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(__tls_get_addr)
+; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(__tls_get_addr)
+; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(__tls_get_addr)
+; LA64LARGEPIC-NEXT: ldx.d $ra, $t8, $ra
; LA64LARGEPIC-NEXT: jirl $ra, $ra, 0
; LA64LARGEPIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
; LA64LARGEPIC-NEXT: addi.d $sp, $sp, 16
|
… code model This commit fixes an issue in the large code model where non-dso_local function calls did not use the GOT as expected in PIC mode. Instead, direct PC-relative access was incorrectly applied, leading to linker errors when building shared libraries. For `ExternalSymbol`, it is not possible to determine whether it is dso_local during pseudo-instruction expansion. We use target flags to differentiate whether GOT should be used. Cherry-picked from llvm#117099, used for fix linker errors when bulding shared libraries with large code model.
@wangleiat (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
This commit fixes an issue in the large code model where non-dso_local function calls did not use the GOT as expected in PIC mode. Instead, direct PC-relative access was incorrectly applied, leading to linker errors when building shared libraries.
For
ExternalSymbol
, it is not possible to determine whether it is dso_local during pseudo-instruction expansion. We use target flags to differentiate whether GOT should be used.Cherry-picked from #117099, used for fix linker errors when bulding shared libraries with large code model.