https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/180610
Backport 62d018b87a161bb2797c1ed03a482ffcdc8b162c Requested by: @androm3da >From 3a0d622605ff4f06389d1feeb5196a6bad10990f Mon Sep 17 00:00:00 2001 From: Brian Cain <[email protected]> Date: Mon, 9 Feb 2026 14:45:36 -0600 Subject: [PATCH] [lld][Hexagon] Fix R_HEX_TPREL_11_X relocation on duplex instructions (#179860) findMaskR11() was missing handling for duplex instructions. This caused incorrect encoding when R_HEX_TPREL_11_X relocations were applied to duplex instructions with large TLS offsets. For duplex instructions, the immediate bits are located at positions 20-25 (mask 0x03f00000), not in the standard positions used for non-duplex instructions. This fix adds the isDuplex() check to findMaskR11() to return the correct mask for duplex instruction encodings. (cherry picked from commit 62d018b87a161bb2797c1ed03a482ffcdc8b162c) --- lld/ELF/Arch/Hexagon.cpp | 2 ++ lld/test/ELF/hexagon-tls-ie.s | 36 ++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp index 9b33e78731c97..d6495e12668d7 100644 --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -225,6 +225,8 @@ static uint32_t findMaskR8(uint32_t insn) { } static uint32_t findMaskR11(uint32_t insn) { + if (isDuplex(insn)) + return 0x03f00000; if ((0xff000000 & insn) == 0xa1000000) return 0x060020ff; return 0x06003fe0; diff --git a/lld/test/ELF/hexagon-tls-ie.s b/lld/test/ELF/hexagon-tls-ie.s index ea05279473116..158f4d2ca8981 100644 --- a/lld/test/ELF/hexagon-tls-ie.s +++ b/lld/test/ELF/hexagon-tls-ie.s @@ -1,5 +1,6 @@ # REQUIRES: hexagon -# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t.o +# RUN: rm -rf %t.dir && split-file %s %t.dir +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %t.dir/main.s -o %t.o # RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s # RUN: ld.lld %t.o -o %t ## shared needs -z notext because of the R_HEX_IE_16/32_X(R_GOT) static @@ -11,6 +12,16 @@ # RUN: FileCheck -check-prefix=SHARED %s # RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=RELA %s +## Test R_HEX_TPREL_11_X on duplex instructions with large TLS offset. +## TPREL relocations cannot be used with -shared, so test separately. +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf \ +# RUN: %t.dir/tprel-duplex.s -o %t-duplex.o +# RUN: llvm-readobj -r %t-duplex.o | FileCheck -check-prefix=RELOC-DUPLEX %s +# RUN: ld.lld %t-duplex.o -o %t-duplex +# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t-duplex | \ +# RUN: FileCheck -check-prefix=CHECK-DUPLEX %s + +#--- main.s .globl _start .type _start, @function _start: @@ -76,3 +87,26 @@ c: .globl d d: .word 4 + +#--- tprel-duplex.s +## Test R_HEX_TPREL_11_X on duplex instructions with large TLS offset. +## This exercises the isDuplex() path in findMaskR11(). + .globl _start + .type _start, @function +_start: +# RELOC-DUPLEX: 0x0 R_HEX_TPREL_32_6_X e 0x0 +# RELOC-DUPLEX-NEXT: 0x4 R_HEX_TPREL_11_X e 0x0 +# CHECK-DUPLEX: { immext(#0xfffbffc0) +# CHECK-DUPLEX-NEXT: r2 = add(r2,##-0x40003); memw(r3+#0x0) = #0 } + { + r2 = add(r2,##e@TPREL) + memw(r3+#0) = #0 + } + jumpr r31 + +.section .tbss,"awT",@nobits +.p2align 2 +.space 0xd +.globl e +e: +.space 0x40000 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
