From 69e1baa931dfa63838683378fa20ed9c46c68a70 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 19 Aug 2026 03:19:40 +0800 Subject: [RISCV][GlobalISel] Match floating comparisons --- backend/utils/TableGen/Common/CodeGenSelection.cpp | 54 ++++++++++++++++++++++ backend/utils/TableGen/Common/CodeGenTarget.h | 6 +++ backend/utils/TableGen/GlobalISelEmitter.cpp | 12 +++-- 3 files changed, 68 insertions(+), 4 deletions(-) (limited to 'backend/utils/TableGen') diff --git a/backend/utils/TableGen/Common/CodeGenSelection.cpp b/backend/utils/TableGen/Common/CodeGenSelection.cpp index df9bf7b..defe98b 100644 --- a/backend/utils/TableGen/Common/CodeGenSelection.cpp +++ b/backend/utils/TableGen/Common/CodeGenSelection.cpp @@ -79,6 +79,33 @@ findInstructionBySymbol(const NormalizedTargetModel &Model, std::string_view Sym return static_cast(Position->second); } +[[nodiscard]] std::optional +floatingPredicateValue(std::string_view Symbol) noexcept { + static constexpr std::array, 16> Predicates = {{ + {"false", FloatingPredicate::AlwaysFalse}, + {"oeq", FloatingPredicate::OrderedEqual}, + {"ogt", FloatingPredicate::OrderedGreaterThan}, + {"oge", FloatingPredicate::OrderedGreaterEqual}, + {"olt", FloatingPredicate::OrderedLessThan}, + {"ole", FloatingPredicate::OrderedLessEqual}, + {"one", FloatingPredicate::OrderedNotEqual}, + {"ord", FloatingPredicate::Ordered}, + {"uno", FloatingPredicate::Unordered}, + {"ueq", FloatingPredicate::UnorderedEqual}, + {"ugt", FloatingPredicate::UnorderedGreaterThan}, + {"uge", FloatingPredicate::UnorderedGreaterEqual}, + {"ult", FloatingPredicate::UnorderedLessThan}, + {"ule", FloatingPredicate::UnorderedLessEqual}, + {"une", FloatingPredicate::UnorderedNotEqual}, + {"true", FloatingPredicate::AlwaysTrue}, + }}; + const auto *const Position = + std::ranges::find(Predicates, Symbol, &decltype(Predicates)::value_type::first); + if (Position == Predicates.end()) + return std::nullopt; + return static_cast(Position->second); +} + [[nodiscard]] const NormalizedRegister *findRegisterBySymbol(const NormalizedTargetModel &Model, std::string_view Symbol) { const auto Position = std::ranges::find(Model.Registers, Symbol, &NormalizedRegister::Symbol); @@ -243,6 +270,33 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) { ++Normalized.Specificity; } + if (Rule.IntegerPredicate && Rule.FloatingPredicate) { + fail(Rule.Range, "selection rule cannot require both integer and floating predicates"); + return false; + } + if (Rule.FloatingPredicate) { + const auto Predicate = floatingPredicateValue(Rule.FloatingPredicate->Predicate); + if (!Predicate) { + fail(Rule.FloatingPredicate->Range, + "selection floating predicate is not a recognized floating predicate"); + return false; + } + if (MatchInstruction != nullptr && + (Rule.FloatingPredicate->OperandIndex >= MatchInstruction->Operands.size() || + !std::ranges::contains( + MatchInstruction->Operands[Rule.FloatingPredicate->OperandIndex].Kinds, + "Predicate"))) { + fail(Rule.FloatingPredicate->Range, + "selection floating predicate requires a predicate operand"); + return false; + } + Normalized.FloatingPredicate = { + .OperandIndex = Rule.FloatingPredicate->OperandIndex, + .Predicate = *Predicate, + }; + ++Normalized.Specificity; + } + std::unordered_set TargetPredicateSymbols; for (const SourceSelectionTargetPredicate &Predicate : Rule.TargetPredicates) { if (!isIdentifier(Predicate.Symbol) || diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h index 9a7c0a2..020bb88 100644 --- a/backend/utils/TableGen/Common/CodeGenTarget.h +++ b/backend/utils/TableGen/Common/CodeGenTarget.h @@ -195,6 +195,11 @@ struct NormalizedSelectionIntegerPredicate final { std::uint32_t Predicate = 0; }; +struct NormalizedSelectionFloatingPredicate final { + std::uint32_t OperandIndex = 0; + std::uint32_t Predicate = 0; +}; + struct NormalizedSelectionConstantRange final { std::int64_t Minimum = 0; std::int64_t Maximum = 0; @@ -266,6 +271,7 @@ struct NormalizedSelectionRule final { std::uint32_t MatchOpcode = 0; std::optional ResultType; std::optional IntegerPredicate; + std::optional FloatingPredicate; std::vector TargetPredicates; std::vector OperandTypes; std::vector OperandBanks; diff --git a/backend/utils/TableGen/GlobalISelEmitter.cpp b/backend/utils/TableGen/GlobalISelEmitter.cpp index d73d691..7390bdf 100644 --- a/backend/utils/TableGen/GlobalISelEmitter.cpp +++ b/backend/utils/TableGen/GlobalISelEmitter.cpp @@ -42,10 +42,11 @@ void emitTypePredicate(std::ostream &Output, std::uint32_t OperandIndex, [[nodiscard]] std::size_t instructionCount(const NormalizedSelectionRule &Rule) noexcept { std::size_t Count = 2U + (Rule.ResultType ? 1U : 0U) + (Rule.IntegerPredicate ? 1U : 0U) + - Rule.TargetPredicates.size() + Rule.OperandTypes.size() + - Rule.OperandBanks.size() + Rule.OperandClasses.size() + - Rule.OperandImmediates.size() + Rule.OperandDefConstants.size() + - Rule.Temporaries.size() + Rule.EraseOperandDefinitions.size(); + (Rule.FloatingPredicate ? 1U : 0U) + Rule.TargetPredicates.size() + + Rule.OperandTypes.size() + Rule.OperandBanks.size() + + Rule.OperandClasses.size() + Rule.OperandImmediates.size() + + Rule.OperandDefConstants.size() + Rule.Temporaries.size() + + Rule.EraseOperandDefinitions.size(); for (const NormalizedSelectionDefUsePredicate &Predicate : Rule.DefUsePredicates) Count += 1U + static_cast(Predicate.IntegerPredicate.has_value()) + Predicate.Captures.size() + Predicate.OperandDefConstants.size(); @@ -115,6 +116,9 @@ std::string emitGlobalISel(const NormalizedTargetModel &Model, std::string_view if (Rule.IntegerPredicate) emitInstruction(Output, "CheckIntegerPredicate", Rule.IntegerPredicate->OperandIndex, Rule.IntegerPredicate->Predicate); + if (Rule.FloatingPredicate) + emitInstruction(Output, "CheckFloatingPredicate", Rule.FloatingPredicate->OperandIndex, + Rule.FloatingPredicate->Predicate); for (const std::string &Predicate : Rule.TargetPredicates) emitInstruction(Output, "CheckTargetPredicate", 0, 0, "0", 0, Predicate); for (const NormalizedSelectionOperandTypePredicate &Predicate : Rule.OperandTypes) -- cgit v1.2.3