Skip to content

Conversation

lenary
Copy link
Member

@lenary lenary commented Oct 3, 2025

With Xqcili, c.li may be relaxed to qc.e.li (this is because qc.e.li is compressed into c.li, which needs to be undone). qc.e.li is relaxable, so we need to mark c.li as linker relaxable when it is emitted.

This fixup cannot be emitted as a relocation, but we still mark it as requiring no R_RISCV_RELAX in case this changes in the future.

With Xqcili, `c.li` may be relaxed to `qc.e.li` (this is because
`qc.e.li` is compressed into `c.li`, which needs to be undone).
`qc.e.li` is relaxable, so we need to mark `c.li` as linker relaxable
when it is emitted.

This fixup cannot be emitted as a relocation, but we still mark it as
requiring no R_RISCV_RELAX in case this changes in the future.
@llvmbot
Copy link
Member

llvmbot commented Oct 3, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Sam Elliott (lenary)

Changes

With Xqcili, c.li may be relaxed to qc.e.li (this is because qc.e.li is compressed into c.li, which needs to be undone). qc.e.li is relaxable, so we need to mark c.li as linker relaxable when it is emitted.

This fixup cannot be emitted as a relocation, but we still mark it as requiring no R_RISCV_RELAX in case this changes in the future.


Full diff: https://github.com/llvm/llvm-project/pull/161797.diff

3 Files Affected:

  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+1)
  • (added) llvm/test/MC/RISCV/xqcili-linker-relaxation.s (+43)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 41a9c92cf99c3..96e8afca0680e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -823,6 +823,7 @@ static bool relaxableFixupNeedsRelocation(const MCFixupKind Kind) {
     break;
   case RISCV::fixup_riscv_rvc_jump:
   case RISCV::fixup_riscv_rvc_branch:
+  case RISCV::fixup_riscv_rvc_imm:
   case RISCV::fixup_riscv_jal:
     return false;
   }
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 6d587e6f167fc..5934c91cb4b9a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -688,6 +688,7 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
       // the `jal` again in the assembler.
     } else if (MIFrm == RISCVII::InstFormatCI) {
       FixupKind = RISCV::fixup_riscv_rvc_imm;
+      AsmRelaxToLinkerRelaxableWithFeature(RISCV::FeatureVendorXqcili);
     } else if (MIFrm == RISCVII::InstFormatI) {
       FixupKind = RISCV::fixup_riscv_12_i;
     } else if (MIFrm == RISCVII::InstFormatQC_EB) {
diff --git a/llvm/test/MC/RISCV/xqcili-linker-relaxation.s b/llvm/test/MC/RISCV/xqcili-linker-relaxation.s
new file mode 100644
index 0000000000000..63bb17859776a
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcili-linker-relaxation.s
@@ -0,0 +1,43 @@
+
+# RUN: llvm-mc --triple=riscv32 -mattr=+relax,+experimental-xqcili \
+# RUN:    %s -filetype=obj -o - -riscv-add-build-attributes \
+# RUN:    | llvm-objdump -dr -M no-aliases - \
+# RUN:    | FileCheck %s
+
+## This tests that we correctly emit relocations for linker relaxation when
+## emitting `QC.E.LI` and `QC.LI`.
+
+  .section .text.ex1, "ax", @progbits
+  .global ex1
+ex1:
+# CHECK-LABEL: <ex1>:
+  blez    a1, .L1
+# CHECK-NEXT: bge zero, a1, 0x0 <ex1>
+# CHECK-NEXT: R_RISCV_BRANCH .L1{{$}}
+  qc.e.li a0, sym
+# CHECK-NEXT: qc.e.li a0, 0x0
+# CHECK-NEXT: R_RISCV_VENDOR QUALCOMM{{$}}
+# CHECK-NEXT: R_RISCV_CUSTOM194 sym{{$}}
+# CHECK-NEXT: R_RISCV_RELAX *ABS*{{$}}
+.L1:
+# CHECK: <.L1>:
+  ret
+# CHECK-NEXT: c.jr ra
+
+
+  .section .text.ex2, "ax", @progbits
+  .global ex2
+ex2:
+# CHECK-LABEL: <ex2>:
+  blez    a1, .L2
+# CHECK-NEXT: bge zero, a1, 0x0 <ex2>
+# CHECK-NEXT: R_RISCV_BRANCH .L2{{$}}
+  qc.li a0,  %qc.abs20(sym)
+# CHECK-NEXT: qc.li a0, 0x0
+# CHECK-NEXT: R_RISCV_VENDOR QUALCOMM{{$}}
+# CHECK-NEXT: R_RISCV_CUSTOM192 sym{{$}}
+# CHECK-NEXT: R_RISCV_RELAX *ABS*{{$}}
+.L2:
+# CHECK: <.L2>:
+  ret
+# CHECK-NEXT: c.jr ra

Copy link
Contributor

@svs-quic svs-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@@ -0,0 +1,43 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneeded blank line

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

## emitting `QC.E.LI` and `QC.LI`.

.section .text.ex1, "ax", @progbits
.global ex1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need a global symbol at offset 0 for the anchor. if you omit it, you can use <.text.ex1>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@lenary lenary requested a review from MaskRay October 6, 2025 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants