[llvm] 1d2f5ea - [RISCV] Add symbol parsing support for Xqcili load large immediate instructions (#134581)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 22:56:30 PDT 2025


Author: Sudharsan Veeravalli
Date: 2025-04-08T22:56:26-07:00
New Revision: 1d2f5ead05e85057b8d0c6198203b392e9f855f8

URL: https://github.com/llvm/llvm-project/commit/1d2f5ead05e85057b8d0c6198203b392e9f855f8
DIFF: https://github.com/llvm/llvm-project/commit/1d2f5ead05e85057b8d0c6198203b392e9f855f8.diff

LOG: [RISCV] Add symbol parsing support for Xqcili load large immediate instructions (#134581)

This patch adds support for parsing symbols in the Xqcili load large
immediate instructions. The 32 bit `qc.li` instructions uses the
`R_RISCV_QC_ABS20_U` relocation while the 48 bit `qc.e.li` instruction
uses the `R_RISCV_QC_E_32` relocation and the `InstFormatQC_EAI`
instruction format.

Vendor relocation support will be added in a later patch.

Added: 
    llvm/test/MC/RISCV/xqcili-relocations.s

Modified: 
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
    llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
    llvm/test/MC/RISCV/xqcili-invalid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 94d3bb1f10daf..c57c123ab01dc 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -551,6 +551,21 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return IsValid && VK == RISCVMCExpr::VK_None;
   }
 
+  // True if operand is a symbol with no modifiers, or a constant with no
+  // modifiers and isInt<N>(Op).
+  template <int N> bool isBareSimmN() const {
+    if (!isImm())
+      return false;
+
+    int64_t Imm;
+    if (evaluateConstantImm(getImm(), Imm))
+      return isInt<N>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+    RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+    return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+           VK == RISCVMCExpr::VK_None;
+  }
+
   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
 
   bool isBareSymbol() const {
@@ -794,9 +809,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
   bool isSImm6() const { return isSImm<6>(); }
   bool isSImm11() const { return isSImm<11>(); }
   bool isSImm16() const { return isSImm<16>(); }
-  bool isSImm20() const { return isSImm<20>(); }
   bool isSImm26() const { return isSImm<26>(); }
-  bool isSImm32() const { return isSImm<32>(); }
 
   bool isSImm5NonZero() const {
     return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<5>(Imm); });
@@ -876,6 +889,19 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return isUImmPred([](int64_t Imm) { return isUInt<16>(Imm) && Imm != 0; });
   }
 
+  bool isSImm20LI() const {
+    if (!isImm())
+      return false;
+
+    int64_t Imm;
+    if (evaluateConstantImm(getImm(), Imm))
+      return isInt<20>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+    RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+    return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+           VK == RISCVMCExpr::VK_QC_ABS20;
+  }
+
   bool isUImm20LUI() const {
     if (!isImm())
       return false;
@@ -1519,6 +1545,11 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
         "immediate must be non-zero in the range");
+  case Match_InvalidSImm20LI:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
+        "operand must be a symbol with a %qc.abs20 specifier or an integer "
+        " in the range");
   case Match_InvalidUImm20LUI:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, 0, (1 << 20) - 1,
@@ -1555,10 +1586,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidSImm26:
     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
                                       (1 << 25) - 1);
-  case Match_InvalidSImm20:
-    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),
-                                      (1 << 19) - 1);
-  case Match_InvalidSImm32:
+  case Match_InvalidBareSImm32:
     return generateImmOutOfRangeError(Operands, ErrorInfo,
                                       std::numeric_limits<int32_t>::min(),
                                       std::numeric_limits<uint32_t>::max());

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 6641116db9a19..c6c2e0810b75e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -93,6 +93,8 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0},
       {"fixup_riscv_tlsdesc_call", 0, 0, 0},
       {"fixup_riscv_qc_e_branch", 0, 48, MCFixupKindInfo::FKF_IsPCRel},
