[llvm] [RISCV] Add a Pass for adding %qc.access specifiers (PR #201938)

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 20:56:09 PDT 2026


================
@@ -0,0 +1,229 @@
+//===-- RISCVQCRelaxMarking.cpp - Mark Instructions for QC Relaxations ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass adds access tags to some instructions which are used by the
+// assembler to emit marker relocations, which enable some code-size relaxations
+// for Xqcilo/Xqcili.
+//
+// The pass is looking for the following sequences:
+//
+//   $dst1 = QC_E_LI sym
+//   $dst2 = Load killed $dst1, 0
+//
+//   $dst1 = QC_E_LI sym
+//   Store $dst2, killed $dst1, 0
+//
+// In either case, the Load/Store is modified to become a
+// PseudoQCAccess<Load/Store>, with an additional operand that represents the
+// accessed symbolic address, which will become the contents of a
+// `R_RISCV_QC_ACCESS_*` relocation on the emitted instruction.
+//
+// FIXME: The intention is this pass does not change the size of any
+// instructions, but right now it has to do instruction compression as the
+// CompressPat infrastructure cannot handle compressing the `%qc.access(...)`
+// operand. Symbolic operands are not usually compressible, but this one is as
+// we have relocations for both 32-bit and 16-bit instructions (and the
+// relocation does not care about the fields of the instruction).
+
+#include "RISCV.h"
+#include "RISCVSubtarget.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-qc-relax-marking"
+#define RISCV_QC_RELAX_MARKING_NAME "RISC-V QC Relaxation Marking"
+
+STATISTIC(NumMarked, "Number of Loads/Stores Marked");
+
+namespace {
+
+struct RISCVQCRelaxMarking : public MachineFunctionPass {
+  static char ID;
+
+  bool runOnMachineFunction(MachineFunction &) override;
+
+  RISCVQCRelaxMarking() : MachineFunctionPass(ID) {}
+
+  StringRef getPassName() const override { return RISCV_QC_RELAX_MARKING_NAME; }
+};
+
+} // end namespace
+
+char RISCVQCRelaxMarking::ID = 0;
+
+INITIALIZE_PASS(RISCVQCRelaxMarking, DEBUG_TYPE, RISCV_QC_RELAX_MARKING_NAME,
+                false, false)
+
+/// Returns an instance of the Make Compressible Optimization pass.
+FunctionPass *llvm::createRISCVQCRelaxMarkingPass() {
+  return new RISCVQCRelaxMarking();
+}
+
+static bool isLoad(const MachineInstr &MI) {
----------------
lenary wrote:

My view here is "we can", though as I did it i got into "oh, these are only rv32 base+simm12 offset loads, which might not be very shareable for the canonical predicate for "isLoad". I've made `isBaseLoad` and `isBaseStore` predicates but they're not 1:1 these functions.

https://github.com/llvm/llvm-project/pull/201938


More information about the llvm-commits mailing list