From 97e5fbaa55b4672db36123c2425d05a4738452ab Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Fri, 14 Aug 2026 20:35:54 +0800 Subject: [GlobalISel] Match LLVM legalization value tracking --- .../lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 64 ++++++++++++++++++++++ backend/lib/Target/RISCV/RISCVTarget.cpp | 6 +- 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'backend/lib/Target') diff --git a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 4d81404..f1d2fac 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -4,6 +4,7 @@ #include "RISCVImmediateMaterialization.h" #include "rcc/CodeGen/GenericOpcodes.h" +#include "rcc/CodeGen/GlobalISel/GISelChangeObserver.h" #include "rcc/CodeGen/GlobalISel/LegalizerHelper.h" #include "rcc/CodeGen/LowLevelType.h" #include "rcc/CodeGen/MachineBasicBlock.h" @@ -1093,6 +1094,69 @@ Expected RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineFunction &Function = Helper.MIRBuilder.function(); const TargetDescription &Target = Helper.MIRBuilder.target(); + if (Instruction.opcode() == opcode(GenericOpcode::G_ADD) || + Instruction.opcode() == opcode(GenericOpcode::G_SUB)) { + auto XLenType = LowLevelType::makeCategoryNeutralScalar(64); + if (!XLenType) + return std::unexpected(XLenType.error()); + + Helper.Observer.changingInstr(Instruction); + if (auto Widened = Helper.widenScalarSrc(Instruction, *XLenType, 1, GenericOpcode::G_ANYEXT); + !Widened) + return std::unexpected(Widened.error()); + if (auto Widened = Helper.widenScalarSrc(Instruction, *XLenType, 2, GenericOpcode::G_ANYEXT); + !Widened) + return std::unexpected(Widened.error()); + + auto ALUDestination = Function.registerInfo().createVirtualRegister(*XLenType); + if (!ALUDestination) + return std::unexpected(ALUDestination.error()); + auto SignExtendedDestination = Function.registerInfo().createVirtualRegister(*XLenType); + if (!SignExtendedDestination) + return std::unexpected(SignExtendedDestination.error()); + + MachineOperand *DestinationOperand = Instruction.operandAt(0); + const Register *Destination = + DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf(); + if (Destination == nullptr) + return makeUnexpected(ErrorCode::VerificationError, + "RISC-V word arithmetic requires a register destination"); + const Register OriginalDestination = *Destination; + if (auto Point = Helper.MIRBuilder.setInsertPointAfter(Instruction); !Point) + return std::unexpected(Point.error()); + if (auto Built = + Helper.MIRBuilder.buildSExtInReg(*SignExtendedDestination, *ALUDestination, 32); + !Built) + return std::unexpected(Built.error()); + if (auto Built = Helper.MIRBuilder.buildTrunc(OriginalDestination, *SignExtendedDestination); + !Built) + return std::unexpected(Built.error()); + if (auto Changed = DestinationOperand->setRegister(*ALUDestination); !Changed) + return std::unexpected(Changed.error()); + Helper.Observer.changedInstr(Instruction); + return {}; + } + if (Instruction.opcode() == opcode(GenericOpcode::G_SEXT_INREG)) { + const MachineOperand *DestinationOperand = Instruction.operandAt(0); + const MachineOperand *SizeOperand = Instruction.operandAt(2); + const Register *Destination = + DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf(); + const std::int64_t *Size = + SizeOperand == nullptr ? nullptr : SizeOperand->getIf(); + if (Destination == nullptr || Size == nullptr) + return makeUnexpected(ErrorCode::VerificationError, + "RISC-V G_SEXT_INREG has invalid operands"); + auto DestinationType = Function.registerInfo().getType(*Destination); + if (!DestinationType) + return std::unexpected(DestinationType.error()); + if (DestinationType->minimumBitWidth() == 64 && *Size == 32) + return {}; + return Helper.lower(Instruction, LegalizationDecision{ + .Action = LegalizationAction::Lower, + .TypeIndex = 0, + .NewType = {}, + }); + } if (Instruction.opcode() == opcode(GenericOpcode::G_ICMP)) return lowerIntegerCompare(Instruction, Function, Target); if (Instruction.opcode() == opcode(GenericOpcode::G_ATOMIC_CMPXCHG)) diff --git a/backend/lib/Target/RISCV/RISCVTarget.cpp b/backend/lib/Target/RISCV/RISCVTarget.cpp index 8bdea20..1735386 100644 --- a/backend/lib/Target/RISCV/RISCVTarget.cpp +++ b/backend/lib/Target/RISCV/RISCVTarget.cpp @@ -241,8 +241,12 @@ Expected createTargetDescription() { TargetMIRTextInfoDesc MIRText; appendGeneratedMIRTextInfo(MIRText); configureFunctionInfoMIRSchema(MIRText); + TargetBooleanContentInfo BooleanInfo{ + .ScalarInteger = BooleanContent::ZeroOrOne, + .ScalarFloatingPoint = BooleanContent::ZeroOrOne, + }; return TargetDescription::create(std::move(*Instructions), std::move(*Registers), - std::move(MIRText)); + std::move(MIRText), BooleanInfo); } std::shared_ptr createCallPreservedMask(CallingConvention Convention) { -- cgit v1.2.3