+      {"fixup_riscv_qc_e_32", 16, 32, 0},
+      {"fixup_riscv_qc_abs20_u", 12, 20, 0},
   };
   static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
                 "Not all fixup kinds added to Infos array");
@@ -559,7 +561,20 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
             (Bit5 << 2);
     return Value;
   }
-
+  case RISCV::fixup_riscv_qc_e_32: {
+    if (!isInt<32>(Value))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    return ((Value & 0xffffffff) << 16);
+  }
+  case RISCV::fixup_riscv_qc_abs20_u: {
+    if (!isInt<20>(Value))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    unsigned Bit19 = (Value >> 19) & 0x1;
+    unsigned Bit14_0 = Value & 0x7fff;
+    unsigned Bit18_15 = (Value >> 15) & 0xf;
+    Value = (Bit19 << 31) | (Bit14_0 << 16) | (Bit18_15 << 12);
+    return Value;
+  }
   }
 }
 

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 506c638c83a72..84a23de6b1995 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -340,9 +340,9 @@ enum OperandType : unsigned {
   OPERAND_SIMM12_LSB00000,
   OPERAND_SIMM16,
   OPERAND_SIMM16_NONZERO,
-  OPERAND_SIMM20,
+  OPERAND_SIMM20_LI,
   OPERAND_SIMM26,
-  OPERAND_SIMM32,
+  OPERAND_BARE_SIMM32,
   OPERAND_CLUI_IMM,
   OPERAND_VTYPEI10,
   OPERAND_VTYPEI11,

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 5fdf8e23d1214..9859bf39bcc5e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -173,6 +173,10 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
     return ELF::R_RISCV_RELAX;
   case RISCV::fixup_riscv_align:
     return ELF::R_RISCV_ALIGN;
+  case RISCV::fixup_riscv_qc_e_32:
+    return ELF::R_RISCV_QC_E_32;
+  case RISCV::fixup_riscv_qc_abs20_u:
+    return ELF::R_RISCV_QC_ABS20_U;
   }
 }
 

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
index df7916a4490b7..a4f5673fca225 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
@@ -80,6 +80,10 @@ enum Fixups {
   // 12-bit fixup for symbol references in the 48-bit Xqcibi branch immediate
   // instructions
   fixup_riscv_qc_e_branch,
+  // 32-bit fixup for symbol references in the 48-bit qc.e.li instruction
+  fixup_riscv_qc_e_32,
+  // 20-bit fixup for symbol references in the 32-bit qc.li instruction
+  fixup_riscv_qc_abs20_u,
 
   // Used as a sentinel, must be the last
   fixup_riscv_invalid,

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 37a2ac336d20c..95858da45f202 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -653,6 +653,9 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
     case RISCVMCExpr::VK_TLSDESC_CALL:
       FixupKind = RISCV::fixup_riscv_tlsdesc_call;
       break;
+    case RISCVMCExpr::VK_QC_ABS20:
+      FixupKind = RISCV::fixup_riscv_qc_abs20_u;
+      break;
     }
   } else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) {
     // FIXME: Sub kind binary exprs have chance of underflow.
@@ -668,6 +671,8 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
       FixupKind = RISCV::fixup_riscv_12_i;
     } else if (MIFrm == RISCVII::InstFormatQC_EB) {
       FixupKind = RISCV::fixup_riscv_qc_e_branch;
+    } else if (MIFrm == RISCVII::InstFormatQC_EAI) {
+      FixupKind = RISCV::fixup_riscv_qc_e_32;
     }
   }
 

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
index a48dca7be0d28..d6650e156c8b3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
@@ -116,6 +116,7 @@ RISCVMCExpr::getSpecifierForName(StringRef name) {
       .Case("tlsdesc_load_lo", VK_TLSDESC_LOAD_LO)
       .Case("tlsdesc_add_lo", VK_TLSDESC_ADD_LO)
       .Case("tlsdesc_call", VK_TLSDESC_CALL)
+      .Case("qc.abs20", VK_QC_ABS20)
       // Used in data directives
       .Case("pltpcrel", VK_PLTPCREL)
       .Case("gotpcrel", VK_GOTPCREL)
@@ -164,6 +165,8 @@ StringRef RISCVMCExpr::getSpecifierName(Specifier S) {
     return "gotpcrel";
   case VK_PLTPCREL:
     return "pltpcrel";
+  case VK_QC_ABS20:
+    return "qc.abs20";
   }
   llvm_unreachable("Invalid ELF symbol kind");
 }

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
index fd6993c18d820..e0aa7ff244521 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
@@ -43,6 +43,7 @@ class RISCVMCExpr : public MCTargetExpr {
     VK_TLSDESC_LOAD_LO,
     VK_TLSDESC_ADD_LO,
     VK_TLSDESC_CALL,
+    VK_QC_ABS20,
   };
 
 private:

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 44894365b6d41..f8a35533ba952 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2654,9 +2654,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         CASE_OPERAND_SIMM(6)
         CASE_OPERAND_SIMM(11)
         CASE_OPERAND_SIMM(12)
