aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:17:02 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:17:02 +0800
commitae9caa1af23247b75f94645c540930e2933c86e4 (patch)
tree5bf278d3812331aa00bd8700b5cf3d4b35e70023 /backend/lib/Target/RISCV
parent7d763c8b0ae6eee5f015fa82c744bff4c7ec8c8b (diff)
downloadrcc-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.cpp28
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))