diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 03:19:40 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 03:19:40 +0800 |
| commit | 69e1baa931dfa63838683378fa20ed9c46c68a70 (patch) | |
| tree | d8ae9222ed52c3036b30371241bd593e0324ce6c /backend/lib/CodeGen | |
| parent | c0f2700e0c7effc5da267bf501232ff4bfea63bc (diff) | |
| download | rcc-project-69e1baa931dfa63838683378fa20ed9c46c68a70.tar.gz rcc-project-69e1baa931dfa63838683378fa20ed9c46c68a70.tar.xz | |
[RISCV][GlobalISel] Match floating comparisons
Diffstat (limited to 'backend/lib/CodeGen')
| -rw-r--r-- | backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp | 26 | ||||
| -rw-r--r-- | backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp | 34 |
2 files changed, 50 insertions, 10 deletions
diff --git a/backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp b/backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp index d4f73f6..3597509 100644 --- a/backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp +++ b/backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp @@ -106,6 +106,20 @@ namespace { return Integer != nullptr && static_cast<std::uint32_t>(*Integer) == PredicateValue; } +[[nodiscard]] Expected<bool> matchesFloatingPredicate(const MachineInstr &Instruction, + std::size_t OperandIndex, + std::uint32_t PredicateValue) { + if (PredicateValue >= static_cast<std::uint32_t>(FloatingPredicate::Count)) { + return makeUnexpected(ErrorCode::VerificationError, + "generated match table has an invalid floating predicate"); + } + const MachineOperand *Operand = Instruction.operandAt(OperandIndex); + const auto *Predicate = Operand == nullptr ? nullptr : Operand->getIf<PredicateOperand>(); + const FloatingPredicate *Floating = + Predicate == nullptr ? nullptr : Predicate->floatingPredicate(); + return Floating != nullptr && static_cast<std::uint32_t>(*Floating) == PredicateValue; +} + [[nodiscard]] std::optional<std::int64_t> immediateValue(const MachineOperand &Operand) { if (const std::int64_t *Immediate = Operand.getIf<std::int64_t>()) return *Immediate; @@ -384,6 +398,18 @@ matchRule(const GIMatchTable &Table, const GIMatchTableRule &Rule, const Machine return std::optional<MatchedRule>{}; break; } + case GIMatchTableOpcode::CheckFloatingPredicate: { + if (Applying) { + return makeUnexpected(ErrorCode::VerificationError, + "generated match table performs a predicate after an action"); + } + auto Matched = matchesFloatingPredicate(Instruction, Step.OperandIndex, Step.Value); + if (!Matched) + return std::unexpected(Matched.error()); + if (!*Matched) + return std::optional<MatchedRule>{}; + break; + } case GIMatchTableOpcode::CheckTargetPredicate: { if (Applying || Step.Symbol.empty()) { return makeUnexpected(ErrorCode::VerificationError, diff --git a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 8cfb9c7..995a9a0 100644 --- a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -273,6 +273,19 @@ Expected<MachinePassResult> InstructionSelect::runImplementation(MachineFunction Worklist.push_back(Instruction); DiscoveredInstructions.insert(Instruction->stableID()); } + const auto DiscoverNewInstructions = [&]() -> Expected<void> { + for (MachineInstr *Candidate : bottomUpInstructions(Function)) { + const InstructionDescriptor *CandidateDescriptor = + Target.instructionDescriptor(Candidate->opcode()); + if (CandidateDescriptor == nullptr) { + return std::unexpected( + passFailure("instruction selector produced an unknown instruction descriptor")); + } + if (DiscoveredInstructions.insert(Candidate->stableID()).second) + Worklist.push_back(Candidate); + } + return {}; + }; for (std::size_t Index = 0; Index < Worklist.size(); ++Index) { MachineInstr *Instruction = Worklist[Index]; @@ -320,6 +333,14 @@ Expected<MachinePassResult> InstructionSelect::runImplementation(MachineFunction auto Selection = Info->select(*Instruction, Function, Target); if (!Selection) return std::unexpected(Selection.error()); + if (Instruction->parent() == nullptr) { + Result.Changed = true; + Result.Changes.add(MachinePassChange::Instructions); + auto Discovered = DiscoverNewInstructions(); + if (!Discovered) + return std::unexpected(Discovered.error()); + continue; + } const InstructionDescriptor *Selected = Target.instructionDescriptor(Instruction->opcode()); if (Selected == nullptr) return std::unexpected( @@ -348,16 +369,9 @@ Expected<MachinePassResult> InstructionSelect::runImplementation(MachineFunction Result.Changes.add(MachinePassChange::Instructions); if (Selected->Flags.has(InstructionFlag::Generic)) Worklist.push_back(Instruction); - for (MachineInstr *Candidate : bottomUpInstructions(Function)) { - const InstructionDescriptor *CandidateDescriptor = - Target.instructionDescriptor(Candidate->opcode()); - if (CandidateDescriptor == nullptr) - return std::unexpected( - passFailure("instruction selector produced an unknown instruction descriptor")); - if (!DiscoveredInstructions.insert(Candidate->stableID()).second) - continue; - Worklist.push_back(Candidate); - } + auto Discovered = DiscoverNewInstructions(); + if (!Discovered) + return std::unexpected(Discovered.error()); } for (MachineInstr *Instruction : layoutInstructions(Function)) { const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode()); |
