aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/GlobalISel
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 03:19:40 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 03:19:40 +0800
commit69e1baa931dfa63838683378fa20ed9c46c68a70 (patch)
treed8ae9222ed52c3036b30371241bd593e0324ce6c /backend/lib/CodeGen/GlobalISel
parentc0f2700e0c7effc5da267bf501232ff4bfea63bc (diff)
downloadrcc-project-69e1baa931dfa63838683378fa20ed9c46c68a70.tar.gz
rcc-project-69e1baa931dfa63838683378fa20ed9c46c68a70.tar.xz
[RISCV][GlobalISel] Match floating comparisons
Diffstat (limited to 'backend/lib/CodeGen/GlobalISel')
-rw-r--r--backend/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp26
-rw-r--r--backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp34
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());