From 6552458c13c3955c2bb6bc9adb7dc8c420633a25 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Sun, 1 Feb 2026 21:25:50 -0800 Subject: [PATCH] [Hexagon] Fix encoding of packets with fixups followed by alignment When a packet containing extended immediates and new-value compare-jump instructions with fixups was followed by a .p2align directive, we would incorrectly add nops to the packet. After reshuffling, the fixup offsets would become invalid, causing corrupted encodings. Fixes round-trip assembly for patterns like: { r18 = ##65536 if (!cmp.gtu(r1,r18.new)) jump:t .L1 } .p2align 4 --- .../MCTargetDesc/HexagonAsmBackend.cpp | 7 +++ llvm/test/MC/Hexagon/newvalue_jump_ext_imm.s | 49 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 llvm/test/MC/Hexagon/newvalue_jump_ext_imm.s diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp index 5a187d22d2baa..ad00b9438c8a1 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -596,6 +596,13 @@ class HexagonAsmBackend : public MCAsmBackend { auto &RF = *Frags[K]; MCInst Inst = RF.getInst(); + // Don't add nops to packets that have fixups, as reshuffling can + // invalidate fixup offsets. + if (!RF.getVarFixups().empty()) { + Size = 0; + break; + } + const bool WouldTraverseLabel = llvm::any_of( Asm->symbols(), [&RF, &Inst, Asm = Asm](MCSymbol const &sym) { uint64_t Offset = 0; diff --git a/llvm/test/MC/Hexagon/newvalue_jump_ext_imm.s b/llvm/test/MC/Hexagon/newvalue_jump_ext_imm.s new file mode 100644 index 0000000000000..b0faf64f4cf42 --- /dev/null +++ b/llvm/test/MC/Hexagon/newvalue_jump_ext_imm.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d - | FileCheck %s +# Test that packets with extended immediates and new-value compare-jumps +# followed by alignment directives are encoded and decoded correctly. + +# CHECK-LABEL: : +# CHECK: immext(#0x10000) +# CHECK-NEXT: r18 = ##0x10000 +# CHECK-NEXT: if (!cmp.gtu(r1,r18.new)) jump:t +test1: + .p2align 4 + { + r18 = ##65536 + if (!cmp.gtu(r1,r18.new)) jump:t .L1 + } + .p2align 4 +.L1: + nop + +# CHECK-LABEL: : +# CHECK: immext(#0x20000) +# CHECK-NEXT: r19 = ##0x20000 +# CHECK-NEXT: if (cmp.eq(r19.new,r2)) jump:nt +test2: + .p2align 4 + { + r19 = ##131072 + if (cmp.eq(r19.new,r2)) jump:nt .L2 + } + .p2align 4 +.L2: + nop + +# CHECK-LABEL: : +# CHECK: allocframe(#0x10) +# CHECK-NEXT: memd(r29+#0x0) = r19:18 +# CHECK: immext(#0x10000) +# CHECK-NEXT: r18 = ##0x10000 +# CHECK-NEXT: if (!cmp.gtu(r1,r18.new)) jump:t +test3: + .p2align 4 + allocframe(#16) + memd(r29+#0) = r19:18 + { + r18 = ##65536 + if (!cmp.gtu(r1,r18.new)) jump:t .L3 + } + .p2align 4 +.L3: + nop