-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[RISCV] Support Xqcilo loads/stores in RISCVMakeCompressible #172971
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
Conversation
|
@llvm/pr-subscribers-backend-risc-v Author: Sudharsan Veeravalli (svs-quic) ChangesThis patch adds support for converting Xqcilo loads/stores with either large offsets or uncompressible registers into loads/stores that can be compressed. We do this transformation only when the Xqcilia extension is enabled in addition to the Xqcilo extension so that we can use the QC_E_ADDI instruction to form the new base. There might be a few cases where compressing from the 48-bit Xqcilo load/store to a 32-bit load/store might be beneficial which this patch does not address. Patch is 32.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172971.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVMakeCompressible.cpp b/llvm/lib/Target/RISCV/RISCVMakeCompressible.cpp
index 54569b1f7aaf3..478e839929da3 100644
--- a/llvm/lib/Target/RISCV/RISCVMakeCompressible.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMakeCompressible.cpp
@@ -101,12 +101,17 @@ static unsigned log2LdstWidth(unsigned Opcode) {
llvm_unreachable("Unexpected opcode");
case RISCV::LBU:
case RISCV::SB:
+ case RISCV::QC_E_LBU:
+ case RISCV::QC_E_SB:
return 0;
case RISCV::LH:
case RISCV::LH_INX:
case RISCV::LHU:
case RISCV::SH:
case RISCV::SH_INX:
+ case RISCV::QC_E_LH:
+ case RISCV::QC_E_LHU:
+ case RISCV::QC_E_SH:
return 1;
case RISCV::LW:
case RISCV::LW_INX:
@@ -114,6 +119,8 @@ static unsigned log2LdstWidth(unsigned Opcode) {
case RISCV::SW_INX:
case RISCV::FLW:
case RISCV::FSW:
+ case RISCV::QC_E_LW:
+ case RISCV::QC_E_SW:
return 2;
case RISCV::LD:
case RISCV::LD_RV32:
@@ -132,12 +139,18 @@ static unsigned offsetMask(unsigned Opcode) {
llvm_unreachable("Unexpected opcode");
case RISCV::LBU:
case RISCV::SB:
+ case RISCV::QC_E_LB:
+ case RISCV::QC_E_LBU:
+ case RISCV::QC_E_SB:
return maskTrailingOnes<unsigned>(2U);
case RISCV::LH:
case RISCV::LH_INX:
case RISCV::LHU:
case RISCV::SH:
case RISCV::SH_INX:
+ case RISCV::QC_E_LH:
+ case RISCV::QC_E_LHU:
+ case RISCV::QC_E_SH:
return maskTrailingOnes<unsigned>(1U);
case RISCV::LW:
case RISCV::LW_INX:
@@ -151,6 +164,8 @@ static unsigned offsetMask(unsigned Opcode) {
case RISCV::SD_RV32:
case RISCV::FLD:
case RISCV::FSD:
+ case RISCV::QC_E_LW:
+ case RISCV::QC_E_SW:
return maskTrailingOnes<unsigned>(5U);
}
}
@@ -214,6 +229,15 @@ static bool isCompressibleLoad(const MachineInstr &MI) {
return !STI.is64Bit() && STI.hasStdExtCOrZcfOrZce();
case RISCV::FLD:
return STI.hasStdExtCOrZcd();
+ // For the Xqcilo loads we mark it as compressible only if Xqcilia is also
+ // enabled so that QC_E_ADDI can be used to create the new base.
+ case RISCV::QC_E_LBU:
+ case RISCV::QC_E_LH:
+ case RISCV::QC_E_LHU:
+ return !STI.is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia() &&
+ STI.hasStdExtZcb();
+ case RISCV::QC_E_LW:
+ return !STI.is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia();
}
}
@@ -238,6 +262,14 @@ static bool isCompressibleStore(const MachineInstr &MI) {
return !STI.is64Bit() && STI.hasStdExtCOrZcfOrZce();
case RISCV::FSD:
return STI.hasStdExtCOrZcd();
+ // For the Xqcilo stores we mark it as compressible only if Xqcilia is also
+ // enabled so that QC_E_ADDI can be used to create the new base.
+ case RISCV::QC_E_SB:
+ case RISCV::QC_E_SH:
+ return !STI.is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia() &&
+ STI.hasStdExtZcb();
+ case RISCV::QC_E_SW:
+ return !STI.is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia();
}
}
@@ -437,10 +469,16 @@ bool RISCVMakeCompressibleOpt::runOnMachineFunction(MachineFunction &Fn) {
// Create the appropriate copy and/or offset.
if (RISCV::GPRRegClass.contains(RegImm.Reg)) {
- assert(isInt<12>(RegImm.Imm));
- BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::ADDI), NewReg)
- .addReg(RegImm.Reg)
- .addImm(RegImm.Imm);
+ if (isInt<12>(RegImm.Imm)) {
+ BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::ADDI), NewReg)
+ .addReg(RegImm.Reg)
+ .addImm(RegImm.Imm);
+ } else {
+ assert(STI.hasVendorXqcilia() && isInt<26>(RegImm.Imm));
+ BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::QC_E_ADDI), NewReg)
+ .addReg(RegImm.Reg)
+ .addImm(RegImm.Imm);
+ }
} else {
assert(RegImm.Imm == 0);
TII.copyPhysReg(MBB, MI, MI.getDebugLoc(), NewReg, RegImm.Reg,
diff --git a/llvm/test/CodeGen/RISCV/make-compressible-xqci.mir b/llvm/test/CodeGen/RISCV/make-compressible-xqci.mir
new file mode 100644
index 0000000000000..5b9aad84c354f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/make-compressible-xqci.mir
@@ -0,0 +1,543 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -o - %s -mtriple=riscv32 -mattr=+experimental-xqcilo,+experimental-xqcilia -simplify-mir \
+# RUN: -run-pass=riscv-make-compressible | FileCheck --check-prefixes=RV32XQCI %s
+# RUN: llc -o - %s -mtriple=riscv32 -mattr=+zcb,+experimental-xqcilo,+experimental-xqcilia -simplify-mir \
+# RUN: -run-pass=riscv-make-compressible | FileCheck --check-prefixes=RV32XQCI_ZCB %s
+# RUN: llc -o - %s -mtriple=riscv32 -mattr=+experimental-xqcilo -simplify-mir \
+# RUN: -run-pass=riscv-make-compressible | FileCheck --check-prefixes=RV32XQCI_NOXQCILIA %s
+# RUN: llc -o - %s -mtriple=riscv32 -mattr=+zcb,+experimental-xqcilo -simplify-mir \
+# RUN: -run-pass=riscv-make-compressible | FileCheck --check-prefixes=RV32XQCI_ZCB_NOXQCILIA %s
+
+--- |
+
+ define void @load_large_offset_i32(ptr %p) #0 { ret void }
+
+ define void @load_large_offset_s16(ptr %p) #0 { ret void }
+
+ define void @load_large_offset_u16(ptr %p) #0 { ret void }
+
+ define void @load_large_offset_u8(ptr %p) #0 { ret void }
+
+ define void @load_large_offset_s8_no_opt(ptr %p) #0 { ret void }
+
+ define void @store_large_offset_i32(ptr %p) #0 { ret void }
+
+ define void @store_large_offset_i16(ptr %p) #0 { ret void }
+
+ define void @store_large_offset_i8(ptr %p) #0 { ret void }
+
+ define void @store_large_offset_no_opt(ptr %p) #0 { ret void }
+
+ attributes #0 = { minsize }
+
+...
+---
+name: load_large_offset_i32
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: load_large_offset_i32
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: $x12 = QC_E_ADDI $x10, 3968
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LW $x12, 32 :: (load (s32))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LW $x12, 36 :: (load (s32))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LW $x12, 40 :: (load (s32))
+ ; RV32XQCI-NEXT: dead renamable $x10 = QC_E_LW killed $x12, 44 :: (load (s32))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: load_large_offset_i32
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: $x12 = QC_E_ADDI $x10, 3968
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LW $x12, 32 :: (load (s32))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LW $x12, 36 :: (load (s32))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LW $x12, 40 :: (load (s32))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x10 = QC_E_LW killed $x12, 44 :: (load (s32))
+ ; RV32XQCI_ZCB-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_NOXQCILIA-LABEL: name: load_large_offset_i32
+ ; RV32XQCI_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4000 :: (load (s32))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4004 :: (load (s32))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4008 :: (load (s32))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LW killed renamable $x10, 4012 :: (load (s32))
+ ; RV32XQCI_NOXQCILIA-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB_NOXQCILIA-LABEL: name: load_large_offset_i32
+ ; RV32XQCI_ZCB_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4000 :: (load (s32))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4004 :: (load (s32))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LW renamable $x10, 4008 :: (load (s32))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LW killed renamable $x10, 4012 :: (load (s32))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: PseudoRET
+ dead renamable $x11 = QC_E_LW renamable $x10, 4000 :: (load (s32))
+ dead renamable $x11 = QC_E_LW renamable $x10, 4004 :: (load (s32))
+ dead renamable $x11 = QC_E_LW renamable $x10, 4008 :: (load (s32))
+ dead renamable $x10 = QC_E_LW killed renamable $x10, 4012 :: (load (s32))
+ PseudoRET
+
+...
+---
+name: load_large_offset_s16
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: load_large_offset_s16
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x10 = QC_E_LH killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: load_large_offset_s16
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: $x12 = QC_E_ADDI $x10, 4000
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LH $x12, 0 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LH $x12, 0 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LH $x12, 2 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x10 = QC_E_LH killed $x12, 2 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_NOXQCILIA-LABEL: name: load_large_offset_s16
+ ; RV32XQCI_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LH killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB_NOXQCILIA-LABEL: name: load_large_offset_s16
+ ; RV32XQCI_ZCB_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LH renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LH killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: PseudoRET
+ dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ dead renamable $x11 = QC_E_LH renamable $x10, 4000 :: (load (s16))
+ dead renamable $x11 = QC_E_LH renamable $x10, 4002 :: (load (s16))
+ dead renamable $x10 = QC_E_LH killed renamable $x10, 4002 :: (load (s16))
+ PseudoRET
+
+...
+---
+name: load_large_offset_u16
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: load_large_offset_u16
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI-NEXT: dead renamable $x10 = QC_E_LHU killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: load_large_offset_u16
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: $x12 = QC_E_ADDI $x10, 4000
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LHU $x12, 0 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LHU $x12, 0 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LHU $x12, 2 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x10 = QC_E_LHU killed $x12, 2 :: (load (s16))
+ ; RV32XQCI_ZCB-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_NOXQCILIA-LABEL: name: load_large_offset_u16
+ ; RV32XQCI_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LHU killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_NOXQCILIA-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB_NOXQCILIA-LABEL: name: load_large_offset_u16
+ ; RV32XQCI_ZCB_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LHU renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LHU killed renamable $x10, 4002 :: (load (s16))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: PseudoRET
+ dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ dead renamable $x11 = QC_E_LHU renamable $x10, 4000 :: (load (s16))
+ dead renamable $x11 = QC_E_LHU renamable $x10, 4002 :: (load (s16))
+ dead renamable $x10 = QC_E_LHU killed renamable $x10, 4002 :: (load (s16))
+ PseudoRET
+
+...
+---
+name: load_large_offset_u8
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: load_large_offset_u8
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x10 = QC_E_LBU killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: load_large_offset_u8
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: $x12 = QC_E_ADDI $x10, 4000
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LBU $x12, 0 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LBU $x12, 1 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LBU $x12, 2 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x10 = QC_E_LBU killed $x12, 3 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_NOXQCILIA-LABEL: name: load_large_offset_u8
+ ; RV32XQCI_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LBU killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB_NOXQCILIA-LABEL: name: load_large_offset_u8
+ ; RV32XQCI_ZCB_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LBU renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LBU killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: PseudoRET
+ dead renamable $x11 = QC_E_LBU renamable $x10, 4000 :: (load (s8))
+ dead renamable $x11 = QC_E_LBU renamable $x10, 4001 :: (load (s8))
+ dead renamable $x11 = QC_E_LBU renamable $x10, 4002 :: (load (s8))
+ dead renamable $x10 = QC_E_LBU killed renamable $x10, 4003 :: (load (s8))
+ PseudoRET
+
+...
+---
+name: load_large_offset_s8_no_opt
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: load_large_offset_s8_no_opt
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI-NEXT: dead renamable $x10 = QC_E_LB killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: load_large_offset_s8_no_opt
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: dead renamable $x10 = QC_E_LB killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI_ZCB-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_NOXQCILIA-LABEL: name: load_large_offset_s8_no_opt
+ ; RV32XQCI_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LB killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI_NOXQCILIA-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB_NOXQCILIA-LABEL: name: load_large_offset_s8_no_opt
+ ; RV32XQCI_ZCB_NOXQCILIA: liveins: $x10
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: {{ $}}
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4000 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4001 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x11 = QC_E_LB renamable $x10, 4002 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: dead renamable $x10 = QC_E_LB killed renamable $x10, 4003 :: (load (s8))
+ ; RV32XQCI_ZCB_NOXQCILIA-NEXT: PseudoRET
+ dead renamable $x11 = QC_E_LB renamable $x10, 4000 :: (load (s8))
+ dead renamable $x11 = QC_E_LB renamable $x10, 4001 :: (load (s8))
+ dead renamable $x11 = QC_E_LB renamable $x10, 4002 :: (load (s8))
+ dead renamable $x10 = QC_E_LB killed renamable $x10, 4003 :: (load (s8))
+ PseudoRET
+
+...
+---
+name: store_large_offset_i32
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x10
+
+ ; RV32XQCI-LABEL: name: store_large_offset_i32
+ ; RV32XQCI: liveins: $x10
+ ; RV32XQCI-NEXT: {{ $}}
+ ; RV32XQCI-NEXT: renamable $x11 = ADDI $x0, 1
+ ; RV32XQCI-NEXT: $x12 = QC_E_ADDI $x10, 3968
+ ; RV32XQCI-NEXT: QC_E_SW killed renamable $x11, $x12, 32 :: (volatile store (s32))
+ ; RV32XQCI-NEXT: renamable $x11 = ADDI $x0, 3
+ ; RV32XQCI-NEXT: QC_E_SW killed renamable $x11, $x12, 36 :: (volatile store (s32))
+ ; RV32XQCI-NEXT: renamable $x11 = ADDI $x0, 5
+ ; RV32XQCI-NEXT: QC_E_SW killed renamable $x11, $x12, 40 :: (volatile store (s32))
+ ; RV32XQCI-NEXT: renamable $x11 = ADDI $x0, 7
+ ; RV32XQCI-NEXT: QC_E_SW killed renamable $x11, killed $x12, 44 :: (volatile store (s32))
+ ; RV32XQCI-NEXT: PseudoRET
+ ;
+ ; RV32XQCI_ZCB-LABEL: name: store_large_offset_i32
+ ; RV32XQCI_ZCB: liveins: $x10
+ ; RV32XQCI_ZCB-NEXT: {{ $}}
+ ; RV32XQCI_ZCB-NEXT: renamable $x11 = ADDI $x0, 1
+ ; RV32XQCI_ZCB-NEXT: $x12 = QC_E_ADDI $x10, 3968
+ ; RV32XQCI_ZCB-NEXT: QC_E_SW killed renamable $x11, $x12, 32 :: (volatile store (s32))
+ ; RV32XQCI_ZCB-NEX...
[truncated]
|
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Did you miss out support for QC_E_LB? Some of the cases miss it, and the message doesn't say why |
There is no C.LB for it to be compressed into. If you notice there is no LB support in the pass as well for the same reason. |
There was one case where I had added this by mistake. I have removed that now. |
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/31858 Here is the relevant piece of the build log for the reference |
This patch adds support for converting Xqcilo loads/stores with either large offsets or uncompressible registers into loads/stores that can be compressed. We do this transformation only when the Xqcilia extension is enabled in addition to the Xqcilo extension so that we can use the QC_E_ADDI instruction to form the new base.
There might be a few cases where compressing from the 48-bit Xqcilo load/store to a 32-bit load/store might be beneficial which this patch does not address.