From 103299abab6922f450671baa76e34ad746ac4312 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 17 Aug 2026 02:46:40 +0800 Subject: [RISCV][GlobalISel] Constrain core copies during selection --- .../lib/CodeGen/GlobalISel/InstructionSelect.cpp | 24 +++++++++++++--------- .../RISCV/GISel/RISCVInstructionSelector.cpp | 15 ++++++++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 1048843..8cfb9c7 100644 --- a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -291,7 +291,9 @@ Expected InstructionSelect::runImplementation(MachineFunction if (CurrentDescriptor == nullptr) return std::unexpected( passFailure("instruction selector encountered an unknown instruction descriptor")); - if (!CurrentDescriptor->Flags.has(InstructionFlag::Generic)) + const bool IsGeneric = CurrentDescriptor->Flags.has(InstructionFlag::Generic); + const bool IsCopy = Instruction->opcode() == opcode(GenericOpcode::COPY); + if (!IsGeneric && !IsCopy) continue; const OpcodeState Before = stateOf(*Instruction); if (!SeenStates.insert(Before).second) { @@ -322,21 +324,23 @@ Expected InstructionSelect::runImplementation(MachineFunction if (Selected == nullptr) return std::unexpected( passFailure("instruction selector produced an unknown instruction descriptor")); - auto FlagPropagation = - Info->propagateSelectionFlags(*Instruction, InputFlags, InputMayRaiseFPException, Target); - if (!FlagPropagation) - return std::unexpected(FlagPropagation.error()); - auto Constraint = Info->constrainSelectedInstruction(*Instruction, Function, Target); - if (!Constraint) { - return std::unexpected(withErrorContext( - Constraint.error(), "instruction selector could not constrain selected registers: ")); + if (IsGeneric) { + auto FlagPropagation = + Info->propagateSelectionFlags(*Instruction, InputFlags, InputMayRaiseFPException, Target); + if (!FlagPropagation) + return std::unexpected(FlagPropagation.error()); + auto Constraint = Info->constrainSelectedInstruction(*Instruction, Function, Target); + if (!Constraint) { + return std::unexpected(withErrorContext( + Constraint.error(), "instruction selector could not constrain selected registers: ")); + } } auto Validation = Target.validateInstruction(*Instruction, Function.registerInfo()); if (!Validation) return std::unexpected(withErrorContext(Validation.error(), "instruction selector produced invalid MachineIR: ")); const OpcodeState After = stateOf(*Instruction); - if (After == Before) + if (IsGeneric && After == Before) return std::unexpected( passFailure("instruction selector reported success without observable progress", ErrorCode::InternalError)); diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 898b366..bd46144 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -421,6 +421,8 @@ public: return std::unexpected(Generated.error()); if (*Generated) return {}; + if (Instruction.opcode() == opcode(GenericOpcode::COPY)) + return selectCopy(Instruction, Function, Target); auto Match = canSelect(Instruction, Function, Target); if (!Match) return std::unexpected(Match.error()); @@ -514,6 +516,19 @@ public: } private: + [[nodiscard]] Expected selectCopy(MachineInstr &Instruction, MachineFunction &Function, + const TargetDescription &Target) const { + const MachineOperand *DestinationOperand = Instruction.operandAt(0); + const Register *Destination = + DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf(); + if (Destination == nullptr) + return makeUnexpected(ErrorCode::VerificationError, + "RISC-V COPY selection requires a register destination"); + if (!Destination->isVirtual()) + return {}; + return RegisterBanks.constrainRegister(Function, *Destination, Target); + } + [[nodiscard]] Expected createTemporary(MachineFunction &Function, LowLevelType Type, const TargetDescription &Target, std::optional Bank = std::nullopt) const { -- cgit v1.2.3