[llvm] [RISCV][Xqcilo] Load/Store Pseudos (PR #134931)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 14:13:15 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

Author: Sam Elliott (lenary)

<details>
<summary>Changes</summary>

This adds `qc.e.l<type> <reg>, <symbol>` and `qc.e.s<type> <reg>, <symbol>, <reg>` pseudos for the corresponding Xqcilo instructions.

These emit as an AUIPC + (Standard) Load/Store pair, because this sequence is shorter and can be relaxed back into the equivalent Xqcilo load/store instruction in the right circumstances.

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


4 Files Affected:

- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+8) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+17) 
- (added) llvm/test/MC/RISCV/xqcilo-pseudos-invalid.s (+70) 
- (added) llvm/test/MC/RISCV/xqcilo-pseudos-valid.s (+43) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index dba78fef0bad8..ac3f88f2c867b 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -3746,18 +3746,23 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
     emitLoadTLSGDAddress(Inst, IDLoc, Out);
     return false;
   case RISCV::PseudoLB:
+  case RISCV::PseudoQC_E_LB:
     emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
     return false;
   case RISCV::PseudoLBU:
+  case RISCV::PseudoQC_E_LBU:
     emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
     return false;
   case RISCV::PseudoLH:
+  case RISCV::PseudoQC_E_LH:
     emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
     return false;
   case RISCV::PseudoLHU:
+  case RISCV::PseudoQC_E_LHU:
     emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
     return false;
   case RISCV::PseudoLW:
+  case RISCV::PseudoQC_E_LW:
     emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
     return false;
   case RISCV::PseudoLWU:
@@ -3776,12 +3781,15 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
     emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
     return false;
   case RISCV::PseudoSB:
+  case RISCV::PseudoQC_E_SB:
     emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
     return false;
   case RISCV::PseudoSH:
+  case RISCV::PseudoQC_E_SH:
     emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
     return false;
   case RISCV::PseudoSW:
+  case RISCV::PseudoQC_E_SW:
     emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
     return false;
   case RISCV::PseudoSD:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index f762c4943f630..97d0d2d028ff1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1186,6 +1186,23 @@ def PseudoLongQC_E_BGEI : LongBcciPseudo<simm16nonzero, 10>;
 def PseudoLongQC_E_BLTUI : LongBcciPseudo<uimm16nonzero, 10>;
 def PseudoLongQC_E_BGEUI : LongBcciPseudo<uimm16nonzero, 10>;
 
+// Load/Store predicates with QC.E.* Mnemonics. These expand to an AUIPC +
+// (Standard) Load/Store pairs, as this sequence can materialize all 32-bit
+// addresses, and is shorter than e.g. an AUIPC + Xqcilo Load/Store pair.
+// These pairs can be turned back into Xqcilo instructions using linker
+// relaxation.
+let Predicates = [HasVendorXqcilo, IsRV32] in {
+def PseudoQC_E_LB : PseudoLoad<"qc.e.lb">;
+def PseudoQC_E_LBU : PseudoLoad<"qc.e.lbu">;
+def PseudoQC_E_LH : PseudoLoad<"qc.e.lh">;
+def PseudoQC_E_LHU : PseudoLoad<"qc.e.lhu">;
+def PseudoQC_E_LW : PseudoLoad<"qc.e.lw">;
+
+def PseudoQC_E_SB : PseudoStore<"qc.e.sb">;
+def PseudoQC_E_SH : PseudoStore<"qc.e.sh">;
+def PseudoQC_E_SW : PseudoStore<"qc.e.sw">;
+} // Predicates = [HasVendorXqcilo, IsRV32]
+
 //===----------------------------------------------------------------------===//
 // Code Gen Patterns
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/RISCV/xqcilo-pseudos-invalid.s b/llvm/test/MC/RISCV/xqcilo-pseudos-invalid.s
new file mode 100644
index 0000000000000..b6da8e487152c
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilo-pseudos-invalid.s
@@ -0,0 +1,70 @@
+# Xqcilo - Qualcomm uC Large Offset Load Store extension
+# RUN: not llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo \
+# RUN:     2>&1 | FileCheck -check-prefixes=CHECK-ENABLED %s
+# RUN: not llvm-mc %s -triple=riscv32 -mattr=-experimental-xqcilo \
+# RUN:     2>&1 | FileCheck -check-prefixes=CHECK-DISABLED %s
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lb a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lb a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lbu a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lh a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lhu a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lw a0, 0xf000
+
+# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
+# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
+qc.e.sb a0, 0xf000, t0
+
+# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
+# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
+qc.e.sh a0, 0xf000, t0
+
+# CHECK-ENABLED: [[@LINE+2]]:21: error: invalid operand for instruction
+# CHECK-DISABLED: [[@LINE+1]]:21: error: invalid operand for instruction
+qc.e.sw a0, 0xf000, t0
+
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lb a0, undefined
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lbu a0, undefined
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lh a0, undefined
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lhu a0, undefined
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lw a0, undefined
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sb a0, undefined, t0
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sh a0, undefined, t0
+# CHECK-DISABLED: [[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sw a0, undefined, t0
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sb a0, undefined
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sh a0, undefined
+
+# CHECK-ENABLED: [[@LINE+2]]:1: error: too few operands for instruction
+# CHECK-DISABLED: [[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sw a0, undefined
diff --git a/llvm/test/MC/RISCV/xqcilo-pseudos-valid.s b/llvm/test/MC/RISCV/xqcilo-pseudos-valid.s
new file mode 100644
index 0000000000000..b8fc33dc9deb3
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilo-pseudos-valid.s
@@ -0,0 +1,43 @@
+# Xqcilo - Qualcomm uC Large Offset Load Store extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo \
+# RUN:     | FileCheck -check-prefixes=CHECK %s
+
+# CHECK-LABEL: .Lpcrel_hi0
+# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
+# CHECK-NEXT: lb a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+qc.e.lb a0, undefined
+
+# CHECK-LABEL: .Lpcrel_hi1
+# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
+# CHECK-NEXT: lbu a0, %pcrel_lo(.Lpcrel_hi1)(a0)
+qc.e.lbu a0, undefined
+
+# CHECK-LABEL: .Lpcrel_hi2
+# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
+# CHECK-NEXT: lh a0, %pcrel_lo(.Lpcrel_hi2)(a0)
+qc.e.lh a0, undefined
+
+# CHECK-LABEL: .Lpcrel_hi3
+# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
+# CHECK-NEXT: lhu a0, %pcrel_lo(.Lpcrel_hi3)(a0)
+qc.e.lhu a0, undefined
+
+# CHECK-LABEL: .Lpcrel_hi4
+# CHECK-NEXT: auipc a0, %pcrel_hi(undefined)
+# CHECK-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
+qc.e.lw a0, undefined
+
+# CHECK-LABEL: .Lpcrel_hi5
+# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
+# CHECK-NEXT: sb a0, %pcrel_lo(.Lpcrel_hi5)(t0)
+qc.e.sb a0, undefined, t0
+
+# CHECK-LABEL: .Lpcrel_hi6
+# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
+# CHECK-NEXT: sh a0, %pcrel_lo(.Lpcrel_hi6)(t0)
+qc.e.sh a0, undefined, t0
+
+# CHECK-LABEL: .Lpcrel_hi7
+# CHECK-NEXT: auipc t0, %pcrel_hi(undefined)
+# CHECK-NEXT: sw a0, %pcrel_lo(.Lpcrel_hi7)(t0)
+qc.e.sw a0, undefined, t0

``````````

</details>


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


More information about the llvm-commits mailing list