[v0,4/4] LoongArch: Emit alignment relocations after relaxed instructions

Message ID 20260707174719.1883721-5-mengqinggang@loongson.cn
State New
Headers
Series Emit fewer relocations for linker relaxation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

mengqinggang July 7, 2026, 5:47 p.m. UTC
  Alignment cannot change before relaxed instructions.
Emit alignment relocations only after them.

Similar with https://github.com/llvm/llvm-project/pull/150816.
---
 gas/config/tc-loongarch.c                     |  8 ++-
 .../gas/loongarch/negative_right_shift.d      | 67 +++++++++----------
 .../gas/loongarch/negative_right_shift.s      |  9 ++-
 gas/testsuite/gas/loongarch/relax-align.d     | 46 +++++++++++++
 .../{relax_align.l => relax-align.l}          |  0
 .../{relax_align.s => relax-align.s}          |  6 +-
 gas/testsuite/gas/loongarch/relax-align1.d    |  8 +++
 gas/testsuite/gas/loongarch/relax-align1.s    | 16 +++++
 gas/testsuite/gas/loongarch/relax-align2.d    | 27 +++-----
 gas/testsuite/gas/loongarch/relax-align2.s    |  4 ++
 gas/testsuite/gas/loongarch/relax_align.d     | 52 --------------
 ld/testsuite/ld-undefined/undefined.exp       |  2 -
 12 files changed, 130 insertions(+), 115 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/relax-align.d
 rename gas/testsuite/gas/loongarch/{relax_align.l => relax-align.l} (100%)
 rename gas/testsuite/gas/loongarch/{relax_align.s => relax-align.s} (79%)
 create mode 100644 gas/testsuite/gas/loongarch/relax-align1.d
 create mode 100644 gas/testsuite/gas/loongarch/relax-align1.s
 delete mode 100644 gas/testsuite/gas/loongarch/relax_align.d
  

Patch

diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index ed5d47a0360..e67394c460c 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -2178,6 +2178,11 @@  loongarch_frag_align_code (int n, int max)
   if (!LARCH_opts.relax)
     return false;
 
+  /* Only create an alignment frag if the current section already
+     has relaxed instructions.  */
+  if (!now_seg->sec_flg1)
+    return false;
+
   bfd_vma align_bytes = (bfd_vma) 1 << n;
   bfd_vma worst_case_bytes = align_bytes - 4;
   bfd_vma addend = worst_case_bytes;
@@ -2192,8 +2197,7 @@  loongarch_frag_align_code (int n, int max)
   frag_wane (frag_now);
   frag_new (0);
 