-        CASE_OPERAND_SIMM(20)
         CASE_OPERAND_SIMM(26)
-        CASE_OPERAND_SIMM(32)
         // clang-format on
         case RISCVOp::OPERAND_SIMM5_PLUS1:
           Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
@@ -2673,6 +2671,12 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         case RISCVOp::OPERAND_SIMM12_LSB00000:
           Ok = isShiftedInt<7, 5>(Imm);
           break;
+        case RISCVOp::OPERAND_SIMM20_LI:
+          Ok = isInt<20>(Imm);
+          break;
+        case RISCVOp::OPERAND_BARE_SIMM32:
+          Ok = isInt<32>(Imm);
+          break;
         case RISCVOp::OPERAND_UIMMLOG2XLEN:
           Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
           break;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 651893d9f67cf..78bf6337b4a00 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -103,22 +103,38 @@ def simm16nonzero : RISCVOp<XLenVT>,
   let OperandType = "OPERAND_SIMM16_NONZERO";
 }
 
-def simm20 : RISCVSImmLeafOp<20>;
+def simm20_li : RISCVOp<XLenVT> {
+  let ParserMatchClass = SImmAsmOperand<20, "LI">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<20>";
+  let OperandType = "OPERAND_SIMM20_LI";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (MCOp.evaluateAsConstantImm(Imm))
+      return isInt<20>(Imm);
+    return MCOp.isBareSymbolRef();
+  }];
+}
 
 def simm26 : RISCVSImmLeafOp<26>;
 
+class BareSImmNAsmOperand<int width>
+    : ImmAsmOperand<"BareS", width, ""> {
+  let PredicateMethod = "isBareSimmN<" # width # ">";
+}
+
 // 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no
 // sign-/zero-extension. This is represented internally as a signed 32-bit value.
