diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 4bdc3f26285..658c5b93e08 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3513,6 +3513,19 @@ loongarch_resolve_pcrel_lo_relocs (loongarch_pcrel_relocs *p)
   return true;
 }
 
+static bfd_vma
+ifunc_got_off (struct elf_link_hash_table *htab,
+	       struct elf_link_hash_entry *h)
+{
+  bfd_vma idx =
+    (h->plt.offset - (htab->splt ? PLT_HEADER_SIZE : 0)) / PLT_ENTRY_SIZE;
+
+  return sec_addr (htab->sgotplt)
+	 + (htab->splt ? GOTPLT_HEADER_SIZE : 0)
+	 + (idx * GOT_ENTRY_SIZE)
+	 - sec_addr (htab->sgot);
+}
+
 static int
 loongarch_elf_relocate_section (struct bfd_link_info *info,
 				bfd *input_bfd, asection *input_section,
@@ -4539,25 +4552,7 @@ loongarch_elf_relocate_section (struct bfd_link_info *info,
 		  /* Hidden symbol not has got entry,
 		   * only got.plt entry so it is (plt - got).  */
 		  if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
-		    {
-		      bfd_vma idx;
-		      if (htab->elf.splt != NULL)
-			{
-			  idx = (h->plt.offset - PLT_HEADER_SIZE)
-			    / PLT_ENTRY_SIZE;
-			  got_off = sec_addr (htab->elf.sgotplt)
-			    + GOTPLT_HEADER_SIZE
-			    + (idx * GOT_ENTRY_SIZE)
-			    - sec_addr (htab->elf.sgot);
-			}
-		      else
-			{
-			  idx = h->plt.offset / PLT_ENTRY_SIZE;
-			  got_off = sec_addr (htab->elf.sgotplt)
-			    + (idx * GOT_ENTRY_SIZE)
-			    - sec_addr (htab->elf.sgot);
-			}
-		    }
+		    got_off = ifunc_got_off (&htab->elf, h);
 
 		  if ((h->got.offset & 1) == 0)
 		    {
@@ -4638,18 +4633,7 @@ loongarch_elf_relocate_section (struct bfd_link_info *info,
 		got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
 
 	      if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
-		{
-		  bfd_vma idx;
-		  if (htab->elf.splt != NULL)
-		    idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
-		  else
-		    idx = h->plt.offset / PLT_ENTRY_SIZE;
-
-		  got_off = sec_addr (htab->elf.sgotplt)
-		    + GOTPLT_HEADER_SIZE
-		    + (idx * GOT_ENTRY_SIZE)
-		    - sec_addr (htab->elf.sgot);
-		}
+		got_off = ifunc_got_off (&htab->elf, h);
 
 	      relocation = got_off + sec_addr (got);
 	    }
diff --git a/ld/testsuite/ld-loongarch-elf/ifunc.exp b/ld/testsuite/ld-loongarch-elf/ifunc.exp
index da33eeb8061..f6c97ae2019 100644
--- a/ld/testsuite/ld-loongarch-elf/ifunc.exp
+++ b/ld/testsuite/ld-loongarch-elf/ifunc.exp
@@ -30,5 +30,13 @@ if [istarget loongarch*-*-*] {
 	    "attr-ifunc-4" \
 	    "attr-ifunc-4.out" \
 	] \
+	[list \
+	    "Run static-ifunc" \
+	    "-static" \
+	    "" \
+	    {static-ifunc.c} \
+	    "static-ifunc" \
+	    "static-ifunc.out" \
+	] \
     ]
 }
diff --git a/ld/testsuite/ld-loongarch-elf/static-ifunc.c b/ld/testsuite/ld-loongarch-elf/static-ifunc.c
new file mode 100644
index 00000000000..c0b1788df7c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/static-ifunc.c
@@ -0,0 +1,27 @@
+int
+f1 ()
+{
+  return 42;
+}
+int
+f2 ()
+{
+  return 47;
+}
+
+void *
+fx ()
+{
+  return f1;
+}
+
+[[gnu::ifunc ("fx")]] int f ();
+
+int
+main ()
+{
+  int (*p) () = f;
+  asm ("# prevent optimization" : "+r"(p));
+  __builtin_printf ("%d\n", p ());
+  return 0;
+}
diff --git a/ld/testsuite/ld-loongarch-elf/static-ifunc.out b/ld/testsuite/ld-loongarch-elf/static-ifunc.out
new file mode 100644
index 00000000000..d81cc0710eb
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/static-ifunc.out
@@ -0,0 +1 @@
+42
