diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-15 03:17:02 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-15 03:17:02 +0800 |
| commit | ae9caa1af23247b75f94645c540930e2933c86e4 (patch) | |
| tree | 5bf278d3812331aa00bd8700b5cf3d4b35e70023 /backend/lib/Target/RISCV | |
| parent | 7d763c8b0ae6eee5f015fa82c744bff4c7ec8c8b (diff) | |
| download | rcc-project-ae9caa1af23247b75f94645c540930e2933c86e4.tar.gz rcc-project-ae9caa1af23247b75f94645c540930e2933c86e4.tar.xz | |
[GlobalISel] Lower integer rotate operations
Diffstat (limited to 'backend/lib/Target/RISCV')
| -rw-r--r-- | backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 37fad6d..cbd3a31 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -643,6 +643,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &Subtarget) { getActionDefinitionsBuilder({opcode(GenericOpcode::G_FSHL), opcode(GenericOpcode::G_FSHR)}) .lower(); getActionDefinitionsBuilder({opcode(GenericOpcode::G_ROTR), opcode(GenericOpcode::G_ROTL)}) + .legalFor(HasZbb, {{S64, S64}}) + .customFor(HasZbb, {{S32, S32}}) .lower(); getActionDefinitionsBuilder(opcode(GenericOpcode::G_BITREVERSE)).maxScalar(0, S64).lower(); getActionDefinitionsBuilder(opcode(GenericOpcode::G_BSWAP)).maxScalar(0, S64).lower(); @@ -1076,6 +1078,32 @@ Expected<void> RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, Helper.Observer.changedInstr(Instruction); return {}; } + if (Instruction.opcode() == opcode(GenericOpcode::G_SDIV) || + Instruction.opcode() == opcode(GenericOpcode::G_UDIV) || + Instruction.opcode() == opcode(GenericOpcode::G_UREM) || + Instruction.opcode() == opcode(GenericOpcode::G_ROTL) || + Instruction.opcode() == opcode(GenericOpcode::G_ROTR)) { + 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()); + if (auto Widened = Helper.widenScalarDst(Instruction, *XLenType); !Widened) + return std::unexpected(Widened.error()); + auto WordOpcode = getRISCVWOpcode(static_cast<GenericOpcode>(Instruction.opcode().value())); + if (!WordOpcode) + return std::unexpected(WordOpcode.error()); + if (auto Changed = Instruction.setOpcode(*WordOpcode); !Changed) + return std::unexpected(Changed.error()); + Helper.Observer.changedInstr(Instruction); + return {}; + } if (Instruction.opcode() == opcode(GenericOpcode::G_ATOMIC_CMPXCHG)) return lowerAtomicCompareExchange(Instruction, Function, Target); if (Instruction.opcode() == opcode(GenericOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS)) |
