[llvm-branch-commits] [lld] 7ddc1bb - [lld][Hexagon] Fix findMaskR8 missing duplex support (#183936)
Douglas Yung via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 5 11:06:39 PST 2026
Author: Brian Cain
Date: 2026-03-05T19:06:17Z
New Revision: 7ddc1bbf3de93f2b284260e08a08842bd8f39a21
URL: https://github.com/llvm/llvm-project/commit/7ddc1bbf3de93f2b284260e08a08842bd8f39a21
DIFF: https://github.com/llvm/llvm-project/commit/7ddc1bbf3de93f2b284260e08a08842bd8f39a21.diff
LOG: [lld][Hexagon] Fix findMaskR8 missing duplex support (#183936)
findMaskR8() lacked an isDuplex() check, unlike findMaskR6(),
findMaskR11(), and findMaskR16() which all handle duplex instructions.
When the assembler generates R_HEX_8_X on a duplex SA1_addi instruction
(e.g. `{ r0 = add(r0, ##target); memw(r1+#0) = r2 }`), the wrong mask
0x00001fe0 placed relocation bits at [12:5] instead of [25:20],
corrupting the low sub-instruction (e.g. memw became memb).
Add the isDuplex() check returning 0x03f00000, and add a comprehensive
test covering all duplex instruction x relocation type combinations
across findMaskR6, findMaskR8, findMaskR11, and findMaskR16.
(cherry picked from commit 9105d9c24949d8cf9b740cb874027351e7230e70)
Added:
lld/test/ELF/hexagon-duplex-relocs.s
Modified:
lld/ELF/Arch/Hexagon.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index d6495e12668d7..09dee664589b2 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -217,6 +217,8 @@ static uint32_t findMaskR6(Ctx &ctx, uint32_t insn) {
}
static uint32_t findMaskR8(uint32_t insn) {
+ if (isDuplex(insn))
+ return 0x03f00000;
if ((0xff000000 & insn) == 0xde000000)
return 0x00e020e8;
if ((0xff000000 & insn) == 0x3c000000)
diff --git a/lld/test/ELF/hexagon-duplex-relocs.s b/lld/test/ELF/hexagon-duplex-relocs.s
new file mode 100644
index 0000000000000..8d7705517cb34
--- /dev/null
+++ b/lld/test/ELF/hexagon-duplex-relocs.s
@@ -0,0 +1,40 @@
+# REQUIRES: hexagon
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t.o
+# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t | FileCheck %s
+
+## Test R_HEX_8_X relocation on duplex instructions (SA1_addi).
+## findMaskR8() must use the duplex mask 0x03f00000 when parse bits [15:14]
+## are zero. Pair a non-duplex form with a duplex form using the same symbol
+## and verify both resolve to the same address.
+##
+## Duplex paths for the other findMask functions are already covered:
+## findMaskR6: hexagon.s (R_HEX_6_X duplex)
+## findMaskR11: hexagon-tls-ie.s (R_HEX_TPREL_11_X duplex)
+## findMaskR16: hexagon-shared.s (R_HEX_GOT_16_X duplex)
+
+ .globl _start, target
+ .type _start, @function
+_start:
+
+# Non-duplex reference (R_HEX_16_X, via findMaskR16)
+# RELOC: R_HEX_32_6_X target 0x0
+# RELOC-NEXT: R_HEX_16_X target 0x0
+# CHECK: { immext(#
+# CHECK-NEXT: r0 = add(r0,##[[ADDR:0x[0-9a-f]+]]) }
+ r0 = add(r0, ##target)
+
+# Duplex form (R_HEX_8_X, via findMaskR8)
+# RELOC-NEXT: R_HEX_32_6_X target 0x0
+# RELOC-NEXT: R_HEX_8_X target 0x0
+# CHECK-NEXT: { immext(#
+# CHECK-NEXT: r0 = add(r0,##[[ADDR]]); memw(r1+#0x0) = r2 }
+ { r0 = add(r0, ##target)
+ memw(r1+#0) = r2 }
+
+ jumpr r31
+
+target:
+ nop
+ jumpr r31
More information about the llvm-branch-commits
mailing list