Skip to content

[RISCV][Xqcilo] Load/Store Pseudos #134931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 9, 2025
Merged

Conversation

lenary
Copy link
Member

@lenary lenary commented Apr 8, 2025

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.

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.
@lenary lenary requested review from svs-quic and hchandel April 8, 2025 21:12
@llvmbot llvmbot added backend:RISC-V mc Machine (object) code labels Apr 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 8, 2025

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

@llvm/pr-subscribers-mc

Author: Sam Elliott (lenary)

Changes

This adds qc.e.l&lt;type&gt; &lt;reg&gt;, &lt;symbol&gt; and qc.e.s&lt;type&gt; &lt;reg&gt;, &lt;symbol&gt;, &lt;reg&gt; 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 --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

// (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
// Load/Store psuedos with QC.E.* Mnemonics. These expand to an AUIPC +
Copy link
Collaborator

Choose a reason for hiding this comment

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

pseudo*

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

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

LGTM

@lenary lenary merged commit ad01e0a into llvm:main Apr 9, 2025
11 checks passed
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
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.
@lenary lenary deleted the pr/riscv-xqcilo-psuedos branch June 16, 2025 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants