llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-mc Author: Sam Elliott (lenary) <details> <summary>Changes</summary> This adds support for Xqccmp to the following passes: - Prolog Epilog Insertion - reusing much of the existing push/pop logic, but extending it to cope with frame pointers and reorder the CFI information correctly. - Move Merger - extending it to support the `qc.` variants of the double-move instructions. - Push/Pop Optimizer - extending it to support the `qc.` variants of the pop instructions. The testing is based on existing Zcmp tests, but I have put them in separate files as some of the Zcmp tests were getting quite long. --- This is stacked on #<!-- -->128731. --- Patch is 293.87 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128815.diff 26 Files Affected: - (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) - (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+12-1) - (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+3) - (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) - (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+59-8) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1) - (added) llvm/lib/Target/RISCV/RISCVInstrInfoXqccmp.td (+95) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZc.td (-2) - (modified) llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h (+32-3) - (modified) llvm/lib/Target/RISCV/RISCVMoveMerger.cpp (+54-12) - (modified) llvm/lib/Target/RISCV/RISCVPushPopOptimizer.cpp (+27-8) - (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+5) - (modified) llvm/test/CodeGen/RISCV/attributes.ll (+5) - (added) llvm/test/CodeGen/RISCV/xqccmp-additional-stack.ll (+54) - (added) llvm/test/CodeGen/RISCV/xqccmp-callee-saved-gprs.ll (+1171) - (added) llvm/test/CodeGen/RISCV/xqccmp-cm-popretz.mir (+66) - (added) llvm/test/CodeGen/RISCV/xqccmp-cm-push-pop.mir (+92) - (added) llvm/test/CodeGen/RISCV/xqccmp-push-pop-popret.ll (+3889) - (added) llvm/test/CodeGen/RISCV/xqccmp-with-float.ll (+90) - (added) llvm/test/CodeGen/RISCV/xqccmp_mvas_mvsa.mir (+28) - (added) llvm/test/MC/RISCV/rv32xqccmp-invalid.s (+35) - (added) llvm/test/MC/RISCV/rv32xqccmp-valid.s (+353) - (added) llvm/test/MC/RISCV/rv64e-xqccmp-valid.s (+85) - (added) llvm/test/MC/RISCV/rv64xqccmp-invalid.s (+35) - (added) llvm/test/MC/RISCV/rv64xqccmp-valid.s (+181) - (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+6) ``````````diff diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index fcd820464e2d1..1c29ae98c96f0 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -193,6 +193,7 @@ // CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) +// CHECK-NEXT: xqccmp 0.1 'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves) // CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqciac 0.3 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) // CHECK-NEXT: xqcicli 0.2 'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 650ad48e50de0..fb0ff9a73159d 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1682,6 +1682,17 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidRnumArg: { return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10); } + case Match_InvalidStackAdj: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + StringRef SpecName = "Zc"; + if (getSTI().hasFeature(RISCV::FeatureVendorXqccmp)) + SpecName = "Xqccmp"; + + return Error( + ErrorLoc, + "stack adjustment is invalid for this instruction and register list; " + "refer to " + SpecName + " spec for a detailed range of stack adjustment"); + } } if (const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) { @@ -3640,7 +3651,7 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst, } } - if (Opcode == RISCV::CM_MVSA01) { + if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) { MCRegister Rd1 = Inst.getOperand(0).getReg(); MCRegister Rd2 = Inst.getOperand(1).getReg(); if (Rd1 == Rd2) { diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 8c07d87680d65..7beed1d157024 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -745,6 +745,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, "Qualcomm uC Conditional Move 16bit"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint16, "Qualcomm uC Interrupts 16bit"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXqccmp, DecoderTableXqccmp16, + "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"); TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc), DecoderTableXwchc16, "WCH QingKe XW"); TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 1a93371a4d92f..2b5b7173f2a68 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1374,6 +1374,14 @@ def HasVendorXqcilo AssemblerPredicate<(all_of FeatureVendorXqcilo), "'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)">; +def FeatureVendorXqccmp + : RISCVExperimentalExtension<0, 1, + "Qualcomm 16-bit Push/Pop and Double Moves", + [FeatureStdExtZca]>; +def HasVendorXqccmp : Predicate<"Subtarget->hasVendorXqccmp()">, + AssemblerPredicate<(all_of FeatureVendorXqccmp), + "'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves)">; + // Rivos Extension(s) def FeatureVendorXRivosVizip diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 32834a6b84f10..6526390f38abd 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -783,6 +783,54 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB, } } +static bool isPush(unsigned Opcode) { + switch (Opcode) { + case RISCV::CM_PUSH: + case RISCV::QC_CM_PUSH: + case RISCV::QC_CM_PUSHFP: + return true; + default: + return false; + } +} + +static bool isPop(unsigned Opcode) { + // There are other pops but these are the only ones introduced during this + // pass. + switch (Opcode) { + case RISCV::CM_POP: + case RISCV::QC_CM_POP: + return true; + default: + return false; + } +} + +static unsigned getPushOpcode(RISCVMachineFunctionInfo::PushKind Kind, + bool hasFP) { + switch (Kind) { + case RISCVMachineFunctionInfo::PushKind::StdExtZcmp: + return RISCV::CM_PUSH; + case RISCVMachineFunctionInfo::PushKind::VendorXqccmp: + return hasFP ? RISCV::QC_CM_PUSHFP : RISCV::QC_CM_PUSH; + default: + llvm_unreachable("Unhandled PushKind"); + } +} + +static unsigned getPopOpcode(RISCVMachineFunctionInfo::PushKind Kind) { + // There are other pops but they are introduced later by the Push/Pop + // Optimizer. + switch (Kind) { + case RISCVMachineFunctionInfo::PushKind::StdExtZcmp: + return RISCV::CM_POP; + case llvm::RISCVMachineFunctionInfo::PushKind::VendorXqccmp: + return RISCV::CM_POP; + default: + llvm_unreachable("Unhandled Push Kind"); + } +} + void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -882,7 +930,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, } if (RVFI->isPushable(MF) && FirstFrameSetup != MBB.end() && - FirstFrameSetup->getOpcode() == RISCV::CM_PUSH) { + isPush(FirstFrameSetup->getOpcode())) { // Use available stack adjustment in push instruction to allocate additional // stack space. Align the stack size down to a multiple of 16. This is // needed for RVE. @@ -926,7 +974,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI, getUnmanagedCSI(MF, CSI)); // Generate new FP. - if (hasFP(MF)) { + if (hasFP(MF) && RVFI->getPushKind(MF) != + RISCVMachineFunctionInfo::PushKind::VendorXqccmp) { if (STI.isRegisterReservedByUser(FPReg)) MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{ MF.getFunction(), "Frame pointer required, but has been reserved."}); @@ -1193,9 +1242,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // Recover callee-saved registers. emitCFIForCSI<CFIRestoreRegisterEmitter>(MBB, MBBI, getUnmanagedCSI(MF, CSI)); - bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() && - MBBI->getOpcode() == RISCV::CM_POP; - if (ApplyPop) { + if (RVFI->isPushable(MF) && MBBI != MBB.end() && isPop(MBBI->getOpcode())) { // Use available stack adjustment in pop instruction to deallocate stack // space. Align the stack size down to a multiple of 16. This is needed for // RVE. @@ -1816,7 +1863,8 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots( FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); }); if (FII != std::end(FixedCSRFIMap)) { int64_t Offset; - if (RVFI->isPushable(MF)) + if (RVFI->getPushKind(MF) == + RISCVMachineFunctionInfo::PushKind::StdExtZcmp) Offset = -((FII->second + RVFI->getRVPushRegs() + 1) * (int64_t)Size); else Offset = FII->second * (int64_t)Size; @@ -1881,8 +1929,10 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( if (PushedRegNum > 0) { // Use encoded number to represent registers to spill. int RegEnc = RVFI->getRVPushRlist(); + + unsigned Opcode = getPushOpcode(RVFI->getPushKind(*MF), hasFP(*MF)); MachineInstrBuilder PushBuilder = - BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH)) + BuildMI(MBB, MI, DL, TII.get(Opcode)) .setMIFlag(MachineInstr::FrameSetup); PushBuilder.addImm((int64_t)RegEnc); PushBuilder.addImm(0); @@ -2035,8 +2085,9 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( if (RVFI->isPushable(*MF)) { int RegEnc = RVFI->getRVPushRlist(); if (RegEnc != llvm::RISCVZC::RLISTENCODE::INVALID_RLIST) { + unsigned Opcode = getPopOpcode(RVFI->getPushKind(*MF)); MachineInstrBuilder PopBuilder = - BuildMI(MBB, MI, DL, TII.get(RISCV::CM_POP)) + BuildMI(MBB, MI, DL, TII.get(Opcode)) .setMIFlag(MachineInstr::FrameDestroy); // Use encoded number to represent registers to restore. PopBuilder.addImm(RegEnc); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index a962e64581797..c84caa76b1b4d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -2147,6 +2147,7 @@ include "RISCVInstrInfoSFB.td" include "RISCVInstrInfoXCV.td" include "RISCVInstrInfoXwch.td" include "RISCVInstrInfoXqci.td" +include "RISCVInstrInfoXqccmp.td" include "RISCVInstrInfoXMips.td" include "RISCVInstrInfoXRivos.td" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqccmp.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqccmp.td new file mode 100644 index 0000000000000..5bb9c1e4b228b --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqccmp.td @@ -0,0 +1,95 @@ +//===---------------- RISCVInstrInfoXqccmp.td --------------*- tablegen -*-===// +// +// 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 file describes Qualcomm's Xqccmp extension. +// +// Xqccmp is broadly equivalent to (and incompatible with) Zcmp except the +// following changes: +// +// - The registers are pushed in the opposite order, so `ra` and `fp` are +// closest to the incoming stack pointer (to be compatible with the +// frame-pointer convention), and +// +// - There is a new `qc.cm.pushfp` instruction which is `qc.cm.push` but it sets +// `fp` to the incoming stack pointer value, as expected by the frame-pointer +// convention. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction Formats +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +let DecoderNamespace = "Xqccmp", Predicates = [HasVendorXqccmp] in { + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +let Defs = [X10, X11] in +def QC_CM_MVA01S : RVInst16CA<0b101011, 0b11, 0b10, (outs), + (ins SR07:$rs1, SR07:$rs2), "qc.cm.mva01s", "$rs1, $rs2">, + Sched<[WriteIALU, WriteIALU, ReadIALU, ReadIALU]>; + +let Uses = [X10, X11] in +def QC_CM_MVSA01 : RVInst16CA<0b101011, 0b01, 0b10, (outs SR07:$rs1, SR07:$rs2), + (ins), "qc.cm.mvsa01", "$rs1, $rs2">, + Sched<[WriteIALU, WriteIALU, ReadIALU, ReadIALU]>; +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Uses = [X2], Defs = [X2] in +def QC_CM_PUSH : RVInstZcCPPP<0b11000, "qc.cm.push", negstackadj>, + Sched<[WriteIALU, ReadIALU, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData]>; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Uses = [X2], Defs = [X2, X8] in +def QC_CM_PUSHFP : RVInstZcCPPP<0b11001, "qc.cm.pushfp", negstackadj>, + Sched<[WriteIALU, WriteIALU, ReadIALU, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, + ReadStoreData, ReadStoreData, ReadStoreData]>; + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isReturn = 1, + Uses = [X2], Defs = [X2] in +def QC_CM_POPRET : RVInstZcCPPP<0b11110, "qc.cm.popret">, + Sched<[WriteIALU, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, WriteLDW, ReadIALU]>; + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isReturn = 1, + Uses = [X2], Defs = [X2, X10] in +def QC_CM_POPRETZ : RVInstZcCPPP<0b11100, "qc.cm.popretz">, + Sched<[WriteIALU, WriteIALU, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + ReadIALU]>; + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, + Uses = [X2], Defs = [X2] in +def QC_CM_POP : RVInstZcCPPP<0b11010, "qc.cm.pop">, + Sched<[WriteIALU, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, + WriteLDW, WriteLDW, WriteLDW, ReadIALU]>; + +} // DecoderNamespace = "Xqccmp", Predicates = [HasVendorXqccmp] + +//===----------------------------------------------------------------------===// +// Aliases +//===----------------------------------------------------------------------===// + diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td index 9dfbcf678d6eb..4944e85cbbcbb 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td @@ -46,8 +46,6 @@ def StackAdjAsmOperand : AsmOperandClass { let Name = "StackAdj"; let ParserMethod = "parseZcmpStackAdj"; let DiagnosticType = "InvalidStackAdj"; - let DiagnosticString = "stack adjustment is invalid for this instruction and register list; " - "refer to Zc spec for a detailed range of stack adjustment"; let PredicateMethod = "isSpimm"; let RenderMethod = "addSpimmOperands"; } diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h index 27a13bb7cace1..e8744a0dcb5cb 100644 --- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h +++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h @@ -141,9 +141,38 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo { // We cannot use fixed locations for the callee saved spill slots if the // function uses a varargs save area. // TODO: Use a separate placement for vararg registers to enable Zcmp. - return MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() && - !MF.getTarget().Options.DisableFramePointerElim(MF) && - VarArgsSaveSize == 0; + if (VarArgsSaveSize != 0) + return false; + + // Zcmp is not compatible with the frame pointer convention. + if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp()) + return !MF.getTarget().Options.DisableFramePointerElim(MF); + + // Xqccmp is Zcmp but has a push order compatible with the frame-pointer + // convention. + if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp()) + return true; + + return false; + } + + enum class PushKind { None = 0, StdExtZcmp, VendorXqccmp }; + + PushKind getPushKind(const MachineFunction &MF) const { + if (VarArgsSaveSize != 0) + return PushKind::None; + + // Zcmp is not compatible with the frame pointer convention. + if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() && + !MF.getTarget().Options.DisableFramePointerElim(MF)) + return PushKind::StdExtZcmp; + + // Xqccmp is Zcmp but has a push order compatible with the frame-pointer + // convention. + if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp()) + return PushKind::VendorXqccmp; + + return PushKind::None; } int getRVPushRlist() const { return RVPushRlist; } diff --git a/llvm/lib/Target/RISCV/RISCVMoveMerger.cpp b/llvm/lib/Target/RISCV/RISCVMoveMerger.cpp index 3c5462057b280..7a2541a652b58 100644 --- a/llvm/lib/Target/RISCV/RISCVMoveMerger.cpp +++ b/llvm/lib/Target/RISCV/RISCVMoveMerger.cpp @@ -9,10 +9,12 @@ // This file contains a pass that performs move related peephole optimizations // as Zcmp has specified. This pass should be run after register allocation. // +// This pass also supports Xqccmp, which has identical instructions. +// //===----------------------------------------------------------------------===// #include "RISCVInstrInfo.h" -#include "RISCVMachineFunctionInfo.h" +#include "RISCVSubtarget.h" using namespace llvm; @@ -43,7 +45,7 @@ struct RISCVMoveMerge : public MachineFunctionPass { MachineBasicBlock::iterator findMatchingInst(MachineBasicBlock::iterator &MBBI, unsigned InstOpcode, const DestSourcePair &RegPair); - bool mergeMoveSARegPair(MachineBasicBlock &MBB); + bool mergeMoveSARegPair(const RISCVSubtarget &STI, MachineBasicBlock &MBB); bool runOnMachineFunction(MachineFunction &Fn) override; StringRef getPassName() const override { return RISCV_MOVE_MERGE_NAME; } @@ -56,6 +58,46 @@ char RISCVMoveMerge::ID = 0; INITIALIZE_PASS(RISCVMoveMerge, "riscv-move-merge", RISCV_MOVE_MERGE_NAME, false, false) +static bool isMoveFromAToS(unsigned Opcode) { + switch (Opcode) { + case RISCV::CM_MVA01S: + case RISCV::QC_CM_MVA01S: + return true; + default: + return false; + } +} + +static unsigned getMoveFromAToSOpcode(const RISCVSubtarget &STI) { + if (STI.hasStdExtZcmp()) + return RISCV::CM_MVA01S; + + if (STI.hasVendorXqccmp()) + return RISCV::QC_CM_MVA01S; + + llvm_unreachable("Unhandled subtarget with paired A to S move."); +} + +static bool isMoveFromSToA(unsigned Opcode) { + switch (Opcode) { + case RISCV::CM_MVSA01: + case RISCV::QC_CM_MVSA01: + return true; + default: + return false; + } +} + +static unsigned getMoveFromSToAOpcode(const RISCVSubtarget &STI) { + if (STI.hasStdExtZcmp()) + return RISCV::CM_MVSA01; + + if (STI.hasVendorXqccmp()) + return RISCV::QC_CM_MVSA01; + + llvm_unreachable("Unhandled subtarget with paired S to A move"); +} + // Check if registers meet CM.MVA01S constraints. bool RISCVMoveMerge::isCandidateToMergeMVA01S(const DestSourcePair &RegPair) { Register Destination = RegPair.Destination->getReg(); @@ -87,7 +129,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I, MachineBasicBlock::iterator NextI = next_nodbg(I, E); DestSourcePair FirstPair = TII->isCopyInstrImpl(*I).value(); DestSourcePair PairedRegs = TII->isCopyInstrImpl(*Paired).value(); - Register ARegInFirstPair = Opcode == RISCV::CM_MVA01S + Register ARegInFirstPair = isMoveFromAToS(Opcode) ? FirstPair.Destination->getReg() : FirstPair.Source->getReg(); @@ -104,7 +146,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I, // mv a0, s2 // mv a1, s1 => cm.mva01s s2,s1 bool StartWithX10 = ARegInFirstPa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/128815 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits