aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 23:55:38 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 23:55:38 +0800
commitaa69e15c6909c3b162b15f5326f0a72ba9bb7163 (patch)
tree6428eb20e41bad1fc8ad2f5c259bc5537f54554d /backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
parentcd30fb546e389d1fb78ce8e579b3dba3a8fdb52a (diff)
downloadrcc-project-aa69e15c6909c3b162b15f5326f0a72ba9bb7163.tar.gz
rcc-project-aa69e15c6909c3b162b15f5326f0a72ba9bb7163.tar.xz
[CodeGen] Unify scalar low-level types
Diffstat (limited to 'backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp')
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp452
1 files changed, 226 insertions, 226 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index eace5ad..1a29ebf 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -31,7 +31,8 @@
namespace rcc::riscv {
namespace {
-[[nodiscard]] std::optional<LLT> registerType(const MachineFunction &Function, Register Reg) {
+[[nodiscard]] std::optional<LowLevelType> registerType(const MachineFunction &Function,
+ Register Reg) {
if (!Reg.isVirtual())
return std::nullopt;
auto Info = Function.registerInfo().virtualRegisterInfo(Reg);
@@ -40,62 +41,60 @@ namespace {
return Info->get().Type;
}
-[[nodiscard]] std::optional<LLT> registerType(const MachineFunction &Function,
- const MachineOperand &Operand) {
+[[nodiscard]] std::optional<LowLevelType> registerType(const MachineFunction &Function,
+ const MachineOperand &Operand) {
const Register *Reg = Operand.getIf<Register>();
return Reg == nullptr ? std::nullopt : registerType(Function, *Reg);
}
-[[nodiscard]] std::optional<LLT> resultType(const MachineFunction &Function,
- const MachineInstr &Instruction) {
+[[nodiscard]] std::optional<LowLevelType> resultType(const MachineFunction &Function,
+ const MachineInstr &Instruction) {
const MachineOperand *Result = Instruction.operandAt(0);
return Result == nullptr ? std::nullopt : registerType(Function, *Result);
}
-[[nodiscard]] std::optional<LLT> operandType(const MachineFunction &Function,
- const MachineInstr &Instruction, std::size_t Index) {
+[[nodiscard]] std::optional<LowLevelType>
+operandType(const MachineFunction &Function, const MachineInstr &Instruction, std::size_t Index) {
const MachineOperand *Operand = Instruction.operandAt(Index);
return Operand == nullptr ? std::nullopt : registerType(Function, *Operand);
}
-[[nodiscard]] bool isRVFloatType(LLT Type) noexcept {
- if (!Type.isFloat())
- return false;
- const std::optional<FloatSemantics> Semantics = Type.floatSemantics();
- return Semantics &&
- (*Semantics == FloatSemantics::IEEESingle || *Semantics == FloatSemantics::IEEEDouble);
+[[nodiscard]] bool isSupportedFloatingScalar(LowLevelType Type) noexcept {
+ return Type.isCategoryNeutralScalar() &&
+ (Type.scalarBitWidth() == 32 || Type.scalarBitWidth() == 64);
}
-[[nodiscard]] bool isSupportedIntegerType(LLT Type) noexcept {
- return ((Type.isInteger() || Type.isAnyScalar()) && Type.scalarBitWidth() != 0 &&
+[[nodiscard]] bool isSupportedIntegerType(LowLevelType Type) noexcept {
+ return (Type.isCategoryNeutralScalar() && Type.scalarBitWidth() != 0 &&
Type.scalarBitWidth() <= 64) ||
(Type.isPointer() && Type.scalarBitWidth() == 64);
}
-[[nodiscard]] bool isSupportedIntegerScalar(LLT Type) noexcept {
- return (Type.isInteger() || Type.isAnyScalar()) && Type.scalarBitWidth() != 0 &&
+[[nodiscard]] bool isSupportedIntegerScalar(LowLevelType Type) noexcept {
+ return Type.isCategoryNeutralScalar() && Type.scalarBitWidth() != 0 &&
Type.scalarBitWidth() <= 64;
}
-[[nodiscard]] bool isNativeIntegerScalar(LLT Type) noexcept {
- return (Type.isInteger() || Type.isAnyScalar()) &&
+[[nodiscard]] bool isNativeIntegerScalar(LowLevelType Type) noexcept {
+ return Type.isCategoryNeutralScalar() &&
(Type.scalarBitWidth() == 32 || Type.scalarBitWidth() == 64);
}
-[[nodiscard]] bool isScalarGPRType(LLT Type) noexcept {
- return ((Type.isInteger() || Type.isAnyScalar()) && Type.scalarBitWidth() != 0 &&
+[[nodiscard]] bool isScalarGPRType(LowLevelType Type) noexcept {
+ return (Type.isCategoryNeutralScalar() && Type.scalarBitWidth() != 0 &&
Type.scalarBitWidth() <= 64) ||
(Type.isPointer() && Type.scalarBitWidth() == 64);
}
-[[nodiscard]] bool isI1Type(LLT Type) noexcept {
- return (Type.isInteger() || Type.isAnyScalar()) && Type.scalarBitWidth() == 1;
+[[nodiscard]] bool isI1Type(LowLevelType Type) noexcept {
+ return Type.isCategoryNeutralScalar() && Type.scalarBitWidth() == 1;
}
-[[nodiscard]] bool isScalarIntegerExtension(LLT Destination, LLT Source) noexcept {
- return (Destination.isInteger() || Destination.isAnyScalar()) &&
- (Source.isInteger() || Source.isAnyScalar()) && Destination.scalarBitWidth() != 0 &&
- Source.scalarBitWidth() != 0 && Source.scalarBitWidth() < Destination.scalarBitWidth() &&
+[[nodiscard]] bool isScalarIntegerExtension(LowLevelType Destination,
+ LowLevelType Source) noexcept {
+ return Destination.isCategoryNeutralScalar() && Source.isCategoryNeutralScalar() &&
+ Destination.scalarBitWidth() != 0 && Source.scalarBitWidth() != 0 &&
+ Source.scalarBitWidth() < Destination.scalarBitWidth() &&
Destination.scalarBitWidth() <= 64;
}
@@ -394,11 +393,12 @@ wideConstantUnmergePlan(const MachineInstr &Constant, const MachineFunction &Fun
std::uint64_t Value);
[[nodiscard]] Expected<Register> buildBinaryBefore(MachineIRBuilder &Builder, MachineInstr &Anchor,
- GenericOpcode Generic, LLT Type, Register Left,
- Register Right);
+ GenericOpcode Generic, LowLevelType Type,
+ Register Left, Register Right);
[[nodiscard]] Expected<Register> buildUnaryBefore(MachineIRBuilder &Builder, MachineInstr &Anchor,
- GenericOpcode Generic, LLT Type, Register Source);
+ GenericOpcode Generic, LowLevelType Type,
+ Register Source);
[[nodiscard]] Expected<void> eraseInstruction(MachineInstr &Instruction);
@@ -462,7 +462,7 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
const Register *Narrow = NarrowOperand == nullptr ? nullptr : NarrowOperand->getIf<Register>();
const MachineOperand *WideOperand = Truncation->operandAt(1);
const Register *Wide = WideOperand == nullptr ? nullptr : WideOperand->getIf<Register>();
- const std::optional<LLT> WideType =
+ const std::optional<LowLevelType> WideType =
WideOperand == nullptr ? std::nullopt : registerType(Function, *WideOperand);
if (Narrow == nullptr || Wide == nullptr || !Wide->isVirtual() || !WideType ||
*WideType != *DestinationType || singleRegisterUse(Function, *Narrow) != OnlyUse)
@@ -533,7 +533,7 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
if (Destination == nullptr || !Destination->isVirtual() || Immediate == nullptr)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V narrow constant legalization has invalid operands");
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
auto SetType = Function.registerInfo().setType(*Destination, *Type);
@@ -554,7 +554,8 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
[[nodiscard]] Expected<Register> widenAtomicCompareExchangeSource(MachineInstr &Instruction,
MachineFunction &Function,
MachineIRBuilder &Builder,
- Register Source, LLT WideType) {
+ Register Source,
+ LowLevelType WideType) {
const auto SourceType = registerType(Function, Source);
if (!SourceType)
return makeUnexpected(ErrorCode::VerificationError,
@@ -578,7 +579,7 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
[[nodiscard]] Expected<void> lowerAtomicCompareExchange(MachineInstr &Instruction,
MachineFunction &Function,
const TargetDescription &Target) {
- const std::optional<LLT> OriginalType = resultType(Function, Instruction);
+ const std::optional<LowLevelType> OriginalType = resultType(Function, Instruction);
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
const MachineOperand *CompareOperand = Instruction.operandAt(2);
const MachineOperand *NewValueOperand = Instruction.operandAt(3);
@@ -593,7 +594,7 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
"RISC-V narrow compare-exchange has invalid operands");
const Register OriginalDestination = *Destination;
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -610,7 +611,7 @@ narrowAnyExtBinaryPlan(const MachineInstr &Extension, const MachineFunction &Fun
MachineInstr *FoldedExtension = singleRegisterUse(Function, OriginalDestination);
if (FoldedExtension != nullptr && FoldedExtension->opcode() == opcode(GenericOpcode::G_ANYEXT) &&
operandType(Function, *FoldedExtension, 0)
- .transform([](LLT Type) { return Type.scalarBitWidth() == 64; })
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() == 64; })
.value_or(false)) {
const MachineOperand *WideDestinationOperand = FoldedExtension->operandAt(0);
const Register *FoldedDestination =
@@ -668,7 +669,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
const Register *Compare = CompareOperand == nullptr ? nullptr : CompareOperand->getIf<Register>();
const Register *NewValue =
NewValueOperand == nullptr ? nullptr : NewValueOperand->getIf<Register>();
- const std::optional<LLT> ValueType = resultType(Function, Instruction);
+ const std::optional<LowLevelType> ValueType = resultType(Function, Instruction);
if (OldValue == nullptr || Success == nullptr || Address == nullptr || Compare == nullptr ||
NewValue == nullptr || !ValueType || Instruction.memOperands().size() != 1)
return makeUnexpected(ErrorCode::VerificationError,
@@ -727,7 +728,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
[[nodiscard]] Expected<Register> widenIntegerCompareSource(MachineInstr &Instruction,
MachineFunction &Function,
MachineIRBuilder &Builder,
- Register Source, LLT WideType) {
+ Register Source, LowLevelType WideType) {
const auto SourceType = registerType(Function, Source);
if (!SourceType)
return makeUnexpected(ErrorCode::VerificationError,
@@ -751,7 +752,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
const MachineOperand *ExtendedOperand = User->operandAt(0);
const Register *Extended =
ExtendedOperand == nullptr ? nullptr : ExtendedOperand->getIf<Register>();
- const std::optional<LLT> ExtendedType =
+ const std::optional<LowLevelType> ExtendedType =
ExtendedOperand == nullptr ? std::nullopt : registerType(Function, *ExtendedOperand);
if (Extended == nullptr || !ExtendedType || *ExtendedType != WideType ||
(Def == nullptr || (Def->opcode() != opcode(GenericOpcode::G_CONSTANT) &&
@@ -778,7 +779,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
Def->operandCount() == 2) {
const MachineOperand *WideOperand = Def->operandAt(1);
const Register *WideSource = WideOperand == nullptr ? nullptr : WideOperand->getIf<Register>();
- const std::optional<LLT> ExistingWideType =
+ const std::optional<LowLevelType> ExistingWideType =
WideOperand == nullptr ? std::nullopt : registerType(Function, *WideOperand);
if (WideSource != nullptr && ExistingWideType && *ExistingWideType == WideType) {
auto Result = Function.registerInfo().createVirtualRegister(WideType);
@@ -825,7 +826,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
const Register OriginalLeft = *Left;
const Register OriginalRight = *Right;
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -855,7 +856,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
FoldedExtension->opcode() == opcode(GenericOpcode::G_SEXT) ||
FoldedExtension->opcode() == opcode(GenericOpcode::G_ZEXT)) &&
operandType(Function, *FoldedExtension, 0)
- .transform([](LLT Type) { return Type.scalarBitWidth() == 64; })
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() == 64; })
.value_or(false)) {
const MachineOperand *ExtendedOperand = FoldedExtension->operandAt(0);
const Register *Extended =
@@ -923,7 +924,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
const std::uint64_t Mask = Plan->SourceWidth == 64
? std::numeric_limits<std::uint64_t>::max()
: (std::uint64_t{1} << Plan->SourceWidth) - 1U;
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -964,7 +965,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
if (Plan->SourceWidth == 32 &&
(Plan->Generic == GenericOpcode::G_ADD || Plan->Generic == GenericOpcode::G_SUB)) {
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
auto Temporary = Function.registerInfo().createVirtualRegister(*WideType);
@@ -1043,7 +1044,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
if (!PoolIndex)
return std::unexpected(PoolIndex.error());
- auto PointerType = LLT::makePointer(0, 64);
+ auto PointerType = LowLevelType::makePointer(0, 64);
if (!PointerType)
return std::unexpected(PointerType.error());
auto Address = Function.registerInfo().createVirtualRegister(*PointerType);
@@ -1143,11 +1144,11 @@ memoryAccessBytes(const MachineInstr &Instruction) noexcept {
return Description.Size.minimumBytes();
}
-[[nodiscard]] bool memoryMatchesType(const MachineInstr &Instruction, LLT Type) noexcept {
+[[nodiscard]] bool memoryMatchesType(const MachineInstr &Instruction, LowLevelType Type) noexcept {
const auto Bytes = memoryAccessBytes(Instruction);
- if (!Bytes || (!isSupportedIntegerType(Type) && !isRVFloatType(Type)))
+ if (!Bytes || (!isSupportedIntegerType(Type) && !isSupportedFloatingScalar(Type)))
return false;
- if (isRVFloatType(Type))
+ if (isSupportedFloatingScalar(Type))
return Type.scalarBitWidth() == 32 ? *Bytes == 4 : *Bytes == 8;
const std::uint64_t ValueBytes = (Type.scalarBitWidth() + 7U) / 8U;
return (*Bytes == 1 || *Bytes == 2 || *Bytes == 4 || *Bytes == 8) && *Bytes <= ValueBytes;
@@ -1224,7 +1225,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
MachineInstr &Anchor,
std::uint32_t Width,
std::uint64_t Value) {
- auto Type = LLT::makeAnyScalar(Width);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(Width);
if (!Type)
return std::unexpected(Type.error());
auto Result = Builder.function().registerInfo().createVirtualRegister(*Type);
@@ -1250,7 +1251,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
}
[[nodiscard]] Expected<Register> buildUnaryBefore(MachineIRBuilder &Builder, MachineInstr &Anchor,
- GenericOpcode Generic, LLT Type,
+ GenericOpcode Generic, LowLevelType Type,
Register Source) {
auto Result = Builder.function().registerInfo().createVirtualRegister(Type);
if (!Result)
@@ -1272,8 +1273,8 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
}
[[nodiscard]] Expected<Register> buildBinaryBefore(MachineIRBuilder &Builder, MachineInstr &Anchor,
- GenericOpcode Generic, LLT Type, Register Left,
- Register Right) {
+ GenericOpcode Generic, LowLevelType Type,
+ Register Left, Register Right) {
auto Result = Builder.function().registerInfo().createVirtualRegister(Type);
if (!Result)
return std::unexpected(Result.error());
@@ -1321,7 +1322,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
[[nodiscard]] Expected<void> widenNarrowMultiply(MachineInstr &Instruction,
MachineFunction &Function,
const TargetDescription &Target) {
- const std::optional<LLT> Type = resultType(Function, Instruction);
+ const std::optional<LowLevelType> Type = resultType(Function, Instruction);
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
const MachineOperand *LeftOperand = Instruction.operandAt(1);
const MachineOperand *RightOperand = Instruction.operandAt(2);
@@ -1342,7 +1343,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
return foldNarrowAnyExtBinary(*Extension, Function, Target);
}
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -1365,7 +1366,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
const TargetDescription &Target,
CallingConvention Convention,
const TargetCallLowering &CallLowering) {
- const std::optional<LLT> Type = resultType(Function, Instruction);
+ const std::optional<LowLevelType> Type = resultType(Function, Instruction);
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
const MachineOperand *LeftOperand = Instruction.operandAt(1);
const MachineOperand *RightOperand = Instruction.operandAt(2);
@@ -1387,6 +1388,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
return ABIValue{
.Value = Reg,
.Type = Type,
+ .Category = ABIValueCategory::Integer,
.OriginalValue = Number,
.FragmentIndex = 0,
.FragmentCount = 1,
@@ -1488,7 +1490,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
}
}
}
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
return buildUnaryBefore(Builder, Anchor, GenericOpcode::G_ZEXT, *WideType, Source);
@@ -1562,7 +1564,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
[[nodiscard]] Expected<void> lowerMergeValues(MachineInstr &Instruction, MachineFunction &Function,
const TargetDescription &Target) {
- const std::optional<LLT> DestinationType = resultType(Function, Instruction);
+ const std::optional<LowLevelType> DestinationType = resultType(Function, Instruction);
if (!DestinationType || DestinationType->scalarBitWidth() == 0)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V merge destination has no scalar type");
@@ -1582,7 +1584,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
MachineInstr *Use = singleUseInstruction(Function, *Destination);
if (Use != nullptr && Use->opcode() == opcode(GenericOpcode::G_ZEXT) &&
operandType(Function, *Use, 0)
- .transform([](LLT Type) { return Type.scalarBitWidth() == 64; })
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() == 64; })
.value_or(false)) {
const MachineOperand *ExtendedOperand = Use->operandAt(0);
const Register *Extended =
@@ -1594,7 +1596,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
}
}
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -1613,7 +1615,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
Terms.push_back(*WideSource);
continue;
}
- const std::optional<LLT> SourceType = registerType(Function, *Operand);
+ const std::optional<LowLevelType> SourceType = registerType(Function, *Operand);
if (!SourceType)
return makeUnexpected(ErrorCode::VerificationError, "RISC-V merge source has no scalar type");
const std::uint64_t Shift =
@@ -1758,8 +1760,8 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V unmerge has invalid register operands");
const std::size_t OutputCount = Instruction.operandCount() - 1U;
- const std::optional<LLT> OutputType = operandType(Function, Instruction, 0);
- const std::optional<LLT> SourceType = operandType(Function, Instruction, OutputCount);
+ const std::optional<LowLevelType> OutputType = operandType(Function, Instruction, 0);
+ const std::optional<LowLevelType> SourceType = operandType(Function, Instruction, OutputCount);
if (!OutputType || !SourceType)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V unmerge operands have no scalar types");
@@ -1770,7 +1772,7 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
const Register *Source = SourceOperand == nullptr ? nullptr : SourceOperand->getIf<Register>();
if (Source == nullptr)
return makeUnexpected(ErrorCode::VerificationError, "RISC-V unmerge source is not a register");
- auto WideType = LLT::makeAnyScalar(64);
+ auto WideType = LowLevelType::makeCategoryNeutralScalar(64);
if (!WideType)
return std::unexpected(WideType.error());
MachineIRBuilder Builder(Function, Target);
@@ -1794,11 +1796,11 @@ void eraseDeadArtifacts(std::span<MachineInstr *const> Candidates,
}
MachineInstr *Extension = singleUseInstruction(Function, *Output);
- const bool FoldZExt = Extension != nullptr &&
- Extension->opcode() == opcode(GenericOpcode::G_ZEXT) &&
- operandType(Function, *Extension, 0)
- .transform([](LLT Type) { return Type.scalarBitWidth() == 64; })
- .value_or(false);
+ const bool FoldZExt =
+ Extension != nullptr && Extension->opcode() == opcode(GenericOpcode::G_ZEXT) &&
+ operandType(Function, *Extension, 0)
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() == 64; })
+ .value_or(false);
if (FoldZExt) {
const MachineOperand *ExtendedOperand = Extension->operandAt(0);
const Register *Extended =
@@ -1851,7 +1853,7 @@ collectWideValueParts(Register Value, MachineFunction &Function, unsigned Depth
const auto Type = registerType(Function, Value);
if (!Type)
return makeUnexpected(ErrorCode::VerificationError, "RISC-V wide value has no scalar type");
- if ((!Type->isInteger() && !Type->isAnyScalar()) || Type->scalarBitWidth() == 0)
+ if (!Type->isCategoryNeutralScalar() || Type->scalarBitWidth() == 0)
return makeUnexpected(ErrorCode::Unsupported,
"RISC-V wide-value decomposition requires an integer scalar");
if (Type->scalarBitWidth() <= 64)
@@ -1869,7 +1871,7 @@ collectWideValueParts(Register Value, MachineFunction &Function, unsigned Depth
for (std::size_t Index = 1; Index < Def->operandCount(); ++Index) {
const MachineOperand *Operand = Def->operandAt(Index);
const Register *Part = Operand == nullptr ? nullptr : Operand->getIf<Register>();
- const std::optional<LLT> PartType =
+ const std::optional<LowLevelType> PartType =
Operand == nullptr ? std::nullopt : registerType(Function, *Operand);
if (Part == nullptr || !PartType || PartType->scalarBitWidth() != 64)
return makeUnexpected(ErrorCode::Unsupported,
@@ -1932,7 +1934,7 @@ struct WideResultPlan final {
for (std::size_t Index = 0; Index < RequiredParts; ++Index) {
const MachineOperand *Operand = Use->operandAt(Index);
const Register *Output = Operand == nullptr ? nullptr : Operand->getIf<Register>();
- const std::optional<LLT> Type =
+ const std::optional<LowLevelType> Type =
Operand == nullptr ? std::nullopt : registerType(Function, *Operand);
if (Output == nullptr || !Type || Type->scalarBitWidth() != 64)
return makeUnexpected(ErrorCode::Unsupported,
@@ -1946,7 +1948,7 @@ struct WideResultPlan final {
MachineInstr &Anchor,
IntegerPredicate Predicate,
Register Left, Register Right) {
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
auto Result = Builder.function().registerInfo().createVirtualRegister(*Type);
@@ -1973,8 +1975,8 @@ struct WideResultPlan final {
}
[[nodiscard]] Expected<Register> buildSelectBefore(MachineIRBuilder &Builder, MachineInstr &Anchor,
- LLT Type, Register Condition, Register TrueValue,
- Register FalseValue) {
+ LowLevelType Type, Register Condition,
+ Register TrueValue, Register FalseValue) {
auto Result = Builder.function().registerInfo().createVirtualRegister(Type);
if (!Result)
return std::unexpected(Result.error());
@@ -2007,7 +2009,7 @@ struct TwoLimbShiftResult final {
emitTwoLimbLeftShiftBody(MachineIRBuilder &Builder, MachineInstr &Anchor, Register Low,
Register High, Register Amount, Register AmountExcess, Register AmountLack,
Register Zero, Register IsShort, Register IsZero) {
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
auto LowShort = buildBinaryBefore(Builder, Anchor, GenericOpcode::G_SHL, *Type, Low, Amount);
@@ -2042,7 +2044,7 @@ emitTwoLimbLeftShiftBody(MachineIRBuilder &Builder, MachineInstr &Anchor, Regist
[[nodiscard]] Expected<TwoLimbShiftResult> emitTwoLimbLeftShift(MachineIRBuilder &Builder,
MachineInstr &Anchor, Register Low,
Register High, Register Amount) {
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
auto Boundary = buildIntegerConstantBefore(Builder, Anchor, 64, 64);
@@ -2074,7 +2076,7 @@ emitTwoLimbLeftShiftBody(MachineIRBuilder &Builder, MachineInstr &Anchor, Regist
emitLowLimbOfTwoLimbLogicalRightShift(MachineIRBuilder &Builder, MachineInstr &Anchor, Register Low,
Register High, Register Amount, Register Boundary,
Register Zero) {
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
auto AmountExcess =
@@ -2119,7 +2121,7 @@ emitThreeLimbLeftShift(MachineIRBuilder &Builder, MachineInstr &Anchor,
if (Parts.size() != 3)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V three-limb shift requires exactly three limbs");
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
@@ -2291,7 +2293,7 @@ emitThreeLimbLeftShift(MachineIRBuilder &Builder, MachineInstr &Anchor,
if (Left.size() != Right.size() || Left.size() < 2)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V wide add requires matching multi-limb operands");
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
std::vector<Register> Results;
@@ -2356,7 +2358,7 @@ emitThreeLimbLeftShift(MachineIRBuilder &Builder, MachineInstr &Anchor,
if (Left.size() != Right.size() || Left.size() < 2)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V wide sub requires matching multi-limb operands");
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
std::vector<Register> Results;
@@ -2415,7 +2417,7 @@ emitWideBitwise(MachineIRBuilder &Builder, MachineInstr &Anchor, GenericOpcode G
if (Left.size() != Right.size() || Left.size() < 2)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V wide bitwise operation requires matching multi-limb operands");
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
std::vector<Register> Results;
@@ -2500,7 +2502,8 @@ emitWideBitwise(MachineIRBuilder &Builder, MachineInstr &Anchor, GenericOpcode G
Truncation->opcode() != opcode(GenericOpcode::G_TRUNC) || Truncation->operandCount() != 2)
return false;
return operandType(Function, *Truncation, 1)
- .transform([](LLT Type) { return isScalarGPRType(Type) && Type.scalarBitWidth() == 64; })
+ .transform(
+ [](LowLevelType Type) { return isScalarGPRType(Type) && Type.scalarBitWidth() == 64; })
.value_or(false);
}
@@ -2515,7 +2518,7 @@ emitWideBitwise(MachineIRBuilder &Builder, MachineInstr &Anchor, GenericOpcode G
const MachineOperand *Definition = Function.registerInfo().getUniqueVRegDef(Condition);
MachineInstr *Truncation = const_cast<MachineInstr *>(Definition->parent());
const Register Source = *Truncation->operandAt(1)->getIf<Register>();
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
MachineIRBuilder Builder(Function, Target);
@@ -2549,7 +2552,7 @@ struct NarrowPhiIncoming final {
[[nodiscard]] Expected<Register>
buildIncomingConversion(MachineFunction &Function, const TargetDescription &Target,
MachineBasicBlock &Block, MachineInstr *Anchor, GenericOpcode Generic,
- LLT Type, Register Source) {
+ LowLevelType Type, Register Source) {
auto Result = Function.registerInfo().createVirtualRegister(Type);
if (!Result)
return std::unexpected(Result.error());
@@ -2573,14 +2576,14 @@ buildIncomingConversion(MachineFunction &Function, const TargetDescription &Targ
[[nodiscard]] Expected<void> lowerNarrowPhi(MachineInstr &Instruction, MachineFunction &Function,
const TargetDescription &Target) {
- const std::optional<LLT> OriginalType = resultType(Function, Instruction);
+ const std::optional<LowLevelType> OriginalType = resultType(Function, Instruction);
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
const Register *Destination =
DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>();
if (!OriginalType || Destination == nullptr || OriginalType->scalarBitWidth() >= 32 ||
Instruction.operandCount() < 3 || (Instruction.operandCount() % 2U) == 0)
return makeUnexpected(ErrorCode::VerificationError, "RISC-V narrow PHI has invalid operands");
- auto LegalType = LLT::makeAnyScalar(32);
+ auto LegalType = LowLevelType::makeCategoryNeutralScalar(32);
if (!LegalType)
return std::unexpected(LegalType.error());
@@ -2603,7 +2606,7 @@ buildIncomingConversion(MachineFunction &Function, const TargetDescription &Targ
if (Def != nullptr && Def->opcode() == opcode(GenericOpcode::G_TRUNC) &&
Def->operandCount() == 2 && singleRegisterUse(Function, *Value) == &Instruction &&
operandType(Function, *Def, 1)
- .transform([](LLT Type) { return Type.scalarBitWidth() >= 32; })
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() >= 32; })
.value_or(false)) {
Reusable = Def;
}
@@ -2731,7 +2734,7 @@ buildIncomingConversion(MachineFunction &Function, const TargetDescription &Targ
auto ResultPlan = wideResultPlan(*Destination, Function, PartCount);
if (!ResultPlan)
return std::unexpected(ResultPlan.error());
- auto Type = LLT::makeAnyScalar(64);
+ auto Type = LowLevelType::makeCategoryNeutralScalar(64);
if (!Type)
return std::unexpected(Type.error());
MachineIRBuilder Builder(Function, Target);
@@ -2800,7 +2803,7 @@ buildIncomingConversion(MachineFunction &Function, const TargetDescription &Targ
if (Trunc == nullptr || Trunc->opcode() != opcode(GenericOpcode::G_TRUNC) ||
Trunc->operandAt(1) != &Use)
return false;
- const std::optional<LLT> Result = resultType(Function, *Trunc);
+ const std::optional<LowLevelType> Result = resultType(Function, *Trunc);
if (!Result || Result->scalarBitWidth() > LowType->scalarBitWidth())
return false;
}
@@ -2813,13 +2816,14 @@ struct RV64ScalarLayout final {
std::uint64_t ABIAlignment = 0;
};
-[[nodiscard]] std::optional<RV64ScalarLayout> rv64ScalarLayout(LLT Type) noexcept {
+[[nodiscard]] std::optional<RV64ScalarLayout> rv64ScalarLayout(LowLevelType Type) noexcept {
if (Type.isPointer()) {
return Type.addressSpace() == 0 && Type.scalarBitWidth() == 64
? std::optional<RV64ScalarLayout>{{8, 8, 8}}
: std::nullopt;
}
- if ((!isSupportedIntegerType(Type) && !isRVFloatType(Type)) || Type.scalarBitWidth() == 0) {
+ if ((!isSupportedIntegerType(Type) && !isSupportedFloatingScalar(Type)) ||
+ Type.scalarBitWidth() == 0) {
return std::nullopt;
}
const std::uint64_t StoreBytes = (Type.scalarBitWidth() + 7U) / 8U;
@@ -2828,7 +2832,7 @@ struct RV64ScalarLayout final {
}
[[nodiscard]] Expected<const MachineMemOperand *>
-createMemoryAccess(MachineFunction &Function, MemoryAccessFlag Access, LLT Type,
+createMemoryAccess(MachineFunction &Function, MemoryAccessFlag Access, LowLevelType Type,
std::uint64_t SizeBytes, std::uint64_t AlignmentBytes) {
auto Size = MemorySize::fixed(SizeBytes);
auto Align = Alignment::create(AlignmentBytes);
@@ -2845,8 +2849,8 @@ createMemoryAccess(MachineFunction &Function, MemoryAccessFlag Access, LLT Type,
struct VAArgPlan final {
Register Destination;
Register ListPointer;
- LLT DestinationType;
- LLT PointerType;
+ LowLevelType DestinationType;
+ LowLevelType PointerType;
std::uint64_t Alignment = 0;
RV64ScalarLayout ValueLayout;
};
@@ -2863,8 +2867,8 @@ struct VAArgPlan final {
const Register *Destination =
DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>();
const Register *ListPointer = ListOperand == nullptr ? nullptr : ListOperand->getIf<Register>();
- const std::optional<LLT> DestinationType = resultType(Function, Instruction);
- const std::optional<LLT> PointerType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> DestinationType = resultType(Function, Instruction);
+ const std::optional<LowLevelType> PointerType = operandType(Function, Instruction, 1);
const auto AlignmentValue = AlignmentOperand == nullptr
? Expected<std::int64_t>(std::unexpected(
Error(ErrorCode::InvalidArgument, "missing alignment")))
@@ -2989,7 +2993,7 @@ struct VAArgPlan final {
struct VACopyPlan final {
Register Destination;
Register Source;
- LLT PointerType;
+ LowLevelType PointerType;
};
[[nodiscard]] std::optional<VACopyPlan> vacopyPlan(const MachineInstr &Instruction,
@@ -3006,8 +3010,8 @@ struct VACopyPlan final {
const Register *Destination =
DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>();
const Register *Source = SourceOperand == nullptr ? nullptr : SourceOperand->getIf<Register>();
- const std::optional<LLT> DestinationType = operandType(Function, Instruction, 1);
- const std::optional<LLT> SourceType = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> DestinationType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> SourceType = operandType(Function, Instruction, 2);
if (Intrinsic == nullptr || Intrinsic->ID != intrinsicID(GenericIntrinsic::VACopy) ||
Destination == nullptr || Source == nullptr || !Destination->isVirtual() ||
!Source->isVirtual() || !DestinationOperand->isUse() || !SourceOperand->isUse() ||
@@ -3095,7 +3099,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
return LegalizationAction::Legal;
const GenericOpcode Generic = static_cast<GenericOpcode>(Instruction.opcode().value());
- const std::optional<LLT> Type = resultType(Function, Instruction);
+ const std::optional<LowLevelType> Type = resultType(Function, Instruction);
switch (Generic) {
case GenericOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
return vacopyPlan(Instruction, Function) ? LegalizationAction::Custom
@@ -3110,7 +3114,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_BR:
return LegalizationAction::Legal;
case GenericOpcode::G_BRCOND: {
- const std::optional<LLT> Condition = operandType(Function, Instruction, 0);
+ const std::optional<LowLevelType> Condition = operandType(Function, Instruction, 0);
if (!Condition || !isScalarGPRType(*Condition))
return LegalizationAction::Unsupported;
return canLowerNarrowBranchCondition(Instruction, Function) ? LegalizationAction::Custom
@@ -3120,28 +3124,28 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
if (!Type)
return LegalizationAction::Unsupported;
for (std::size_t Index = 1; Index < Instruction.operandCount(); Index += 2) {
- const std::optional<LLT> Incoming = operandType(Function, Instruction, Index);
+ const std::optional<LowLevelType> Incoming = operandType(Function, Instruction, Index);
if (!Incoming || *Incoming != *Type)
return LegalizationAction::Unsupported;
}
- if ((Type->isInteger() || Type->isAnyScalar()) && Type->scalarBitWidth() > 64)
+ if (Type->isCategoryNeutralScalar() && Type->scalarBitWidth() > 64)
return LegalizationAction::Custom;
- if ((Type->isInteger() || Type->isAnyScalar()) && Type->scalarBitWidth() < 32)
+ if (Type->isCategoryNeutralScalar() && Type->scalarBitWidth() < 32)
return LegalizationAction::Custom;
- if (!isSupportedIntegerType(*Type) && !isRVFloatType(*Type))
+ if (!isSupportedIntegerType(*Type))
return LegalizationAction::Unsupported;
return LegalizationAction::Legal;
}
case GenericOpcode::G_IMPLICIT_DEF:
- return Type && (isSupportedIntegerType(*Type) || isRVFloatType(*Type))
- ? LegalizationAction::Legal
- : LegalizationAction::Unsupported;
+ return Type && isSupportedIntegerType(*Type) ? LegalizationAction::Legal
+ : LegalizationAction::Unsupported;
case GenericOpcode::G_STORE:
if (Instruction.operandCount() == 0)
return LegalizationAction::Unsupported;
- if (const std::optional<LLT> ValueType = registerType(Function, *Instruction.operandAt(0));
+ if (const std::optional<LowLevelType> ValueType =
+ registerType(Function, *Instruction.operandAt(0));
ValueType) {
- const std::optional<LLT> AddressType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> AddressType = operandType(Function, Instruction, 1);
if (!AddressType || !AddressType->isPointer() || AddressType->addressSpace() != 0 ||
AddressType->scalarBitWidth() != 64) {
return LegalizationAction::Unsupported;
@@ -3153,8 +3157,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
- if ((isSupportedIntegerType(*ValueType) || isRVFloatType(*ValueType)) &&
- isSupportedNonAtomicMemoryAccess(Instruction) &&
+ if (isSupportedIntegerType(*ValueType) && isSupportedNonAtomicMemoryAccess(Instruction) &&
memoryMatchesType(Instruction, *ValueType)) {
return LegalizationAction::Legal;
}
@@ -3163,7 +3166,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_SEXTLOAD:
case GenericOpcode::G_ZEXTLOAD: {
const auto Bytes = memoryAccessBytes(Instruction);
- const std::optional<LLT> AddressType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> AddressType = operandType(Function, Instruction, 1);
return Type && Bytes && AddressType && isSupportedIntegerType(*Type) &&
AddressType->isPointer() && AddressType->addressSpace() == 0 &&
AddressType->scalarBitWidth() == 64 &&
@@ -3175,19 +3178,19 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_FPEXTLOAD: {
const auto Bytes = memoryAccessBytes(Instruction);
- const std::optional<LLT> AddressType = operandType(Function, Instruction, 1);
- return Type && Bytes && AddressType && Type->isFloat() && Type->scalarBitWidth() == 64 &&
- AddressType->isPointer() && AddressType->addressSpace() == 0 &&
- AddressType->scalarBitWidth() == 64 && *Bytes == 4 &&
- isSupportedNonAtomicMemoryAccess(Instruction)
+ const std::optional<LowLevelType> AddressType = operandType(Function, Instruction, 1);
+ return Type && Bytes && AddressType && Type->isCategoryNeutralScalar() &&
+ Type->scalarBitWidth() == 64 && AddressType->isPointer() &&
+ AddressType->addressSpace() == 0 && AddressType->scalarBitWidth() == 64 &&
+ *Bytes == 4 && isSupportedNonAtomicMemoryAccess(Instruction)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FPTRUNCSTORE: {
- const std::optional<LLT> ValueType = operandType(Function, Instruction, 0);
- const std::optional<LLT> AddressType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> ValueType = operandType(Function, Instruction, 0);
+ const std::optional<LowLevelType> AddressType = operandType(Function, Instruction, 1);
const auto Bytes = memoryAccessBytes(Instruction);
- return ValueType && AddressType && Bytes && ValueType->isFloat() &&
+ return ValueType && AddressType && Bytes && ValueType->isCategoryNeutralScalar() &&
ValueType->scalarBitWidth() == 64 && AddressType->isPointer() &&
AddressType->addressSpace() == 0 && AddressType->scalarBitWidth() == 64 &&
*Bytes == 4 && isSupportedNonAtomicMemoryAccess(Instruction)
@@ -3196,7 +3199,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_LOAD:
if (Type) {
- const std::optional<LLT> AddressType = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> AddressType = operandType(Function, Instruction, 1);
if (!AddressType || !AddressType->isPointer() || AddressType->addressSpace() != 0 ||
AddressType->scalarBitWidth() != 64) {
return LegalizationAction::Unsupported;
@@ -3208,8 +3211,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
- if ((isSupportedIntegerType(*Type) || isRVFloatType(*Type)) &&
- isSupportedNonAtomicMemoryAccess(Instruction) && memoryMatchesType(Instruction, *Type)) {
+ if (isSupportedIntegerType(*Type) && isSupportedNonAtomicMemoryAccess(Instruction) &&
+ memoryMatchesType(Instruction, *Type)) {
return LegalizationAction::Legal;
}
}
@@ -3218,33 +3221,35 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_FSUB:
case GenericOpcode::G_FMUL:
case GenericOpcode::G_FDIV: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
- return Type && Left && Right && isRVFloatType(*Type) && *Left == *Type && *Right == *Type
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
+ return Type && Left && Right && isSupportedFloatingScalar(*Type) && *Left == *Type &&
+ *Right == *Type
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FMA: {
- const std::optional<LLT> First = operandType(Function, Instruction, 1);
- const std::optional<LLT> Second = operandType(Function, Instruction, 2);
- const std::optional<LLT> Third = operandType(Function, Instruction, 3);
- return Type && First && Second && Third && isRVFloatType(*Type) && *First == *Type &&
- *Second == *Type && *Third == *Type
+ const std::optional<LowLevelType> First = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Second = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Third = operandType(Function, Instruction, 3);
+ return Type && First && Second && Third && isSupportedFloatingScalar(*Type) &&
+ *First == *Type && *Second == *Type && *Third == *Type
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FNEG:
case GenericOpcode::G_FABS:
case GenericOpcode::G_FSQRT: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- return Type && Source && isRVFloatType(*Type) && *Source == *Type
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && isSupportedFloatingScalar(*Type) && *Source == *Type
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FCOPYSIGN: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
- return Type && Left && Right && isRVFloatType(*Type) && *Left == *Type && *Right == *Type
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
+ return Type && Left && Right && isSupportedFloatingScalar(*Type) && *Left == *Type &&
+ *Right == *Type
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
@@ -3252,16 +3257,15 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
const MachineOperand *Immediate = Instruction.operandAt(1);
const auto *Floating =
Immediate == nullptr ? nullptr : Immediate->getIf<FloatingImmediateOperand>();
- const std::optional<FloatSemantics> Semantics = Type ? Type->floatSemantics() : std::nullopt;
- return Type && isRVFloatType(*Type) && Floating != nullptr && Semantics &&
- Floating->Bits.semantics() == *Semantics
+ return Type && isSupportedFloatingScalar(*Type) && Floating != nullptr &&
+ Floating->Bits.bitWidth() == Type->scalarBitWidth()
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_ASSERT_SEXT:
case GenericOpcode::G_ASSERT_ZEXT:
case GenericOpcode::G_ASSERT_ALIGN: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
return Type && Source && *Type == *Source && isScalarGPRType(*Type) &&
Instruction.operandCount() == 3
? LegalizationAction::Legal
@@ -3269,38 +3273,35 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_FREEZE:
case GenericOpcode::G_CONSTANT_FOLD_BARRIER: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- return Type && Source && *Type == *Source &&
- (isSupportedIntegerType(*Type) || isRVFloatType(*Type))
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && *Type == *Source && isSupportedIntegerType(*Type)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_PTRTOINT: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- return Type && Source && Type->isInteger() && Type->scalarBitWidth() == 64 &&
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 64 &&
Source->isPointer() && Source->scalarBitWidth() == 64
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_INTTOPTR: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
return Type && Source && Type->isPointer() && Type->scalarBitWidth() == 64 &&
- Source->isInteger() && Source->scalarBitWidth() == 64
+ Source->isCategoryNeutralScalar() && Source->scalarBitWidth() == 64
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_BITCAST: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- const bool IntegerFloatPair =
- Type && Source && Type->scalarBitWidth() == Source->scalarBitWidth() &&
- ((Type->isFloat() && Source->isInteger()) || (Type->isInteger() && Source->isFloat())) &&
- (Type->scalarBitWidth() == 32 || Type->scalarBitWidth() == 64);
- return IntegerFloatPair ? LegalizationAction::Legal : LegalizationAction::Unsupported;
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && *Type != *Source && Type->scalarBitWidth() == Source->scalarBitWidth()
+ ? LegalizationAction::Legal
+ : LegalizationAction::Unsupported;
}
case GenericOpcode::G_ANYEXT:
case GenericOpcode::G_SEXT:
case GenericOpcode::G_ZEXT: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
if (!Type || !Source)
return LegalizationAction::Unsupported;
if (!isScalarIntegerExtension(*Type, *Source)) {
@@ -3309,8 +3310,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>();
MachineInstr *OnlyUse =
Destination == nullptr ? nullptr : singleUseInstruction(Function, *Destination);
- return (Type->isInteger() || Type->isAnyScalar()) &&
- (Source->isInteger() || Source->isAnyScalar()) &&
+ return Type->isCategoryNeutralScalar() && Source->isCategoryNeutralScalar() &&
Type->scalarBitWidth() > 64 &&
Source->scalarBitWidth() < Type->scalarBitWidth() && OnlyUse != nullptr &&
OnlyUse->opcode() == opcode(GenericOpcode::G_UNMERGE_VALUES)
@@ -3334,10 +3334,9 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
return LegalizationAction::Legal;
}
case GenericOpcode::G_TRUNC: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- if (Type && Source && (Type->isInteger() || Type->isAnyScalar()) &&
- (Source->isInteger() || Source->isAnyScalar()) && Type->scalarBitWidth() > 64 &&
- Source->scalarBitWidth() > Type->scalarBitWidth())
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ if (Type && Source && Type->isCategoryNeutralScalar() && Source->isCategoryNeutralScalar() &&
+ Type->scalarBitWidth() > 64 && Source->scalarBitWidth() > Type->scalarBitWidth())
return LegalizationAction::Legal;
return Type && Source && isSupportedIntegerScalar(*Type) && isSupportedIntegerScalar(*Source) &&
Type->scalarBitWidth() != 0 && Source->scalarBitWidth() >= Type->scalarBitWidth()
@@ -3351,19 +3350,20 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
const std::size_t SmallTypeIndex = Generic == GenericOpcode::G_MERGE_VALUES ? 1 : 0;
const std::size_t BigTypeIndex =
Generic == GenericOpcode::G_MERGE_VALUES ? 0 : Instruction.operandCount() - 1U;
- const std::optional<LLT> SmallType = operandType(Function, Instruction, SmallTypeIndex);
- const std::optional<LLT> BigType = operandType(Function, Instruction, BigTypeIndex);
+ const std::optional<LowLevelType> SmallType =
+ operandType(Function, Instruction, SmallTypeIndex);
+ const std::optional<LowLevelType> BigType = operandType(Function, Instruction, BigTypeIndex);
if (SmallType && BigType && Generic == GenericOpcode::G_MERGE_VALUES &&
BigType->scalarBitWidth() > 64 && !canFoldWideMergeImmediately(Instruction, Function))
return LegalizationAction::Legal;
- return SmallType && BigType && (SmallType->isInteger() || SmallType->isAnyScalar()) &&
- (BigType->isInteger() || BigType->isAnyScalar()) &&
- SmallType->scalarBitWidth() != 0 && BigType->scalarBitWidth() != 0
+ return SmallType && BigType && SmallType->isCategoryNeutralScalar() &&
+ BigType->isCategoryNeutralScalar() && SmallType->scalarBitWidth() != 0 &&
+ BigType->scalarBitWidth() != 0
? LegalizationAction::Custom
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_SEXT_INREG: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
const MachineOperand *WidthOperand = Instruction.operandAt(2);
const auto Width =
WidthOperand == nullptr
@@ -3379,8 +3379,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
const MachineOperand *Predicate = Instruction.operandAt(1);
const auto *IntegerPredicate =
Predicate == nullptr ? nullptr : Predicate->getIf<PredicateOperand>();
- const std::optional<LLT> Left = operandType(Function, Instruction, 2);
- const std::optional<LLT> Right = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 3);
if (!Type || !isSupportedIntegerScalar(*Type) || IntegerPredicate == nullptr ||
IntegerPredicate->integerPredicate() == nullptr || !Left || !Right || *Left != *Right ||
!isSupportedIntegerType(*Left)) {
@@ -3394,19 +3394,20 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
const MachineOperand *Predicate = Instruction.operandAt(1);
const auto *FloatingPredicate =
Predicate == nullptr ? nullptr : Predicate->getIf<PredicateOperand>();
- const std::optional<LLT> Left = operandType(Function, Instruction, 2);
- const std::optional<LLT> Right = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 3);
return Type && isI1Type(*Type) && FloatingPredicate != nullptr &&
FloatingPredicate->floatingPredicate() != nullptr && Left && Right &&
- *Left == *Right && isRVFloatType(*Left)
+ *Left == *Right && isSupportedFloatingScalar(*Left)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FPEXT:
case GenericOpcode::G_FPTRUNC: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
const bool IsExtension = Generic == GenericOpcode::G_FPEXT;
- return Type && Source && isRVFloatType(*Type) && isRVFloatType(*Source) &&
+ return Type && Source && isSupportedFloatingScalar(*Type) &&
+ isSupportedFloatingScalar(*Source) &&
((IsExtension && Source->scalarBitWidth() == 32 &&
Type->scalarBitWidth() == 64) ||
(!IsExtension && Source->scalarBitWidth() == 64 &&
@@ -3416,39 +3417,39 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_FPTOSI:
case GenericOpcode::G_FPTOUI: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- return Type && Source && isSupportedIntegerType(*Type) && isRVFloatType(*Source)
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && isSupportedIntegerType(*Type) && isSupportedFloatingScalar(*Source)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_SITOFP:
case GenericOpcode::G_UITOFP: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
- return Type && Source && isRVFloatType(*Type) && isSupportedIntegerType(*Source)
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
+ return Type && Source && isSupportedFloatingScalar(*Type) && isSupportedIntegerType(*Source)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_FMINNUM:
case GenericOpcode::G_FMAXNUM: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
- return Type && Left && Right && isRVFloatType(*Type) && *Left == *Type && *Right == *Type
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
+ return Type && Left && Right && isSupportedFloatingScalar(*Type) && *Left == *Type &&
+ *Right == *Type
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_SELECT: {
- const std::optional<LLT> Condition = operandType(Function, Instruction, 1);
- const std::optional<LLT> TrueValue = operandType(Function, Instruction, 2);
- const std::optional<LLT> FalseValue = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Condition = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> TrueValue = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> FalseValue = operandType(Function, Instruction, 3);
return Type && Condition && TrueValue && FalseValue && isScalarGPRType(*Condition) &&
- *TrueValue == *Type && *FalseValue == *Type &&
- (isSupportedIntegerType(*Type) || isRVFloatType(*Type))
+ *TrueValue == *Type && *FalseValue == *Type && isSupportedIntegerType(*Type)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_PTRMASK: {
- const std::optional<LLT> Pointer = operandType(Function, Instruction, 1);
- const std::optional<LLT> Mask = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Pointer = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Mask = operandType(Function, Instruction, 2);
return Type && Pointer && Mask && Type->isPointer() && Type->addressSpace() == 0 &&
Type->scalarBitWidth() == 64 && *Pointer == *Type &&
isSupportedIntegerScalar(*Mask) && Mask->scalarBitWidth() == 64
@@ -3456,16 +3457,16 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_ABS: {
- const std::optional<LLT> Source = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1);
return Type && Source && *Source == *Type && isSupportedIntegerScalar(*Type)
? LegalizationAction::Legal
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_SDIVREM:
case GenericOpcode::G_UDIVREM: {
- const std::optional<LLT> Remainder = operandType(Function, Instruction, 1);
- const std::optional<LLT> Left = operandType(Function, Instruction, 2);
- const std::optional<LLT> Right = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Remainder = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 3);
return Type && Remainder && Left && Right && isSupportedIntegerScalar(*Type) &&
*Remainder == *Type && *Left == *Type && *Right == *Type
? LegalizationAction::Legal
@@ -3473,8 +3474,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_SMULH:
case GenericOpcode::G_UMULH: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
return Type && Left && Right && isNativeIntegerScalar(*Type) && *Left == *Type &&
*Right == *Type
? LegalizationAction::Legal
@@ -3484,8 +3485,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_SMAX:
case GenericOpcode::G_UMIN:
case GenericOpcode::G_UMAX: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
return Type && Left && Right && isSupportedIntegerScalar(*Type) && *Left == *Type &&
*Right == *Type
? LegalizationAction::Legal
@@ -3497,9 +3498,9 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_SSUBO:
case GenericOpcode::G_UMULO:
case GenericOpcode::G_SMULO: {
- const std::optional<LLT> Overflow = operandType(Function, Instruction, 1);
- const std::optional<LLT> Left = operandType(Function, Instruction, 2);
- const std::optional<LLT> Right = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Overflow = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 3);
return Type && Overflow && Left && Right && isNativeIntegerScalar(*Type) &&
isI1Type(*Overflow) && *Left == *Type && *Right == *Type
? LegalizationAction::Legal
@@ -3509,10 +3510,10 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_USUBE:
case GenericOpcode::G_SADDE:
case GenericOpcode::G_SSUBE: {
- const std::optional<LLT> CarryOut = operandType(Function, Instruction, 1);
- const std::optional<LLT> Left = operandType(Function, Instruction, 2);
- const std::optional<LLT> Right = operandType(Function, Instruction, 3);
- const std::optional<LLT> CarryIn = operandType(Function, Instruction, 4);
+ const std::optional<LowLevelType> CarryOut = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> CarryIn = operandType(Function, Instruction, 4);
return Type && CarryOut && Left && Right && CarryIn && isNativeIntegerScalar(*Type) &&
isI1Type(*CarryOut) && isI1Type(*CarryIn) && *Left == *Type && *Right == *Type
? LegalizationAction::Legal
@@ -3528,8 +3529,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_ATOMICRMW_MIN:
case GenericOpcode::G_ATOMICRMW_UMAX:
case GenericOpcode::G_ATOMICRMW_UMIN: {
- const std::optional<LLT> Address = operandType(Function, Instruction, 1);
- const std::optional<LLT> Value = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Address = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Value = operandType(Function, Instruction, 2);
const std::uint64_t Bytes = Type ? Type->scalarBitWidth() / 8U : 0;
return Type && Address && Value && isNativeIntegerScalar(*Type) && *Value == *Type &&
Address->isPointer() && Address->addressSpace() == 0 &&
@@ -3540,11 +3541,11 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_ATOMIC_CMPXCHG: {
- const std::optional<LLT> Address = operandType(Function, Instruction, 1);
- const std::optional<LLT> Compare = operandType(Function, Instruction, 2);
- const std::optional<LLT> NewValue = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> Address = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Compare = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> NewValue = operandType(Function, Instruction, 3);
if (!Type || !Address || !Compare || !NewValue || *Compare != *Type || *NewValue != *Type ||
- (!Type->isInteger() && !Type->isAnyScalar()) ||
+ !Type->isCategoryNeutralScalar() ||
(Type->scalarBitWidth() != 8 && Type->scalarBitWidth() != 16 &&
Type->scalarBitWidth() != 32 && Type->scalarBitWidth() != 64) ||
!Address->isPointer() || Address->addressSpace() != 0 || Address->scalarBitWidth() != 64 ||
@@ -3555,13 +3556,12 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
return Type->scalarBitWidth() == 64 ? LegalizationAction::Legal : LegalizationAction::Custom;
}
case GenericOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
- const std::optional<LLT> Success = operandType(Function, Instruction, 1);
- const std::optional<LLT> Address = operandType(Function, Instruction, 2);
- const std::optional<LLT> Compare = operandType(Function, Instruction, 3);
- const std::optional<LLT> NewValue = operandType(Function, Instruction, 4);
+ const std::optional<LowLevelType> Success = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Address = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Compare = operandType(Function, Instruction, 3);
+ const std::optional<LowLevelType> NewValue = operandType(Function, Instruction, 4);
return Type && Success && Address && Compare && NewValue && isI1Type(*Success) &&
- *Compare == *Type && *NewValue == *Type &&
- (Type->isInteger() || Type->isAnyScalar()) &&
+ *Compare == *Type && *NewValue == *Type && Type->isCategoryNeutralScalar() &&
(Type->scalarBitWidth() == 8 || Type->scalarBitWidth() == 16 ||
Type->scalarBitWidth() == 32 || Type->scalarBitWidth() == 64) &&
Address->isPointer() && Address->addressSpace() == 0 &&
@@ -3605,7 +3605,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
}
case GenericOpcode::G_BRINDIRECT:
return operandType(Function, Instruction, 0)
- .transform([](LLT Value) {
+ .transform([](LowLevelType Value) {
return Value.isPointer() && Value.addressSpace() == 0 &&
Value.scalarBitWidth() == 64;
})
@@ -3629,7 +3629,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
return wideConstantUnmergePlan(Instruction, Function).has_value()
? LegalizationAction::Custom
: LegalizationAction::Unsupported;
- if ((Type->isInteger() || Type->isAnyScalar()) && Type->scalarBitWidth() == 64) {
+ if (Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 64) {
auto Value = signedImmediate(*Immediate);
if (Value && shouldUseRV64IntegerConstantPool(*Value))
return LegalizationAction::Custom;
@@ -3650,10 +3650,10 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
case GenericOpcode::G_SHL:
case GenericOpcode::G_LSHR:
case GenericOpcode::G_ASHR: {
- const std::optional<LLT> Left = operandType(Function, Instruction, 1);
- const std::optional<LLT> Right = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Left = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Right = operandType(Function, Instruction, 2);
if (!Type || !Left || !Right || *Left != *Type || *Right != *Type ||
- (!Type->isInteger() && !Type->isAnyScalar()))
+ !Type->isCategoryNeutralScalar())
return LegalizationAction::Unsupported;
if (Type->scalarBitWidth() > 64) {
return Generic == GenericOpcode::G_ADD || Generic == GenericOpcode::G_SUB ||
@@ -3670,7 +3670,7 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>();
MachineInstr *Extension =
Destination == nullptr ? nullptr : singleRegisterUse(Function, *Destination);
- const std::optional<LLT> ExtensionType =
+ const std::optional<LowLevelType> ExtensionType =
Extension == nullptr ? std::nullopt : resultType(Function, *Extension);
if (Extension != nullptr && Extension->opcode() == opcode(GenericOpcode::G_ANYEXT) &&
ExtensionType && ExtensionType->scalarBitWidth() == 64) {
@@ -3682,8 +3682,8 @@ Expected<LegalizationAction> RISCVLegalizerInfo::classify(const MachineInstr &In
: LegalizationAction::Unsupported;
}
case GenericOpcode::G_PTR_ADD: {
- const std::optional<LLT> Pointer = operandType(Function, Instruction, 1);
- const std::optional<LLT> Offset = operandType(Function, Instruction, 2);
+ const std::optional<LowLevelType> Pointer = operandType(Function, Instruction, 1);
+ const std::optional<LowLevelType> Offset = operandType(Function, Instruction, 2);
return Type && Pointer && Offset && Type->isPointer() && Type->addressSpace() == 0 &&
Type->scalarBitWidth() == 64 && *Pointer == *Type &&
isSupportedIntegerScalar(*Offset) && Offset->scalarBitWidth() == 64
@@ -3737,7 +3737,7 @@ Expected<void> RISCVLegalizerInfo::lower(MachineInstr &Instruction, MachineFunct
}
if (Action == LegalizationAction::Custom &&
resultType(Function, Instruction)
- .transform([](LLT Type) { return Type.scalarBitWidth() > 64; })
+ .transform([](LowLevelType Type) { return Type.scalarBitWidth() > 64; })
.value_or(false)) {
const Opcode Value = Instruction.opcode();
if (Value == opcode(GenericOpcode::G_ADD) || Value == opcode(GenericOpcode::G_SUB) ||
@@ -3783,8 +3783,8 @@ Expected<void> RISCVLegalizerInfo::lower(MachineInstr &Instruction, MachineFunct
if (Action == LegalizationAction::Custom &&
Instruction.opcode() == opcode(GenericOpcode::G_CONSTANT)) {
const MachineOperand *Immediate = Instruction.operandAt(1);
- const std::optional<LLT> Type = resultType(Function, Instruction);
- if (Immediate != nullptr && Type && (Type->isInteger() || Type->isAnyScalar()) &&
+ const std::optional<LowLevelType> Type = resultType(Function, Instruction);
+ if (Immediate != nullptr && Type && Type->isCategoryNeutralScalar() &&
Type->scalarBitWidth() == 64) {
auto Value = signedImmediate(*Immediate);
if (Value && shouldUseRV64IntegerConstantPool(*Value))