-def simm32 : RISCVOp<XLenVT> {
-  let ParserMatchClass = SImmAsmOperand<32, "">;
+def bare_simm32 : RISCVOp<XLenVT> {
+  let ParserMatchClass = BareSImmNAsmOperand<32>;
   let EncoderMethod = "getImmOpValue";
   let DecoderMethod = "decodeSImmOperand<32>";
-  let OperandType = "OPERAND_SIMM32";
+  let OperandType = "OPERAND_BARE_SIMM32";
   let MCOperandPredicate = [{
     int64_t Imm;
     if (MCOp.evaluateAsConstantImm(Imm))
       return isInt<32>(Imm);
-    return false;
+    return MCOp.isBareSymbolRef();
   }];
 }
 
@@ -256,7 +272,7 @@ def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd),
                                      (ins uimm7_opcode:$opcode,
                                           uimm3:$func3,
                                           uimm1:$func1,
-                                          simm32:$imm32),
+                                          bare_simm32:$imm32),
                                      "$opcode, $func3, $func1, $rd, $imm32">;
 def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd),
                                    (ins uimm7_opcode:$opcode,
@@ -303,7 +319,7 @@ def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32",
                             uimm7_opcode:$opcode,
                             uimm3:$func3,
                             uimm1:$func1,
-                            simm32:$imm32)>;
+                            bare_simm32:$imm32)>;
 def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26",
                 (InsnQC_EI AnyReg:$rd,
                            uimm7_opcode:$opcode,
@@ -671,7 +687,7 @@ class QCIRVInstESStore<bits<3> funct3, bits<2> funct2, string opcodestr>
                       opcodestr, "$rs2, ${imm}(${rs1})">;
 
 class QCIRVInstEAI<bits<3> funct3, bits<1> funct1, string opcodestr>
-    : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm32:$imm),
+    : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, bare_simm32:$imm),
                opcodestr, "$rd, $imm", [], InstFormatOther> {
   bits<5> rd;
   bits<32> imm;
@@ -1009,15 +1025,15 @@ let Predicates = [HasVendorXqcilb, IsRV32] in {
 
 let Predicates = [HasVendorXqcili, IsRV32] in {
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
-  def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20:$imm20),
+  def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20_li:$imm20),
                       "qc.li", "$rd, $imm20"> {
     let Inst{31} = imm20{19};
     let Inst{30-16} = imm20{14-0};
     let Inst{15-12} = imm20{18-15};
   }
 
-  def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins simm32:$imm),
-                         "qc.e.li", "$rd, $imm", [], InstFormatOther> {
+  def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins bare_simm32:$imm),
+                         "qc.e.li", "$rd, $imm", [], InstFormatQC_EAI> {
     bits<5> rd;
     bits<32> imm;
 

diff  --git a/llvm/test/MC/RISCV/xqcili-invalid.s b/llvm/test/MC/RISCV/xqcili-invalid.s
index 0c4b4f04e86e9..567ed8ba89736 100644
--- a/llvm/test/MC/RISCV/xqcili-invalid.s
+++ b/llvm/test/MC/RISCV/xqcili-invalid.s
@@ -25,7 +25,7 @@ qc.li x0, 114514
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.li x10
 
-# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [-524288, 524287]
+# CHECK-IMM: :[[@LINE+1]]:12: error: operand must be a symbol with a %qc.abs20 specifier or an integer in the range [-524288, 524287]
 qc.li x10, 33554432
 
 # CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension)

diff  --git a/llvm/test/MC/RISCV/xqcili-relocations.s b/llvm/test/MC/RISCV/xqcili-relocations.s
new file mode 100644
index 0000000000000..b0a3f3bae11d5
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcili-relocations.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple riscv32 -mattr=+experimental-xqcili %s -show-encoding \
+# RUN:     | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili %s -o %t.o
+# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
+
+# Check prefixes:
+# RELOC - Check the relocation in the object.
+# FIXUP - Check the fixup on the instruction.
+# INSTR - Check the instruction is handled properly by the ASMPrinter.
+
+.text
+
+qc.li x4, %qc.abs20(foo)
+# RELOC: R_RISCV_CUSTOM192 foo 0x0
+# INSTR: qc.li tp, %qc.abs20(foo)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(foo), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x5, foo
+# RELOC: R_RISCV_CUSTOM194 foo 0x0
+# INSTR: qc.e.li t0, foo
+# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_32
+
+# Check that a label in a 
diff erent section is handled similar to an undefined symbol
+qc.li x9, %qc.abs20(.bar)
+# RELOC: R_RISCV_CUSTOM192 .bar 0x0
+# INSTR: qc.li s1, %qc.abs20(.bar)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(.bar), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x8, .bar
+# RELOC: R_RISCV_CUSTOM194 .bar 0x0
+# INSTR: qc.e.li s0, .bar
+# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_32
+
+# Check that branches to a defined symbol are handled correctly
+qc.li x7, %qc.abs20(.L1)
+# INSTR: qc.li t2, %qc.abs20(.L1)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(.L1), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x6, .L1
+# INSTR: qc.e.li t1, .L1
+# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_32
+
+.L1:
+  ret
+
+.section .t2
+
+.bar:
+  ret


        


More information about the llvm-commits mailing list