-  /* Mark the current section and frag as linker relaxable.  */
-  now_seg->sec_flg1 = true;
+  /* Mark the current frag as linker relaxable.  */
   frag_now->tc_frag_data.linker_relax = true;
 
   /* If max <= 0, ignore max.
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.d b/gas/testsuite/gas/loongarch/negative_right_shift.d
index 4237710c2b3..9221e61f3ab 100644
--- a/gas/testsuite/gas/loongarch/negative_right_shift.d
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.d
@@ -1,40 +1,33 @@ 
-#as:
+#as: -mrelax
 #objdump: -d
-#skip: loongarch32-*-*
 #warning_output: negative_right_shift.l
 
-.*:     file format .*
-
-
-Disassembly of section \.text:
-
-0+ <directives>:
-   0:	03400000 	nop
-   4:	00000001 	\.word		0x00000001
-   8:	00000001 	\.word		0x00000001
-
-0+c <insns>:
-   c:	02bff9ac 	addi.w      	\$t0, \$t1, -2
-  10:	02fff9ac 	addi.d      	\$t0, \$t1, -2
-  14:	13fff9ac 	addu16i.d   	\$t0, \$t1, -2
-  18:	15ffffcc 	lu12i.w     	\$t0, -2
-  1c:	17ffffcc 	lu32i.d     	\$t0, -2
-  20:	033ff9ac 	lu52i.d     	\$t0, \$t1, -2
-  24:	023ff9ac 	slti        	\$t0, \$t1, -2
-  28:	027ff9ac 	sltui       	\$t0, \$t1, -2
-  2c:	19ffffcc 	pcaddi      	\$t0, -2
-  30:	1dffffcc 	pcaddu12i   	\$t0, -2
-  34:	1fffffcc 	pcaddu18i   	\$t0, -2
-  38:	1bffffcc 	pcalau12i   	\$t0, -2
-  3c:	02bffdac 	addi.w      	\$t0, \$t1, -1
-  40:	02fffdac 	addi.d      	\$t0, \$t1, -1
-  44:	13fffdac 	addu16i.d   	\$t0, \$t1, -1
-  48:	15ffffec 	lu12i.w     	\$t0, -1
-  4c:	17ffffec 	lu32i.d     	\$t0, -1
-  50:	033ffdac 	lu52i.d     	\$t0, \$t1, -1
-  54:	023ffdac 	slti        	\$t0, \$t1, -1
-  58:	027ffdac 	sltui       	\$t0, \$t1, -1
-  5c:	19ffffec 	pcaddi      	\$t0, -1
-  60:	1dffffec 	pcaddu12i   	\$t0, -1
-  64:	1fffffec 	pcaddu18i   	\$t0, -1
-  68:	1bffffec 	pcalau12i   	\$t0, -1
+#...
+.*03400000 	nop
+.*00000001 	\.word		0x00000001
+.*00000001 	\.word		0x00000001
+#...
+.*02bff9ac 	addi.w      	\$t0, \$t1, -2
+.*02fff9ac 	addi.d      	\$t0, \$t1, -2
+.*13fff9ac 	addu16i.d   	\$t0, \$t1, -2
+.*15ffffcc 	lu12i.w     	\$t0, -2
+.*17ffffcc 	lu32i.d     	\$t0, -2
+.*033ff9ac 	lu52i.d     	\$t0, \$t1, -2
+.*023ff9ac 	slti        	\$t0, \$t1, -2
+.*027ff9ac 	sltui       	\$t0, \$t1, -2
+.*19ffffcc 	pcaddi      	\$t0, -2
+.*1dffffcc 	pcaddu12i   	\$t0, -2
+.*1fffffcc 	pcaddu18i   	\$t0, -2
+.*1bffffcc 	pcalau12i   	\$t0, -2
+.*02bffdac 	addi.w      	\$t0, \$t1, -1
+.*02fffdac 	addi.d      	\$t0, \$t1, -1
+.*13fffdac 	addu16i.d   	\$t0, \$t1, -1
+.*15ffffec 	lu12i.w     	\$t0, -1
+.*17ffffec 	lu32i.d     	\$t0, -1
+.*033ffdac 	lu52i.d     	\$t0, \$t1, -1
+.*023ffdac 	slti        	\$t0, \$t1, -1
+.*027ffdac 	sltui       	\$t0, \$t1, -1
+.*19ffffec 	pcaddi      	\$t0, -1
+.*1dffffec 	pcaddu12i   	\$t0, -1
+.*1fffffec 	pcaddu18i   	\$t0, -1
+.*1bffffec 	pcalau12i   	\$t0, -1
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.s b/gas/testsuite/gas/loongarch/negative_right_shift.s
index c6a8a1e7c6e..302dba1fb8f 100644
--- a/gas/testsuite/gas/loongarch/negative_right_shift.s
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.s
@@ -1,9 +1,12 @@ 
-directives:
+.text
+call .text
+
+directives: # unsigned shift
 .align	  -1>>62
 .word	  -1>>63
 .4byte	  -1>>63
 
-insns:
+insns: #signed left shift
 addi.w	  $t0, $t1, -1<<1
 addi.d	  $t0, $t1, -1<<1
 addu16i.d $t0, $t1, -1<<1
@@ -17,7 +20,7 @@  pcaddu12i $t0, -1<<1
 pcaddu18i $t0, -1<<1
 pcalau12i $t0, -1<<1
 
-# warn
+# warn signed right shift
 addi.w	  $t0, $t1, -1>>63
 addi.d	  $t0, $t1, -1>>63
 addu16i.d $t0, $t1, -1>>63
diff --git a/gas/testsuite/gas/loongarch/relax-align.d b/gas/testsuite/gas/loongarch/relax-align.d
new file mode 100644
index 00000000000..8e61da5c217
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align.d
@@ -0,0 +1,46 @@ 
+#as: -mrelax
+#objdump: -dr
+#warning_output: relax-align.l
+
+#...
+[ 	]+8:[ 	]+4c000020[ 	]+ret
+[ 	]+c:[ 	]+03400000[ 	]+nop
+[ 	]+c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+10:[ 	]+03400000[ 	]+nop
+[ 	]+14:[ 	]+03400000[ 	]+nop
+[ 	]+18:[ 	]+4c000020[ 	]+ret
+[ 	]+1c:[ 	]+03400000[ 	]+nop
+[ 	]+1c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+20:[ 	]+03400000[ 	]+nop
+[ 	]+24:[ 	]+03400000[ 	]+nop
+[ 	]+28:[ 	]+4c000020[ 	]+ret
+[ 	]+2c:[ 	]+03400000[ 	]+nop
+[ 	]+2c:[ 	]+R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0x104
+[ 	]+30:[ 	]+03400000[ 	]+nop
+[ 	]+34:[ 	]+03400000[ 	]+nop
+[ 	]+38:[ 	]+4c000020[ 	]+ret
+[ 	]+3c:[ 	]+03400000[ 	]+nop
+[ 	]+3c:[ 	]+R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0xb04
+[ 	]+40:[ 	]+03400000[ 	]+nop
+[ 	]+44:[ 	]+03400000[ 	]+nop
+[ 	]+48:[ 	]+4c000020[ 	]+ret
+[ 	]+4c:[ 	]+03400000[ 	]+nop
+[ 	]+4c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+50:[ 	]+03400000[ 	]+nop
+[ 	]+54:[ 	]+03400000[ 	]+nop
+[ 	]+58:[ 	]+4c000020[ 	]+ret
+[ 	]+5c:[ 	]+03400000[ 	]+nop
+[ 	]+5c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+60:[ 	]+03400000[ 	]+nop
+[ 	]+64:[ 	]+03400000[ 	]+nop
+[ 	]+68:[ 	]+4c000020[ 	]+ret
+[ 	]+6c:[ 	]+03400000[ 	]+nop
+[ 	]+6c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+70:[ 	]+03400000[ 	]+nop
+[ 	]+74:[ 	]+03400000[ 	]+nop
+[ 	]+78:[ 	]+4c000020[ 	]+ret
+[ 	]+7c:[ 	]+03400000[ 	]+nop
+[ 	]+7c:[ 	]+R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
+[ 	]+80:[ 	]+03400000[ 	]+nop
+[ 	]+84:[ 	]+03400000[ 	]+nop
+[ 	]+88:[ 	]+4c000020[ 	]+ret
diff --git a/gas/testsuite/gas/loongarch/relax_align.l b/gas/testsuite/gas/loongarch/relax-align.l
similarity index 100%
rename from gas/testsuite/gas/loongarch/relax_align.l
rename to gas/testsuite/gas/loongarch/relax-align.l
diff --git a/gas/testsuite/gas/loongarch/relax_align.s b/gas/testsuite/gas/loongarch/relax-align.s
similarity index 79%
rename from gas/testsuite/gas/loongarch/relax_align.s
rename to gas/testsuite/gas/loongarch/relax-align.s
index 079f549895c..be78f4c3687 100644
--- a/gas/testsuite/gas/loongarch/relax_align.s
+++ b/gas/testsuite/gas/loongarch/relax-align.s
@@ -1,6 +1,6 @@ 
 # Range of max: 0<= max <= 0xffffffff
-  .text
-.L1:
+.text
+  call .text
   ret
   .align 4
   ret
@@ -14,7 +14,7 @@ 
   ret
   .align 4, , 0xffffffff
   ret
-# ignore out of range alignment maxumum
+  # ignore out of range alignment maxumum
   .align 4, , -1
   ret
   .align 4, , -0x80000000
diff --git a/gas/testsuite/gas/loongarch/relax-align1.d b/gas/testsuite/gas/loongarch/relax-align1.d
new file mode 100644
index 00000000000..13576df9dca
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align1.d
@@ -0,0 +1,8 @@ 
+#as: -mrelax
+#objdump: -dr
+
+#...
+.*10: R_LARCH_ALIGN.*0x4
+#...
+.*10: R_LARCH_ALIGN.*0x4
+#...
diff --git a/gas/testsuite/gas/loongarch/relax-align1.s b/gas/testsuite/gas/loongarch/relax-align1.s
new file mode 100644
index 00000000000..dfb9342d507
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align1.s
@@ -0,0 +1,16 @@ 
+# Emit align relocation only if the current section
+# already has relaxed instrctions.
+.text
+  addi.d $t0, $t0, 1
+  .align 3 # Do not emit an align relocation
+  call .text
+  .align 3 # Emit an align relocation
+  addi.d $t0, $t0, 1
+
+.section ".text.a", "ax"
+  addi.d $t0, $t0, 1
+  .align 3 # Do not emit an align relocation
+  call .text
+  .align 3 # Emit an align relocation
+  addi.d $t0, $t0, 1
+
diff --git a/gas/testsuite/gas/loongarch/relax-align2.d b/gas/testsuite/gas/loongarch/relax-align2.d
index cbef84f8777..516091a5735 100644
--- a/gas/testsuite/gas/loongarch/relax-align2.d
+++ b/gas/testsuite/gas/loongarch/relax-align2.d
@@ -1,24 +1,19 @@ 
 #as: --no-warn
 #readelf: -rsW
-#skip: loongarch32-*-*
 
-Relocation section '\.rela\.text' at offset .* contains 2 entries:
-.*
-0+04[ 	]+0000000000000066[ 	]+R_LARCH_ALIGN[ 	]+c
-0+14[ 	]+0000000500000066[ 	]+R_LARCH_ALIGN[ 	]+0+[ 	]+\.Lla-relax-align \+ 404
-
-Relocation section '\.rela\.text2' at offset .* contains 2 entries:
-.*
-0+04[ 	]+0000000000000066[ 	]+R_LARCH_ALIGN[ 	]+c
-0+14[ 	]+0000000600000066[ 	]+R_LARCH_ALIGN[ 	]+0+[ 	]+\.Lla-relax-align \+ 404
-
-Symbol table '\.symtab' contains .* entries:
 #...
-[ 	]+.*:[ 	]+0+[ 	]+0[ 	]+SECTION[ 	]+LOCAL[ 	]+DEFAULT[ 	]+1[ 	]+\.text
+Relocation section '\.rela\.text'.*
 #...
-[ 	]+.*:[ 	]+0+[ 	]+0[ 	]+SECTION[ 	]+LOCAL[ 	]+DEFAULT[ 	]+5[ 	]+\.text2
+.*R_LARCH_ALIGN.*c
+.*R_LARCH_ALIGN.*\.Lla-relax-align.*404
 #...
-[ 	]+.*:[ 	]+0+[ 	]+0[ 	]+NOTYPE[ 	]+LOCAL[ 	]+DEFAULT[ 	]+1[ 	]+\.Lla-relax-align
+Relocation section '\.rela\.text2'.*
+#...
+.*R_LARCH_ALIGN.*c
+.*R_LARCH_ALIGN.*\.Lla-relax-align.*404
+#...
+Symbol table '\.symtab' contains .* entries:
 #...
-[ 	]+.*:[ 	]+0+[ 	]+0[ 	]+NOTYPE[ 	]+LOCAL[ 	]+DEFAULT[ 	]+5[ 	]+\.Lla-relax-align
+.*1.*\.Lla-relax-align
+.*5.*\.Lla-relax-align
 #pass
diff --git a/gas/testsuite/gas/loongarch/relax-align2.s b/gas/testsuite/gas/loongarch/relax-align2.s
index 6cd6bd8731b..4e73d47bf7a 100644
--- a/gas/testsuite/gas/loongarch/relax-align2.s
+++ b/gas/testsuite/gas/loongarch/relax-align2.s
@@ -1,10 +1,14 @@ 
+# Make align symbol .Lla-relax-align in same section with .align
+
 .section ".text", "ax"
+call .text
 nop
 .align 4
 nop
 .align 4, , 4
 
 .section ".text2", "ax"
+call .text
 nop
 .align 4
 nop
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
deleted file mode 100644
index a92df37c636..00000000000
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ /dev/null
@@ -1,52 +0,0 @@ 
-#as:
-#objdump: -dr
-#skip: loongarch32-*-*
-#warning_output: relax_align.l
-
-.*:[    ]+file format .*
-
-
-Disassembly of section .text:
-
-[ 	]*0000000000000000 <.Lla-relax-align>:
-[ 	]+0:[ 	]+4c000020[ 	]+ret
-[ 	]+4:[ 	]+03400000[ 	]+nop
-[ 	]+4: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+8:[ 	]+03400000[ 	]+nop
-[ 	]+c:[ 	]+03400000[ 	]+nop
-[ 	]+10:[ 	]+4c000020[ 	]+ret
-[ 	]+14:[ 	]+03400000[ 	]+nop
-[ 	]+14: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+18:[ 	]+03400000[ 	]+nop
-[ 	]+1c:[ 	]+03400000[ 	]+nop
-[ 	]+20:[ 	]+4c000020[ 	]+ret
-[ 	]+24:[ 	]+03400000[ 	]+nop
-[ 	]+24: R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0x104
-[ 	]+28:[ 	]+03400000[ 	]+nop
-[ 	]+2c:[ 	]+03400000[ 	]+nop
-[ 	]+30:[ 	]+4c000020[ 	]+ret
-[ 	]+34:[ 	]+03400000[ 	]+nop
-[ 	]+34: R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0xb04
-[ 	]+38:[ 	]+03400000[ 	]+nop
-[ 	]+3c:[ 	]+03400000[ 	]+nop
-[ 	]+40:[ 	]+4c000020[ 	]+ret
-[ 	]+44:[ 	]+03400000[ 	]+nop
-[ 	]+44: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+48:[ 	]+03400000[ 	]+nop
-[ 	]+4c:[ 	]+03400000[ 	]+nop
-[ 	]+50:[ 	]+4c000020[ 	]+ret
-[ 	]+54:[ 	]+03400000[ 	]+nop
-[ 	]+54: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+58:[ 	]+03400000[ 	]+nop
-[ 	]+5c:[ 	]+03400000[ 	]+nop
-[ 	]+60:[ 	]+4c000020[ 	]+ret
-[ 	]+64:[ 	]+03400000[ 	]+nop
-[ 	]+64: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+68:[ 	]+03400000[ 	]+nop
-[ 	]+6c:[ 	]+03400000[ 	]+nop
-[ 	]+70:[ 	]+4c000020[ 	]+ret
-[ 	]+74:[ 	]+03400000[ 	]+nop
-[ 	]+74: R_LARCH_ALIGN[ 	]+\*ABS\*\+0xc
-[ 	]+78:[ 	]+03400000[ 	]+nop
-[ 	]+7c:[ 	]+03400000[ 	]+nop
-[ 	]+80:[ 	]+4c000020[ 	]+ret
diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp
index 45c70b4732b..d4ea14e105c 100644
--- a/ld/testsuite/ld-undefined/undefined.exp
+++ b/ld/testsuite/ld-undefined/undefined.exp
@@ -74,7 +74,6 @@  if { ![check_compiler_available] } {
     # in a literal pool outside the function, so that both the
     # "undefined function" and "undefined line" tests fail.
     setup_xfail xtensa*-*-linux*
-    setup_xfail loongarch*-*-*
 
     set mf "tmpdir/undefined.o* in function `function':"
     checkund $mf $testfn
@@ -155,7 +154,6 @@  if { ![check_compiler_available] } {
 
     # eBPF doesn't support dwarf yet.
     setup_xfail bpf-*-*
-    setup_xfail loongarch*-*-*
 
     checkund $ml $testline
 }