aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/Target
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/unittests/Target
parentcd30fb546e389d1fb78ce8e579b3dba3a8fdb52a (diff)
downloadrcc-project-aa69e15c6909c3b162b15f5326f0a72ba9bb7163.tar.gz
rcc-project-aa69e15c6909c3b162b15f5326f0a72ba9bb7163.tar.xz
[CodeGen] Unify scalar low-level types
Diffstat (limited to 'backend/unittests/Target')
-rw-r--r--backend/unittests/Target/RISCVCallLoweringTest.cpp61
-rw-r--r--backend/unittests/Target/RISCVCodeGenTest.cpp178
-rw-r--r--backend/unittests/Target/RISCVLateCodeGenTest.cpp6
-rw-r--r--backend/unittests/Target/RISCVRegisterAllocationTest.cpp9
-rw-r--r--backend/unittests/Target/RISCVSSAExitTest.cpp11
5 files changed, 138 insertions, 127 deletions
diff --git a/backend/unittests/Target/RISCVCallLoweringTest.cpp b/backend/unittests/Target/RISCVCallLoweringTest.cpp
index eee10ab..738aeb1 100644
--- a/backend/unittests/Target/RISCVCallLoweringTest.cpp
+++ b/backend/unittests/Target/RISCVCallLoweringTest.cpp
@@ -61,29 +61,30 @@ private:
return *Value;
}
-[[nodiscard]] rcc::LLT integer(std::uint32_t Bits) {
- const auto Type = rcc::LLT::makeInteger(Bits);
+[[nodiscard]] rcc::LowLevelType integer(std::uint32_t Bits) {
+ const auto Type = rcc::LowLevelType::makeCategoryNeutralScalar(Bits);
if (!Type)
std::terminate();
return *Type;
}
-[[nodiscard]] rcc::LLT anyScalar(std::uint32_t Bits) {
- const auto Type = rcc::LLT::makeAnyScalar(Bits);
+[[nodiscard]] rcc::LowLevelType anyScalar(std::uint32_t Bits) {
+ const auto Type = rcc::LowLevelType::makeCategoryNeutralScalar(Bits);
if (!Type)
std::terminate();
return *Type;
}
-[[nodiscard]] rcc::LLT floating(rcc::FloatSemantics Semantics) {
- const auto Type = rcc::LLT::makeFloat(Semantics);
+[[nodiscard]] rcc::LowLevelType floating(rcc::FloatSemantics Semantics) {
+ const std::uint32_t Bits = Semantics == rcc::FloatSemantics::IEEESingle ? 32 : 64;
+ const auto Type = rcc::LowLevelType::makeCategoryNeutralScalar(Bits);
if (!Type)
std::terminate();
return *Type;
}
-[[nodiscard]] rcc::LLT pointer() {
- const auto Type = rcc::LLT::makePointer(0, 64);
+[[nodiscard]] rcc::LowLevelType pointer() {
+ const auto Type = rcc::LowLevelType::makePointer(0, 64);
if (!Type)
std::terminate();
return *Type;
@@ -128,13 +129,16 @@ private:
return rcc::Register::fromPhysical(physical(rcc::riscv::PhysicalRegisterID::X5));
}
-[[nodiscard]] rcc::ABIValue
-abiValue(rcc::LLT Type, std::uint32_t OriginalValue, rcc::Register Value = planningRegister(),
- rcc::ABIExtensionKind Extension = rcc::ABIExtensionKind::None) {
+[[nodiscard]] rcc::ABIValue abiValue(rcc::LowLevelType Type, std::uint32_t OriginalValue,
+ rcc::Register Value = planningRegister(),
+ rcc::ABIExtensionKind Extension = rcc::ABIExtensionKind::None,
+ std::optional<rcc::ABIValueCategory> Category = std::nullopt) {
const std::uint64_t Size = std::max<std::uint64_t>(1, (Type.scalarBitWidth() + 7U) / 8U);
return {
.Value = Value,
.Type = Type,
+ .Category = Category.value_or(Type.isPointer() ? rcc::ABIValueCategory::Pointer
+ : rcc::ABIValueCategory::Integer),
.OriginalValue = OriginalValue,
.FragmentIndex = 0,
.FragmentCount = 1,
@@ -147,6 +151,13 @@ abiValue(rcc::LLT Type, std::uint32_t OriginalValue, rcc::Register Value = plann
};
}
+[[nodiscard]] rcc::ABIValue floatingABIValue(rcc::FloatSemantics Semantics,
+ std::uint32_t OriginalValue,
+ rcc::Register Value = planningRegister()) {
+ return abiValue(floating(Semantics), OriginalValue, Value, rcc::ABIExtensionKind::None,
+ rcc::ABIValueCategory::FloatingPoint);
+}
+
[[nodiscard]] std::vector<rcc::ABIValue> integerValues(std::size_t Count) {
std::vector<rcc::ABIValue> Values;
Values.reserve(Count);
@@ -160,7 +171,7 @@ abiValue(rcc::LLT Type, std::uint32_t OriginalValue, rcc::Register Value = plann
Values.reserve(Count);
for (std::size_t Index = 0; Index < Count; ++Index) {
Values.push_back(
- abiValue(floating(rcc::FloatSemantics::IEEEDouble), static_cast<std::uint32_t>(Index)));
+ floatingABIValue(rcc::FloatSemantics::IEEEDouble, static_cast<std::uint32_t>(Index)));
}
return Values;
}
@@ -230,8 +241,8 @@ void testIntegerAndFloatingAssignments(TestContext &Context) {
FloatAssignments[16].StackOffsetBytes == 0,
"LP64D floating arguments must fall back from fa0-fa7 to a0-a7 and then stack");
- auto Single = callRequest({abiValue(floating(rcc::FloatSemantics::IEEESingle), 0)}, 1);
- Single.Results = {abiValue(floating(rcc::FloatSemantics::IEEESingle), 0)};
+ auto Single = callRequest({floatingABIValue(rcc::FloatSemantics::IEEESingle, 0)}, 1);
+ Single.Results = {floatingABIValue(rcc::FloatSemantics::IEEESingle, 0)};
auto SinglePlan = CallLowering.planCall(Single);
Context.expect(SinglePlan && SinglePlan->argumentAssignments().size() == 1 &&
SinglePlan->returnAssignments().size() == 1 &&
@@ -241,7 +252,7 @@ void testIntegerAndFloatingAssignments(TestContext &Context) {
physical(rcc::riscv::PhysicalRegisterID::F10_F)),
"LP64D f32 arguments and returns must use the FPR32 physical-register view");
- auto FloatFragment = abiValue(floating(rcc::FloatSemantics::IEEEDouble), 0);
+ auto FloatFragment = floatingABIValue(rcc::FloatSemantics::IEEEDouble, 0);
FloatFragment.FragmentCount = 2;
FloatFragment.OriginalAlignment = align(16);
auto IntegerFragment = abiValue(integer(64), 0);
@@ -265,9 +276,9 @@ void testIntegerAndFloatingAssignments(TestContext &Context) {
GenericScalarPlan->returnAssignments()[0].ValueType == anyScalar(64),
"LLVM generic scalar LLTs must use integer ABI transport without type loss");
- auto LP64Float = callRequest({abiValue(floating(rcc::FloatSemantics::IEEEDouble), 0)}, 1);
+ auto LP64Float = callRequest({floatingABIValue(rcc::FloatSemantics::IEEEDouble, 0)}, 1);
LP64Float.Convention = rcc::riscv::callingConventionID(rcc::riscv::CallingConvention::LP64);
- LP64Float.Results = {abiValue(floating(rcc::FloatSemantics::IEEEDouble), 0)};
+ LP64Float.Results = {floatingABIValue(rcc::FloatSemantics::IEEEDouble, 0)};
auto LP64Plan = CallLowering.planCall(LP64Float);
const auto LP64Mask = rcc::riscv::createCallPreservedMask(rcc::riscv::CallingConvention::LP64);
Context.expect(
@@ -295,8 +306,8 @@ void testIntegerAndFloatingAssignments(TestContext &Context) {
}
void testVariadicAssignments(TestContext &Context) {
- auto FixedFloat = abiValue(floating(rcc::FloatSemantics::IEEEDouble), 0);
- auto VariableFloat = abiValue(floating(rcc::FloatSemantics::IEEEDouble), 1);
+ auto FixedFloat = floatingABIValue(rcc::FloatSemantics::IEEEDouble, 0);
+ auto VariableFloat = floatingABIValue(rcc::FloatSemantics::IEEEDouble, 1);
auto Request = callRequest({FixedFloat, VariableFloat}, 1, true);
auto Plan = CallLowering.planCall(Request);
Context.expect(
@@ -385,8 +396,7 @@ void testSpecialArgumentsAndReturns(TestContext &Context) {
rcc::ReturnLoweringRequest Return;
Return.Convention = convention();
- Return.Values = {abiValue(integer(64), 0),
- abiValue(floating(rcc::FloatSemantics::IEEEDouble), 1)};
+ Return.Values = {abiValue(integer(64), 0), floatingABIValue(rcc::FloatSemantics::IEEEDouble, 1)};
auto ReturnPlan = CallLowering.planReturn(Return);
Context.expect(ReturnPlan && ReturnPlan->returnAssignments().size() == 2 &&
isLocation(ReturnPlan->returnAssignments()[0], returnGPR(0)) &&
@@ -455,7 +465,8 @@ void testTailCalls(TestContext &Context) {
return std::move(*Function);
}
-[[nodiscard]] rcc::Register virtualRegister(rcc::MachineFunction &Function, rcc::LLT Type) {
+[[nodiscard]] rcc::Register virtualRegister(rcc::MachineFunction &Function,
+ rcc::LowLevelType Type) {
auto Register = Function.registerInfo().createVirtualRegister(Type);
if (!Register)
std::terminate();
@@ -500,12 +511,12 @@ void testOrdinaryAndIndirectEmission(TestContext &Context) {
if (!Target || !Function || Block == nullptr)
return;
- const rcc::LLT I64 = integer(64);
- const rcc::LLT F64 = floating(rcc::FloatSemantics::IEEEDouble);
+ const rcc::LowLevelType I64 = integer(64);
+ const rcc::LowLevelType F64 = floating(rcc::FloatSemantics::IEEEDouble);
const rcc::Register Argument = virtualRegister(*Function, I64);
const rcc::Register Result = virtualRegister(*Function, F64);
auto Request = callRequest({abiValue(I64, 0, Argument)}, 1);
- Request.Results = {abiValue(F64, 0, Result)};
+ Request.Results = {floatingABIValue(rcc::FloatSemantics::IEEEDouble, 0, Result)};
rcc::MachineIRBuilder Builder(*Function, *Target);
Context.expect(Builder.setInsertPoint(*Block).has_value(),
diff --git a/backend/unittests/Target/RISCVCodeGenTest.cpp b/backend/unittests/Target/RISCVCodeGenTest.cpp
index 1bc3361..7392f3b 100644
--- a/backend/unittests/Target/RISCVCodeGenTest.cpp
+++ b/backend/unittests/Target/RISCVCodeGenTest.cpp
@@ -66,7 +66,7 @@ struct InstructionFixture final {
auto Block = (*Function)->createBasicBlock();
if (!Block || !(*Function)->appendBlock(**Block))
return {};
- auto Type = rcc::LLT::makeInteger(Bits);
+ auto Type = rcc::LowLevelType::makeCategoryNeutralScalar(Bits);
if (!Type)
return {};
auto Left = (*Function)->registerInfo().createVirtualRegister(*Type);
@@ -87,29 +87,28 @@ struct InstructionFixture final {
}
[[nodiscard]] bool constrainRegister(rcc::MachineFunction &Function, rcc::Register Reg,
- rcc::LLT Type) {
- const auto Bank = Type.isFloat() ? rcc::RegisterBankID::fromValue(
- static_cast<std::uint32_t>(rcc::riscv::RegisterBank::FPR))
- : rcc::RegisterBankID::fromValue(
- static_cast<std::uint32_t>(rcc::riscv::RegisterBank::GPR));
- const auto Class = Type.isFloat()
- ? rcc::RegisterClassID::fromValue(static_cast<std::uint32_t>(
- Type.scalarBitWidth() == 32 ? rcc::riscv::RegisterClass::FPR32
- : rcc::riscv::RegisterClass::FPR64))
- : rcc::RegisterClassID::fromValue(
- static_cast<std::uint32_t>(rcc::riscv::RegisterClass::GPR));
+ rcc::LowLevelType Type, bool Floating = false) {
+ const auto Bank = rcc::RegisterBankID::fromValue(static_cast<std::uint32_t>(
+ Floating ? rcc::riscv::RegisterBank::FPR : rcc::riscv::RegisterBank::GPR));
+ const auto Class = rcc::RegisterClassID::fromValue(static_cast<std::uint32_t>(
+ Floating ? (Type.scalarBitWidth() == 32 ? rcc::riscv::RegisterClass::FPR32
+ : rcc::riscv::RegisterClass::FPR64)
+ : rcc::riscv::RegisterClass::GPR));
return Function.registerInfo().setRegisterBank(Reg, Bank).has_value() &&
Function.registerInfo().setRegisterClass(Reg, Class).has_value();
}
-[[nodiscard]] bool constrainVirtualRegisters(rcc::MachineFunction &Function) {
+[[nodiscard]] bool constrainVirtualRegisters(rcc::MachineFunction &Function,
+ bool FloatingValues = false) {
const auto Registers = Function.registerInfo().virtualRegisters();
for (std::size_t Index = 0; Index < Registers.size(); ++Index) {
const rcc::VirtualRegisterInfo &Info = Registers[Index];
if (Info.IsTombstone)
continue;
auto Reg = rcc::Register::makeVirtual(Index);
- if (!Reg || !Info.Type || !constrainRegister(Function, *Reg, *Info.Type))
+ if (!Reg || !Info.Type ||
+ !constrainRegister(Function, *Reg, *Info.Type,
+ FloatingValues && Info.Type->scalarBitWidth() != 1))
return false;
}
return true;
@@ -128,8 +127,10 @@ struct InstructionFixture final {
[[nodiscard]] std::unique_ptr<rcc::MachineFunction>
createUnaryFunction(TestContext &Context, const rcc::TargetDescription &Target,
- rcc::GenericOpcode Generic, rcc::LLT DestinationType, rcc::LLT SourceType,
- rcc::Register *DestinationOut = nullptr, rcc::Register *SourceOut = nullptr) {
+ rcc::GenericOpcode Generic, rcc::LowLevelType DestinationType,
+ rcc::LowLevelType SourceType, bool FloatingDestination = false,
+ bool FloatingSource = false, rcc::Register *DestinationOut = nullptr,
+ rcc::Register *SourceOut = nullptr) {
auto Function = rcc::MachineFunction::create(
"riscv_unary",
rcc::MachineFunctionStableID::fromValue(200 + static_cast<std::uint32_t>(Generic)));
@@ -143,8 +144,8 @@ createUnaryFunction(TestContext &Context, const rcc::TargetDescription &Target,
auto Source = (*Function)->registerInfo().createVirtualRegister(SourceType);
if (!Destination || !Source)
return nullptr;
- if (!constrainRegister(**Function, *Destination, DestinationType) ||
- !constrainRegister(**Function, *Source, SourceType))
+ if (!constrainRegister(**Function, *Destination, DestinationType, FloatingDestination) ||
+ !constrainRegister(**Function, *Source, SourceType, FloatingSource))
return nullptr;
rcc::MachineIRBuilder Builder(**Function, Target);
if (!Builder.setInsertPoint(**Block))
@@ -161,7 +162,7 @@ createUnaryFunction(TestContext &Context, const rcc::TargetDescription &Target,
[[nodiscard]] std::unique_ptr<rcc::MachineFunction>
createCompareFunction(TestContext &Context, const rcc::TargetDescription &Target,
- rcc::GenericOpcode Generic, rcc::LLT ValueType, bool Floating,
+ rcc::GenericOpcode Generic, rcc::LowLevelType ValueType, bool Floating,
rcc::IntegerPredicate IntegerCondition,
rcc::FloatingPredicate FloatingCondition) {
auto Function = rcc::MachineFunction::create(
@@ -173,15 +174,15 @@ createCompareFunction(TestContext &Context, const rcc::TargetDescription &Target
auto Block = (*Function)->createBasicBlock();
if (!Block || !(*Function)->appendBlock(**Block))
return nullptr;
- auto ResultType = rcc::LLT::makeInteger(1);
+ auto ResultType = rcc::LowLevelType::makeCategoryNeutralScalar(1);
if (!ResultType)
return nullptr;
auto Result = (*Function)->registerInfo().createVirtualRegister(*ResultType);
auto Left = (*Function)->registerInfo().createVirtualRegister(ValueType);
auto Right = (*Function)->registerInfo().createVirtualRegister(ValueType);
if (!Result || !Left || !Right || !constrainRegister(**Function, *Result, *ResultType) ||
- !constrainRegister(**Function, *Left, ValueType) ||
- !constrainRegister(**Function, *Right, ValueType))
+ !constrainRegister(**Function, *Left, ValueType, Floating) ||
+ !constrainRegister(**Function, *Right, ValueType, Floating))
return nullptr;
rcc::MachineIRBuilder Builder(**Function, Target);
if (!Builder.setInsertPoint(**Block))
@@ -202,7 +203,7 @@ createCompareFunction(TestContext &Context, const rcc::TargetDescription &Target
[[nodiscard]] std::unique_ptr<rcc::MachineFunction>
createFloatBinaryFunction(TestContext &Context, const rcc::TargetDescription &Target,
- rcc::GenericOpcode Generic, rcc::LLT Type) {
+ rcc::GenericOpcode Generic, rcc::LowLevelType Type) {
auto Function = rcc::MachineFunction::create(
"riscv_float_binary",
rcc::MachineFunctionStableID::fromValue(700 + static_cast<std::uint32_t>(Generic)));
@@ -215,8 +216,9 @@ createFloatBinaryFunction(TestContext &Context, const rcc::TargetDescription &Ta
auto Left = (*Function)->registerInfo().createVirtualRegister(Type);
auto Right = (*Function)->registerInfo().createVirtualRegister(Type);
auto Result = (*Function)->registerInfo().createVirtualRegister(Type);
- if (!Left || !Right || !Result || !constrainRegister(**Function, *Left, Type) ||
- !constrainRegister(**Function, *Right, Type) || !constrainRegister(**Function, *Result, Type))
+ if (!Left || !Right || !Result || !constrainRegister(**Function, *Left, Type, true) ||
+ !constrainRegister(**Function, *Right, Type, true) ||
+ !constrainRegister(**Function, *Result, Type, true))
return nullptr;
rcc::MachineIRBuilder Builder(**Function, Target);
if (!Builder.setInsertPoint(**Block))
@@ -230,7 +232,8 @@ createFloatBinaryFunction(TestContext &Context, const rcc::TargetDescription &Ta
[[nodiscard]] std::unique_ptr<rcc::MachineFunction> createRegisterOnlyFunction(
TestContext &Context, const rcc::TargetDescription &Target, rcc::GenericOpcode Generic,
- std::initializer_list<rcc::LLT> DefinitionTypes, std::initializer_list<rcc::LLT> UseTypes) {
+ std::initializer_list<rcc::LowLevelType> DefinitionTypes,
+ std::initializer_list<rcc::LowLevelType> UseTypes, bool FloatingValues = false) {
auto Function = rcc::MachineFunction::create(
"riscv_register_only",
rcc::MachineFunctionStableID::fromValue(1000 + static_cast<std::uint32_t>(Generic)));
@@ -246,17 +249,17 @@ createFloatBinaryFunction(TestContext &Context, const rcc::TargetDescription &Ta
auto Pending = Builder.buildInstr(rcc::opcode(Generic));
if (!Pending)
return nullptr;
- for (rcc::LLT Type : DefinitionTypes) {
+ for (rcc::LowLevelType Type : DefinitionTypes) {
auto Reg = (*Function)->registerInfo().createVirtualRegister(Type);
if (!Reg || !Pending->addDef(*Reg))
return nullptr;
}
- for (rcc::LLT Type : UseTypes) {
+ for (rcc::LowLevelType Type : UseTypes) {
auto Reg = (*Function)->registerInfo().createVirtualRegister(Type);
if (!Reg || !Pending->addUse(*Reg))
return nullptr;
}
- if (!Pending->build() || !constrainVirtualRegisters(**Function))
+ if (!Pending->build() || !constrainVirtualRegisters(**Function, FloatingValues))
return nullptr;
return std::move(*Function);
}
@@ -304,8 +307,8 @@ void testClassification(TestContext &Context) {
Context.expect(FloatBlock.has_value(), "floating constant block creation must succeed");
if (!FloatBlock || !(*FloatFunction)->appendBlock(**FloatBlock))
return;
- auto F32 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEESingle);
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
+ auto F32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
Context.expect(F32.has_value() && F64.has_value(),
"RV64GC floating constant types must be constructible");
if (!F32 || !F64)
@@ -442,8 +445,8 @@ void testNarrowIntegerSelection(TestContext &Context) {
"narrow integer selection must satisfy target descriptors");
}
- auto I7 = rcc::LLT::makeInteger(7);
- auto I24 = rcc::LLT::makeInteger(24);
+ auto I7 = rcc::LowLevelType::makeCategoryNeutralScalar(7);
+ auto I24 = rcc::LowLevelType::makeCategoryNeutralScalar(24);
if (!I7 || !I24)
return;
auto Compare = createCompareFunction(Context, *Target, rcc::GenericOpcode::G_ICMP, *I7, false,
@@ -494,11 +497,11 @@ void testScalarSelection(TestContext &Context) {
if (!Target)
return;
- auto I32 = rcc::LLT::makeInteger(32);
- auto I64 = rcc::LLT::makeInteger(64);
- auto F32 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEESingle);
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
- auto I1 = rcc::LLT::makeInteger(1);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto I1 = rcc::LowLevelType::makeCategoryNeutralScalar(1);
Context.expect(I32 && I64 && F32 && F64 && I1, "scalar test types must be constructible");
if (!I32 || !I64 || !F32 || !F64 || !I1)
return;
@@ -546,11 +549,14 @@ void testScalarSelection(TestContext &Context) {
}
}
- auto FPExt = createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPEXT, *F64, *F32);
- auto FPTrunc = createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPTRUNC, *F32, *F64);
- auto FPToSI = createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPTOSI, *I64, *F32);
- auto SIToFP = createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_SITOFP, *F64, *I32);
- auto Bitcast = createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_BITCAST, *I32, *F32);
+ auto FPExt =
+ createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPEXT, *F64, *F32, true, true);
+ auto FPTrunc =
+ createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPTRUNC, *F32, *F64, true, true);
+ auto FPToSI =
+ createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_FPTOSI, *I64, *F32, false, true);
+ auto SIToFP =
+ createUnaryFunction(Context, *Target, rcc::GenericOpcode::G_SITOFP, *F64, *I32, true, false);
if (FPExt) {
auto *Instruction = FPExt->firstBlock()->firstInstruction();
Context.expect((*GISel.Selector).select(*Instruction, *FPExt, *Target).has_value(),
@@ -583,14 +589,6 @@ void testScalarSelection(TestContext &Context) {
rcc::riscv::InstructionOpcode::FCVT_D_W)),
"sitofp must select FCVT.D.W");
}
- if (Bitcast) {
- auto *Instruction = Bitcast->firstBlock()->firstInstruction();
- Context.expect((*GISel.Selector).select(*Instruction, *Bitcast, *Target).has_value(),
- "float-to-integer bitcast must select");
- Context.expect(Instruction->opcode() == rcc::Opcode::fromValue(static_cast<std::uint32_t>(
- rcc::riscv::InstructionOpcode::FMV_X_W)),
- "float-to-integer bitcast must select FMV.X.W");
- }
}
void testComparisonsAndControl(TestContext &Context) {
@@ -598,9 +596,9 @@ void testComparisonsAndControl(TestContext &Context) {
Context.expect(Target.has_value(), "RV64GC target must be available for comparison selection");
if (!Target)
return;
- auto I64 = rcc::LLT::makeInteger(64);
- auto F32 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEESingle);
- auto Pointer = rcc::LLT::makePointer(0, 64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
if (!I64 || !F32 || !Pointer)
return;
@@ -739,10 +737,10 @@ void testCompositeScalarSelection(TestContext &Context) {
Context.expect(Target.has_value(), "RV64GC target must be available for composite selection");
if (!Target)
return;
- auto I1 = rcc::LLT::makeInteger(1);
- auto I32 = rcc::LLT::makeInteger(32);
- auto I64 = rcc::LLT::makeInteger(64);
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
+ auto I1 = rcc::LowLevelType::makeCategoryNeutralScalar(1);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!I1 || !I32 || !I64 || !F64)
return;
@@ -757,9 +755,9 @@ void testCompositeScalarSelection(TestContext &Context) {
auto IntegerSelect = createRegisterOnlyFunction(Context, *Target, rcc::GenericOpcode::G_SELECT,
{*I64}, {*I1, *I64, *I64});
auto FloatSelect = createRegisterOnlyFunction(Context, *Target, rcc::GenericOpcode::G_SELECT,
- {*F64}, {*I1, *F64, *F64});
+ {*F64}, {*I1, *F64, *F64}, true);
auto CopySign = createRegisterOnlyFunction(Context, *Target, rcc::GenericOpcode::G_FCOPYSIGN,
- {*F64}, {*F64, *F64});
+ {*F64}, {*F64, *F64}, true);
const std::array Functions{DivRem.get(), MultiplyHigh.get(), Minimum.get(), Absolute.get(),
IntegerSelect.get(), FloatSelect.get(), CopySign.get()};
for (rcc::MachineFunction *Function : Functions) {
@@ -805,16 +803,16 @@ void testOverflowSelection(TestContext &Context) {
auto Target = rcc::riscv::createTargetDescription();
if (!Target)
return;
- auto I1 = rcc::LLT::makeInteger(1);
- auto I32 = rcc::LLT::makeInteger(32);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I1 = rcc::LowLevelType::makeCategoryNeutralScalar(1);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!I1 || !I32 || !I64)
return;
const std::array Opcodes{rcc::GenericOpcode::G_UADDO, rcc::GenericOpcode::G_USUBO,
rcc::GenericOpcode::G_SADDO, rcc::GenericOpcode::G_SSUBO,
rcc::GenericOpcode::G_UMULO, rcc::GenericOpcode::G_SMULO};
for (rcc::GenericOpcode Generic : Opcodes) {
- const rcc::LLT Type = Generic == rcc::GenericOpcode::G_UMULO ? *I32 : *I64;
+ const rcc::LowLevelType Type = Generic == rcc::GenericOpcode::G_UMULO ? *I32 : *I64;
auto Function =
createRegisterOnlyFunction(Context, *Target, Generic, {Type, *I1}, {Type, Type});
Context.expect(Function != nullptr, "overflow fixture must be complete");
@@ -851,10 +849,10 @@ void testAtomicCompareExchangeLegalization(TestContext &Context) {
if (!Target || !Function)
return;
auto Block = (*Function)->createBasicBlock();
- auto I1 = rcc::LLT::makeAnyScalar(1);
- auto I8 = rcc::LLT::makeAnyScalar(8);
- auto I64 = rcc::LLT::makeAnyScalar(64);
- auto Pointer = rcc::LLT::makePointer(0, 64);
+ auto I1 = rcc::LowLevelType::makeCategoryNeutralScalar(1);
+ auto I8 = rcc::LowLevelType::makeCategoryNeutralScalar(8);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
auto Size = rcc::MemorySize::fixed(1);
auto Align = rcc::Alignment::create(1);
if (!Block || !(*Function)->appendBlock(**Block) || !I1 || !I8 || !I64 || !Pointer || !Size ||
@@ -1003,8 +1001,8 @@ void testConstantExtensionPreservesLiveSource(TestContext &Context) {
auto Target = rcc::riscv::createTargetDescription();
auto Function = rcc::MachineFunction::create("riscv_live_constant_extension",
rcc::MachineFunctionStableID::fromValue(1300));
- auto I32 = rcc::LLT::makeAnyScalar(32);
- auto I64 = rcc::LLT::makeAnyScalar(64);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Target || !Function || !I32 || !I64)
return;
auto Block = (*Function)->createBasicBlock();
@@ -1048,8 +1046,8 @@ void testConstantExtensionPreservesLiveSource(TestContext &Context) {
void testIntegerCompareReusesConstantExtension(TestContext &Context) {
auto Target = rcc::riscv::createTargetDescription();
- auto I32 = rcc::LLT::makeAnyScalar(32);
- auto I64 = rcc::LLT::makeAnyScalar(64);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Target || !I32 || !I64)
return;
auto Function =
@@ -1109,9 +1107,9 @@ void testNarrowAnyExtBinaryArtifacts(TestContext &Context) {
auto Target = rcc::riscv::createTargetDescription();
auto Function = rcc::MachineFunction::create("riscv_narrow_binary_artifacts",
rcc::MachineFunctionStableID::fromValue(1301));
- auto I1 = rcc::LLT::makeAnyScalar(1);
- auto I32 = rcc::LLT::makeAnyScalar(32);
- auto I64 = rcc::LLT::makeAnyScalar(64);
+ auto I1 = rcc::LowLevelType::makeCategoryNeutralScalar(1);
+ auto I32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Target || !Function || !I1 || !I32 || !I64)
return;
auto Block = (*Function)->createBasicBlock();
@@ -1240,8 +1238,8 @@ void testAtomicSelection(TestContext &Context) {
auto Target = rcc::riscv::createTargetDescription();
if (!Target)
return;
- auto I64 = rcc::LLT::makeInteger(64);
- auto Pointer = rcc::LLT::makePointer(0, 64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
auto Size = rcc::MemorySize::fixed(8);
auto Align = rcc::Alignment::create(8);
if (!I64 || !Pointer || !Size || !Align)
@@ -1397,8 +1395,8 @@ void testUnsupportedTypes(TestContext &Context) {
(*GISel.Selector).canSelect(*WideInteger.Instruction, *WideInteger.Function, *Target);
Context.expect(!Selection && Selection.error().code() == rcc::ErrorCode::Unsupported,
"i128 arithmetic must produce an Unsupported diagnostic");
- Context.expect(!Selection && Selection.error().message().find("i128") != std::string::npos,
- "unsupported type diagnostics must name the rejected LLT");
+ Context.expect(!Selection && Selection.error().message().find("s128") != std::string::npos,
+ "unsupported type diagnostics must name the rejected LowLevelType");
}
auto Function = rcc::MachineFunction::create("unsupported_type",
rcc::MachineFunctionStableID::fromValue(100));
@@ -1407,7 +1405,7 @@ void testUnsupportedTypes(TestContext &Context) {
auto Block = (*Function)->createBasicBlock();
if (!Block || !(*Function)->appendBlock(**Block))
return;
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!F64)
return;
auto Result = (*Function)->registerInfo().createVirtualRegister(*F64);
@@ -1447,7 +1445,7 @@ void testVACopyLegalization(TestContext &Context) {
if (!Function)
return;
auto Block = (*Function)->createBasicBlock();
- auto Pointer = rcc::LLT::makePointer(0, 64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
if (!Block || !Pointer || !(*Function)->appendBlock(**Block))
return;
auto Destination = (*Function)->registerInfo().createVirtualRegister(*Pointer);
@@ -1522,8 +1520,8 @@ void testVAArgLegalization(TestContext &Context) {
if (!Function)
return;
auto Block = (*Function)->createBasicBlock();
- auto Pointer = rcc::LLT::makePointer(0, 64);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Block || !Pointer || !I64 || !(*Function)->appendBlock(**Block))
return;
auto Destination = (*Function)->registerInfo().createVirtualRegister(*I64);
@@ -1611,8 +1609,8 @@ void testFrameIndexLegalization(TestContext &Context) {
if (!Function)
return;
auto Block = (*Function)->createBasicBlock();
- auto Pointer = rcc::LLT::makePointer(0, 64);
- auto OtherAddressSpace = rcc::LLT::makePointer(1, 64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
+ auto OtherAddressSpace = rcc::LowLevelType::makePointer(1, 64);
rcc::StackObjectDesc StackSlot;
StackSlot.Size = 8;
StackSlot.Align = *rcc::Alignment::create(8);
@@ -1653,9 +1651,9 @@ void testPointerArithmeticLegalization(TestContext &Context) {
Context.expect(Target.has_value(), "RV64GC target must be available for pointer legalization");
if (!Target)
return;
- auto Pointer = rcc::LLT::makePointer(0, 64);
- auto S64 = rcc::LLT::makeAnyScalar(64);
- auto S32 = rcc::LLT::makeAnyScalar(32);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
+ auto S64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto S32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
if (!Pointer || !S64 || !S32)
return;
auto Legal = createRegisterOnlyFunction(Context, *Target, rcc::GenericOpcode::G_PTR_ADD,
@@ -1686,8 +1684,8 @@ void testMemoryOffsetSelection(TestContext &Context) {
auto Block = (*Function)->createBasicBlock();
if (!Block || !(*Function)->appendBlock(**Block))
return;
- auto I64 = rcc::LLT::makeInteger(64);
- auto Pointer = rcc::LLT::makePointer(0, 64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto Pointer = rcc::LowLevelType::makePointer(0, 64);
if (!I64 || !Pointer)
return;
auto Result = (*Function)->registerInfo().createVirtualRegister(*I64);
diff --git a/backend/unittests/Target/RISCVLateCodeGenTest.cpp b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
index 89da994..0deebc6 100644
--- a/backend/unittests/Target/RISCVLateCodeGenTest.cpp
+++ b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
@@ -727,7 +727,7 @@ void testRISCVMemoryFoldingBoundary(TestContext &Context, const rcc::TargetDescr
if (!Function)
return;
rcc::MachineBasicBlock *Block = appendBlock(Context, *Function);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
auto Align = rcc::Alignment::create(8);
if (Block == nullptr || !I64 || !Align)
return;
@@ -995,8 +995,8 @@ void testPseudoPreparation(TestContext &Context, const rcc::TargetDescription &T
if (!Function)
return;
rcc::MachineBasicBlock *Block = appendBlock(Context, *Function);
- auto I64 = rcc::LLT::makeInteger(64);
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (Block == nullptr || !I64 || !F64)
return;
auto Source = Function->registerInfo().createVirtualRegister(*I64);
diff --git a/backend/unittests/Target/RISCVRegisterAllocationTest.cpp b/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
index 6daf58a..29bc756 100644
--- a/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
+++ b/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
@@ -84,7 +84,8 @@ struct FunctionFixture final {
return FunctionFixture{std::move(*Function), *Block};
}
-[[nodiscard]] rcc::Expected<rcc::Register> createVReg(rcc::MachineFunction &Function, rcc::LLT Type,
+[[nodiscard]] rcc::Expected<rcc::Register> createVReg(rcc::MachineFunction &Function,
+ rcc::LowLevelType Type,
rcc::riscv::RegisterBank Bank,
rcc::riscv::RegisterClass Class) {
auto Reg = Function.registerInfo().createVirtualRegister(Type);
@@ -304,7 +305,7 @@ void testTargetHooks(TestContext &Context, const rcc::TargetDescription &Target)
void testRematerialization(TestContext &Context, const rcc::TargetDescription &Target) {
auto Fixture = createFunction("riscv-rematerialization", 2);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Fixture || !I64)
return;
auto Original = createVReg(*Fixture->Function, *I64, rcc::riscv::RegisterBank::GPR,
@@ -335,7 +336,7 @@ void testRematerialization(TestContext &Context, const rcc::TargetDescription &T
[[nodiscard]] rcc::Expected<FunctionFixture>
createSimpleAllocationFunction(const rcc::TargetDescription &Target, std::uint64_t ID) {
auto Fixture = createFunction("riscv-ra-" + std::to_string(ID), ID);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Fixture)
return std::unexpected(Fixture.error());
if (!I64)
@@ -448,7 +449,7 @@ void testFunctionReservedRegisters(TestContext &Context, const rcc::TargetDescri
[[nodiscard]] rcc::Expected<FunctionFixture>
createPressureFunction(const rcc::TargetDescription &Target, std::uint64_t ID) {
auto Fixture = createFunction("riscv-pressure-" + std::to_string(ID), ID);
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
if (!Fixture)
return std::unexpected(Fixture.error());
if (!I64)
diff --git a/backend/unittests/Target/RISCVSSAExitTest.cpp b/backend/unittests/Target/RISCVSSAExitTest.cpp
index 54a5911..1912666 100644
--- a/backend/unittests/Target/RISCVSSAExitTest.cpp
+++ b/backend/unittests/Target/RISCVSSAExitTest.cpp
@@ -54,7 +54,8 @@ private:
return rcc::RegisterClassID::fromValue(static_cast<std::uint32_t>(Class));
}
-[[nodiscard]] rcc::Expected<rcc::Register> createVReg(rcc::MachineFunction &Function, rcc::LLT Type,
+[[nodiscard]] rcc::Expected<rcc::Register> createVReg(rcc::MachineFunction &Function,
+ rcc::LowLevelType Type,
rcc::riscv::RegisterBank Bank,
rcc::riscv::RegisterClass Class) {
auto Reg = Function.registerInfo().createVirtualRegister(Type);
@@ -219,9 +220,9 @@ void testBehaviorAndCopyLegality(TestContext &Context, const rcc::TargetDescript
Context.expect(Rewritten && *Rewritten && blockOperand(*Jump, 1)->Block == *Third,
"RV64GC branch target rewriting must update direct JAL operands");
- auto I64 = rcc::LLT::makeInteger(64);
- auto F64 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEEDouble);
- auto F32 = rcc::LLT::makeFloat(rcc::FloatSemantics::IEEESingle);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
+ auto F32 = rcc::LowLevelType::makeCategoryNeutralScalar(32);
if (!I64 || !F64 || !F32)
return;
auto GPR =
@@ -318,7 +319,7 @@ void testRV64GCCriticalEdge(TestContext &Context, const rcc::TargetDescription &
auto Merge = appendBlock(**Function);
if (!From || !Side || !Other || !Merge)
return;
- auto I64 = rcc::LLT::makeInteger(64);
+ auto I64 = rcc::LowLevelType::makeCategoryNeutralScalar(64);
auto X0 = rcc::riscv::physicalRegister(rcc::riscv::PhysicalRegisterID::X0);
if (!I64 || !X0)
return;