[llvm-branch-commits] [lld] release/22.x: [lld][Hexagon] Fix R_HEX_TPREL_11_X relocation on duplex instructions (#179860) (PR #180610)
Cullen Rhodes via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Feb 11 02:07:04 PST 2026
https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/180610
>From 4688b97ecddb5f2217a3b6fa22eef86d3e21088f Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
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 at TPREL)
+ memw(r3+#0) = #0
+ }
+ jumpr r31
+
+.section .tbss,"awT", at nobits
+.p2align 2
+.space 0xd
+.globl e
+e:
+.space 0x40000
More information about the llvm-branch-commits
mailing list