From 59f948dbb4fcbbb2456db92a55d307cdfbfd8307 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 12 Aug 2026 03:22:55 +0800 Subject: [MIR] Remove alternate layout and float APIs --- backend/include/rcc/CodeGen/LowLevelType.h | 1 - backend/include/rcc/MIR/LLVMConstantSyntax.h | 1 - backend/include/rcc/MIR/MIParser.h | 1 - backend/include/rcc/MIR/MIRDocument.h | 2 - backend/lib/CodeGen/LowLevelType.cpp | 1 - backend/lib/MIR/LLVMConstantSyntax.cpp | 49 ++++++-------------- backend/lib/MIR/MIParser.cpp | 18 +++----- backend/lib/MIR/MIPrinter.cpp | 1 - backend/lib/MIR/MIRDataParser.cpp | 1 - backend/lib/MIR/MIRDocumentParser.cpp | 14 ++---- backend/lib/MIR/MIRDocumentPrinter.cpp | 9 ++-- backend/lib/MIR/MIRFunctionParser.cpp | 8 ++-- backend/lib/Tooling/ArtifactStore.cpp | 2 - backend/lib/Tooling/BackendDriver.cpp | 1 - backend/lib/Tooling/MIRFuzzer.cpp | 1 - backend/lib/Tooling/PipelineDriver.cpp | 1 - .../tools/AssemblyEmitter/AssemblyEmitterMain.cpp | 1 - backend/unittests/CodeGen/CoreTypesTest.cpp | 1 - backend/unittests/MIR/LLVMConstantSyntaxTest.cpp | 38 +++++++--------- backend/unittests/MIR/MIParserTest.cpp | 12 +++-- backend/unittests/MIR/MIRDocumentTest.cpp | 52 +++++++++++++++++----- backend/unittests/Tooling/PipelineDriverTest.cpp | 1 - 22 files changed, 94 insertions(+), 122 deletions(-) (limited to 'backend') diff --git a/backend/include/rcc/CodeGen/LowLevelType.h b/backend/include/rcc/CodeGen/LowLevelType.h index 1ff9ab5..116ffd5 100644 --- a/backend/include/rcc/CodeGen/LowLevelType.h +++ b/backend/include/rcc/CodeGen/LowLevelType.h @@ -22,7 +22,6 @@ enum class FloatSemantics : std::uint8_t { IEEEDouble, IEEEQuad, PPCDoubleDouble, - PPCDoubleDoubleLegacy, Float8E5M2, Float8E5M2FNUZ, Float8E4M3, diff --git a/backend/include/rcc/MIR/LLVMConstantSyntax.h b/backend/include/rcc/MIR/LLVMConstantSyntax.h index 9d7a7d4..a47da54 100644 --- a/backend/include/rcc/MIR/LLVMConstantSyntax.h +++ b/backend/include/rcc/MIR/LLVMConstantSyntax.h @@ -21,7 +21,6 @@ struct LLVMNamedTypeDefinition final { }; struct LLVMConstantSyntaxOptions final { - std::uint32_t DefaultPointerSizeInBits = 0; std::string_view DataLayout; std::span NamedTypes; std::size_t MaximumDepth = 1024; diff --git a/backend/include/rcc/MIR/MIParser.h b/backend/include/rcc/MIR/MIParser.h index 16af534..b660f47 100644 --- a/backend/include/rcc/MIR/MIParser.h +++ b/backend/include/rcc/MIR/MIParser.h @@ -68,7 +68,6 @@ struct MIParserContext final { std::function HasIRBlock; std::function(std::string_view)> InternSyncScope; std::function(std::uint32_t)> PointerSizeInBits; - std::uint32_t DefaultPointerSizeInBits = 0; }; struct MIParserOptions final { diff --git a/backend/include/rcc/MIR/MIRDocument.h b/backend/include/rcc/MIR/MIRDocument.h index 7980ca1..6041657 100644 --- a/backend/include/rcc/MIR/MIRDocument.h +++ b/backend/include/rcc/MIR/MIRDocument.h @@ -78,7 +78,6 @@ struct MIRDocumentParserOptions final { yaml::ParseOptions YAML; MIParserOptions MachineInstructions; std::string DataLayout; - std::uint32_t DefaultPointerSizeInBits = 0; bool VerifyMachineFunctions = true; }; @@ -130,7 +129,6 @@ struct MIRDocumentPrinterOptions final { MIPrintMode Mode = MIPrintMode::Complete; bool EmitEmbeddedIR = true; std::string DataLayout; - std::uint32_t DefaultPointerSizeInBits = 0; }; [[nodiscard]] Expected printMIRDocument(const MIRDocument &Document, diff --git a/backend/lib/CodeGen/LowLevelType.cpp b/backend/lib/CodeGen/LowLevelType.cpp index a276e02..b124765 100644 --- a/backend/lib/CodeGen/LowLevelType.cpp +++ b/backend/lib/CodeGen/LowLevelType.cpp @@ -21,7 +21,6 @@ constexpr std::array FloatSemanticsTable{ FloatSemanticsInfo{64, "IEEE double", "f64"}, FloatSemanticsInfo{128, "IEEE quad", "f128"}, FloatSemanticsInfo{128, "PPC double-double", "ppcf128"}, - FloatSemanticsInfo{128, "legacy PPC double-double", "ppcf128-legacy"}, FloatSemanticsInfo{8, "float8 E5M2", "f8e5m2"}, FloatSemanticsInfo{8, "float8 E5M2 FNUZ", "f8e5m2fnuz"}, FloatSemanticsInfo{8, "float8 E4M3", "f8e4m3"}, diff --git a/backend/lib/MIR/LLVMConstantSyntax.cpp b/backend/lib/MIR/LLVMConstantSyntax.cpp index a2025dc..a687f80 100644 --- a/backend/lib/MIR/LLVMConstantSyntax.cpp +++ b/backend/lib/MIR/LLVMConstantSyntax.cpp @@ -307,8 +307,8 @@ private: return (BitWidth % 64U) == 0 || (Words.back() >> (BitWidth % 64U)) == 0; } -[[nodiscard]] bool parseLegacyWideFloatHexWords(std::string_view Digits, - std::vector &Words) { +[[nodiscard]] bool parseWideFloatHexWords(std::string_view Digits, + std::vector &Words) { if (Digits.empty() || Digits.size() > 32U || !std::ranges::all_of(Digits, isHexDigit)) return false; Words.assign(2, 0); @@ -466,8 +466,7 @@ makeSpecialFloatWords(FloatSemantics Semantics, const SpecialFloatLiteral &Liter setFloatBit(Words, 61); return Words; } - case FloatSemantics::PPCDoubleDouble: - case FloatSemantics::PPCDoubleDoubleLegacy: { + case FloatSemantics::PPCDoubleDouble: { std::vector HighPart(1, 0); makeBinarySpecialFloat(HighPart, 64, 11, Literal); Words[0] = HighPart.front(); @@ -542,9 +541,8 @@ binaryFloatFormat(FloatSemantics Semantics) noexcept { .StorageBitWidth = 80, .HasExplicitIntegerBit = true}; case FloatSemantics::PPCDoubleDouble: - case FloatSemantics::PPCDoubleDoubleLegacy: - // LLVM parses a decimal PPC double-double through its documented legacy - // 106-bit format and then materializes the canonical pair of doubles. + // Decimal PPC double-double literals use 106 bits of precision and are + // materialized as a canonical pair of doubles. return BinaryFloatFormat{.Precision = 106, .MinExponent = -969, .MaxExponent = 1023, @@ -884,8 +882,7 @@ convertRationalToFloatWords(FloatSemantics Semantics, bool Negative, const BigUn auto Rounded = roundBinaryRational(*Format, Numerator, Denominator, BinaryScale); if (!Rounded) return std::unexpected(Rounded.error()); - if (Semantics == FloatSemantics::PPCDoubleDouble || - Semantics == FloatSemantics::PPCDoubleDoubleLegacy) { + if (Semantics == FloatSemantics::PPCDoubleDouble) { return packPPCDoubleDouble(*Rounded, Negative); } if (Format->HasExplicitIntegerBit) @@ -1806,19 +1803,16 @@ Expected ConstantParser::parseFloatingValue(GenericConstant ExpectedPrefix = 'L'; break; case FloatSemantics::PPCDoubleDouble: - case FloatSemantics::PPCDoubleDoubleLegacy: ExpectedPrefix = 'M'; break; default: break; } if (ExpectedPrefix != '\0') { - const bool IsLegacyWideFormat = - EffectiveType.Semantics == FloatSemantics::IEEEQuad || - EffectiveType.Semantics == FloatSemantics::PPCDoubleDouble || - EffectiveType.Semantics == FloatSemantics::PPCDoubleDoubleLegacy; - const bool Parsed = IsLegacyWideFormat ? parseLegacyWideFloatHexWords(Digits, Words) - : parseHexWords(Digits, BitWidth, Words); + const bool HasWideHexWords = EffectiveType.Semantics == FloatSemantics::IEEEQuad || + EffectiveType.Semantics == FloatSemantics::PPCDoubleDouble; + const bool Parsed = HasWideHexWords ? parseWideFloatHexWords(Digits, Words) + : parseHexWords(Digits, BitWidth, Words); if (Prefix != ExpectedPrefix || !Parsed) { return fail( "floating-point hexadecimal prefix does not match its type"); @@ -2378,7 +2372,6 @@ Expected printType(const GenericConstantType &Type) { case FloatSemantics::IEEEQuad: return std::string("fp128"); case FloatSemantics::PPCDoubleDouble: - case FloatSemantics::PPCDoubleDoubleLegacy: return std::string("ppc_fp128"); case FloatSemantics::X87DoubleExtended: return std::string("x86_fp80"); @@ -2481,8 +2474,7 @@ struct PrintedBinaryFloat final { if (!Format) return std::nullopt; - if (Bits.semantics() == FloatSemantics::PPCDoubleDouble || - Bits.semantics() == FloatSemantics::PPCDoubleDoubleLegacy) { + if (Bits.semantics() == FloatSemantics::PPCDoubleDouble) { if (Words.size() != 2 || Words[1] != 0) return std::nullopt; Format = binaryFloatFormat(FloatSemantics::IEEEDouble); @@ -2942,7 +2934,6 @@ private: std::uint64_t StoreSize) const noexcept; bool Explicit = false; - std::uint32_t LegacyPointerSizeInBits = 0; std::vector Alignments; std::vector Pointers; LayoutAlignment Aggregate{1, 8}; @@ -3010,7 +3001,6 @@ void DataLayoutInfo::setPointer(LayoutPointerEntry Entry) { Expected DataLayoutInfo::parse(LLVMConstantSyntaxOptions Options) { DataLayoutInfo Result; - Result.LegacyPointerSizeInBits = Options.DefaultPointerSizeInBits; if (Options.DataLayout.empty()) return Result; if (Options.DataLayout.size() > Options.MaximumTokenLength) { @@ -3322,21 +3312,8 @@ LayoutAlignment DataLayoutInfo::vector(std::uint32_t BitWidth, Expected DataLayoutInfo::pointer(std::uint32_t AddressSpace) const { if (!Explicit) { - if (LegacyPointerSizeInBits == 0) { - return makeUnexpected(ErrorCode::InvalidArgument, - "pointer size is required to lay out pointer constants"); - } - const std::uint64_t Bytes = (static_cast(LegacyPointerSizeInBits) + 7U) / 8U; - return LayoutPointerEntry{ - .AddressSpace = AddressSpace, - .SizeInBits = LegacyPointerSizeInBits, - .IndexSizeInBits = LegacyPointerSizeInBits, - .Alignment = natural(Bytes), - .HasExternalState = false, - .HasUnstableRepresentation = false, - .NullIsAllOnes = false, - .AddressSpaceName = {}, - }; + return makeUnexpected(ErrorCode::InvalidArgument, + "pointer size is required to lay out pointer constants"); } auto Entry = std::ranges::find_if(Pointers, [AddressSpace](const LayoutPointerEntry &Candidate) { return Candidate.AddressSpace == AddressSpace; diff --git a/backend/lib/MIR/MIParser.cpp b/backend/lib/MIR/MIParser.cpp index f634119..3748187 100644 --- a/backend/lib/MIR/MIParser.cpp +++ b/backend/lib/MIR/MIParser.cpp @@ -621,16 +621,12 @@ bool MIParser::Impl::parseScalarLowLevelType(const MIToken &TypeToken, LLT &Resu Created = LLT::makeFloat(FloatSemantics::BFloat); break; case ScalarKind::Pointer: - if (Context.PointerSizeInBits) { - auto PointerSize = Context.PointerSizeInBits(static_cast(Value)); - if (!PointerSize) - return importError(TypeToken, PointerSize.error()); - Created = LLT::makePointer(Value, *PointerSize); - break; - } - if (Context.DefaultPointerSizeInBits == 0) + if (!Context.PointerSizeInBits) return fail(TypeToken, "pointer low-level type requires an explicit pointer size"); - Created = LLT::makePointer(Value, Context.DefaultPointerSizeInBits); + if (auto PointerSize = Context.PointerSizeInBits(static_cast(Value))) + Created = LLT::makePointer(Value, *PointerSize); + else + return importError(TypeToken, PointerSize.error()); break; } if (!Created) @@ -1722,9 +1718,7 @@ bool MIParser::Impl::parseMemoryBase(MemoryBase &Result, std::int64_t &Offset) { advance(); break; case MITokenKind::QuotedIRValue: { - LLVMConstantSyntaxOptions ConstantOptions; - ConstantOptions.DefaultPointerSizeInBits = Context.DefaultPointerSizeInBits; - auto Constant = parseLLVMConstant(BaseToken.stringValue(), ConstantOptions); + auto Constant = parseLLVMConstant(BaseToken.stringValue()); if (!Constant) return importError(BaseToken, Constant.error()); auto Base = MemoryBase::irConstant(std::move(*Constant)); diff --git a/backend/lib/MIR/MIPrinter.cpp b/backend/lib/MIR/MIPrinter.cpp index 25a7a0c..6f88414 100644 --- a/backend/lib/MIR/MIPrinter.cpp +++ b/backend/lib/MIR/MIPrinter.cpp @@ -211,7 +211,6 @@ namespace { case FloatSemantics::IEEEQuad: return "f128"; case FloatSemantics::PPCDoubleDouble: - case FloatSemantics::PPCDoubleDoubleLegacy: case FloatSemantics::Float8E5M2: case FloatSemantics::Float8E5M2FNUZ: case FloatSemantics::Float8E4M3: diff --git a/backend/lib/MIR/MIRDataParser.cpp b/backend/lib/MIR/MIRDataParser.cpp index 7e04ace..2ac1f2d 100644 --- a/backend/lib/MIR/MIRDataParser.cpp +++ b/backend/lib/MIR/MIRDataParser.cpp @@ -129,7 +129,6 @@ bool MIRDocumentParser::parseConstants(const yaml::Node &Root, MachineFunction & if (scalar(*ValueNode, ValueText, "LLVM constant")) return true; const LLVMConstantSyntaxOptions ConstantOptions{ - .DefaultPointerSizeInBits = Context.DefaultPointerSizeInBits, .DataLayout = DataLayout, .NamedTypes = NamedTypes, }; diff --git a/backend/lib/MIR/MIRDocumentParser.cpp b/backend/lib/MIR/MIRDocumentParser.cpp index 9c4728a..08627d5 100644 --- a/backend/lib/MIR/MIRDocumentParser.cpp +++ b/backend/lib/MIR/MIRDocumentParser.cpp @@ -72,18 +72,19 @@ const yaml::Node *MIRDocumentParser::mappingValue(const yaml::Node &Mapping, } std::string_view MIRDocumentParser::effectiveDataLayout() const noexcept { + if (!Options.DataLayout.empty()) + return Options.DataLayout; if (ActiveDocument != nullptr) { if (const EmbeddedIRReferenceIndex *Embedded = ActiveDocument->embeddedIR()) { if (const auto DataLayout = Embedded->dataLayout()) return *DataLayout; } } - return Options.DataLayout; + return {}; } LLVMConstantSyntaxOptions MIRDocumentParser::pointerLayoutOptions() const noexcept { return { - .DefaultPointerSizeInBits = Options.DefaultPointerSizeInBits, .DataLayout = effectiveDataLayout(), .NamedTypes = {}, }; @@ -243,14 +244,6 @@ MIRDocumentParseResult MIRDocumentParser::run() { FirstFunction = FirstContent + 1; } - if (const EmbeddedIRReferenceIndex *Embedded = Staging.embeddedIR()) { - if (const auto DataLayout = Embedded->dataLayout(); - DataLayout && !Options.DataLayout.empty() && *DataLayout != Options.DataLayout) { - static_cast(fail(Stream->documents()[FirstContent].Range, - "explicit DataLayout does not match embedded LLVM IR data layout")); - return std::move(Result); - } - } if (!effectiveDataLayout().empty()) { auto PointerSize = llvmPointerSizeInBits(0, pointerLayoutOptions()); if (!PointerSize) { @@ -374,7 +367,6 @@ bool MIRDocumentParser::parseFunction(const yaml::Node &Root, MIRDocument &Docum .HasFakeUses = std::nullopt, }; MIParserContext Context; - Context.DefaultPointerSizeInBits = Options.DefaultPointerSizeInBits; if (IRFunction != nullptr) { Context.HasIRBlock = [IRFunction](std::string_view BlockName) { return IRFunction->block(BlockName) != nullptr; diff --git a/backend/lib/MIR/MIRDocumentPrinter.cpp b/backend/lib/MIR/MIRDocumentPrinter.cpp index 5cc0173..06998bb 100644 --- a/backend/lib/MIR/MIRDocumentPrinter.cpp +++ b/backend/lib/MIR/MIRDocumentPrinter.cpp @@ -387,9 +387,6 @@ MIRDocumentPrinter::verifyOmittedEmbeddedIRLayout(const MachineFunction &Functio const EmbeddedIRReferenceIndex *Embedded = Document.embeddedIR(); if (Embedded == nullptr) return {}; - const auto EmbeddedDataLayout = Embedded->dataLayout(); - if (!EmbeddedDataLayout) - return {}; bool HasLayoutDependentContent = false; for (const VirtualRegisterInfo &RegisterInfo : Function.registerInfo().virtualRegisters()) { @@ -412,14 +409,14 @@ MIRDocumentPrinter::verifyOmittedEmbeddedIRLayout(const MachineFunction &Functio if (!HasLayoutDependentContent) return {}; - if (Options.DataLayout != *EmbeddedDataLayout) { + if (Options.DataLayout.empty()) { return makeUnexpected( ErrorCode::InvalidArgument, - "omitting embedded LLVM IR requires printer DataLayout to exactly match its data layout"); + "omitting embedded LLVM IR with layout-dependent MIR requires an explicit printer " + "DataLayout"); } const LLVMConstantSyntaxOptions LayoutOptions{ - .DefaultPointerSizeInBits = Options.DefaultPointerSizeInBits, .DataLayout = Options.DataLayout, .NamedTypes = {}, }; diff --git a/backend/lib/MIR/MIRFunctionParser.cpp b/backend/lib/MIR/MIRFunctionParser.cpp index 7e8821b..8cf3abb 100644 --- a/backend/lib/MIR/MIRFunctionParser.cpp +++ b/backend/lib/MIR/MIRFunctionParser.cpp @@ -411,12 +411,12 @@ TextRange MIRDocumentParser::scalarDiagnosticRange(const yaml::Node &Scalar, if (!FoundContent) return Scalar.range(); - const TextPosition Fallback = Scalar.range().Begin; + const TextPosition DefaultPosition = Scalar.range().Begin; const auto MapPosition = [this, FirstBodyLine, LastBodyLine, Indent, - Fallback](TextPosition Position) { + DefaultPosition](TextPosition Position) { const std::size_t SourceLine = FirstBodyLine + Position.Line - 1U; if (Position.Line == 0 || SourceLine > LastBodyLine || SourceLine > Result.Source.lineCount()) { - return Fallback; + return DefaultPosition; } const std::string_view SourceLineText = Result.Source.line(SourceLine); const std::size_t BodyColumn = Position.Column == 0 ? 0 : Position.Column - 1U; @@ -440,8 +440,6 @@ bool MIRDocumentParser::parseBody(const yaml::Node &Root, MachineFunction &Funct BodyRange = Body->range(); } - if (Options.DefaultPointerSizeInBits != 0) - Context.DefaultPointerSizeInBits = Options.DefaultPointerSizeInBits; if (!effectiveDataLayout().empty()) { const LLVMConstantSyntaxOptions PointerOptions = pointerLayoutOptions(); Context.PointerSizeInBits = [PointerOptions](std::uint32_t AddressSpace) { diff --git a/backend/lib/Tooling/ArtifactStore.cpp b/backend/lib/Tooling/ArtifactStore.cpp index 76fc0df..db330b1 100644 --- a/backend/lib/Tooling/ArtifactStore.cpp +++ b/backend/lib/Tooling/ArtifactStore.cpp @@ -264,7 +264,6 @@ Expected parseAndCanonicalizeMIR(std::string SourceName, std::stri } mir::MIRDocumentParserOptions ParseOptions; ParseOptions.DataLayout = Invocation.DataLayout; - ParseOptions.DefaultPointerSizeInBits = 64; ParseOptions.VerifyMachineFunctions = true; mir::MIRDocumentParseResult Parsed = mir::parseMIRDocument(Target, std::move(SourceName), std::move(SourceText), ParseOptions); @@ -279,7 +278,6 @@ Expected parseAndCanonicalizeMIR(std::string SourceName, std::stri PrintOptions.Mode = mir::MIPrintMode::Complete; PrintOptions.EmitEmbeddedIR = true; PrintOptions.DataLayout = Invocation.DataLayout; - PrintOptions.DefaultPointerSizeInBits = 64; auto Printed = mir::printMIRDocument(*Parsed.document(), Target, std::move(PrintOptions)); if (!Printed) return std::unexpected(Printed.error()); diff --git a/backend/lib/Tooling/BackendDriver.cpp b/backend/lib/Tooling/BackendDriver.cpp index 85a2cf9..2a2a500 100644 --- a/backend/lib/Tooling/BackendDriver.cpp +++ b/backend/lib/Tooling/BackendDriver.cpp @@ -54,7 +54,6 @@ namespace { Options.Mode = mir::MIPrintMode::Complete; Options.EmitEmbeddedIR = true; Options.DataLayout = Invocation.DataLayout; - Options.DefaultPointerSizeInBits = 64; auto Printed = mir::printMIRDocument(Document, Target, std::move(Options)); if (!Printed) return std::unexpected(Printed.error()); diff --git a/backend/lib/Tooling/MIRFuzzer.cpp b/backend/lib/Tooling/MIRFuzzer.cpp index e8a1a7a..ed5b2fa 100644 --- a/backend/lib/Tooling/MIRFuzzer.cpp +++ b/backend/lib/Tooling/MIRFuzzer.cpp @@ -215,7 +215,6 @@ private: PrintOptions.Mode = mir::MIPrintMode::Complete; PrintOptions.EmitEmbeddedIR = true; PrintOptions.DataLayout = Invocation.DataLayout; - PrintOptions.DefaultPointerSizeInBits = 64; auto Printed = mir::printMIRDocument(Parsed->Document, Target, std::move(PrintOptions)); if (!Printed) return std::unexpected(Printed.error()); diff --git a/backend/lib/Tooling/PipelineDriver.cpp b/backend/lib/Tooling/PipelineDriver.cpp index b7844cd..4dab499 100644 --- a/backend/lib/Tooling/PipelineDriver.cpp +++ b/backend/lib/Tooling/PipelineDriver.cpp @@ -153,7 +153,6 @@ captureSnapshot(FunctionRunResult &Result, const mir::MIRDocument &Document, PrintOptions.Mode = mir::MIPrintMode::Complete; PrintOptions.EmitEmbeddedIR = true; PrintOptions.DataLayout = Invocation.DataLayout; - PrintOptions.DefaultPointerSizeInBits = 64; auto Printed = mir::printMIRDocument(Document, Target, std::move(PrintOptions)); if (!Printed) return std::unexpected(Printed.error()); diff --git a/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp b/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp index 30193cd..21567b3 100644 --- a/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp +++ b/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp @@ -127,7 +127,6 @@ int main(int ArgumentCount, char *Arguments[]) { } rcc::mir::MIRDocumentParserOptions Options; Options.DataLayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"; - Options.DefaultPointerSizeInBits = 64; auto Parsed = rcc::mir::parseMIRDocument(*Target, Command.InputPath, std::move(SourceText), Options); if (!Parsed.succeeded()) { diff --git a/backend/unittests/CodeGen/CoreTypesTest.cpp b/backend/unittests/CodeGen/CoreTypesTest.cpp index c2a7b45..b19d6b4 100644 --- a/backend/unittests/CodeGen/CoreTypesTest.cpp +++ b/backend/unittests/CodeGen/CoreTypesTest.cpp @@ -63,7 +63,6 @@ void testLowLevelTypes(TestContext &Context) { std::pair{rcc::FloatSemantics::IEEEDouble, std::uint32_t{64}}, std::pair{rcc::FloatSemantics::IEEEQuad, std::uint32_t{128}}, std::pair{rcc::FloatSemantics::PPCDoubleDouble, std::uint32_t{128}}, - std::pair{rcc::FloatSemantics::PPCDoubleDoubleLegacy, std::uint32_t{128}}, std::pair{rcc::FloatSemantics::Float8E5M2, std::uint32_t{8}}, std::pair{rcc::FloatSemantics::Float8E5M2FNUZ, std::uint32_t{8}}, std::pair{rcc::FloatSemantics::Float8E4M3, std::uint32_t{8}}, diff --git a/backend/unittests/MIR/LLVMConstantSyntaxTest.cpp b/backend/unittests/MIR/LLVMConstantSyntaxTest.cpp index 96346a0..c10fc68 100644 --- a/backend/unittests/MIR/LLVMConstantSyntaxTest.cpp +++ b/backend/unittests/MIR/LLVMConstantSyntaxTest.cpp @@ -31,8 +31,7 @@ private: }; constexpr rcc::mir::LLVMConstantSyntaxOptions Options{ - .DefaultPointerSizeInBits = 64, - .DataLayout = {}, + .DataLayout = "e-p:64:64", .NamedTypes = {}, }; @@ -44,6 +43,14 @@ void expectRoundTrip(TestContext &Context, std::string_view Text, std::uint64_t return; } auto Size = rcc::mir::llvmConstantStorageSize(Parsed->Type, Options); + if (!Size || *Size != ExpectedSize) { + std::cerr << Text << ": expected storage size " << ExpectedSize << ", got "; + if (Size) + std::cerr << *Size; + else + std::cerr << Size.error().message(); + std::cerr << '\n'; + } Context.expect(Size.has_value() && *Size == ExpectedSize, "LLVM constant storage size must match its structured type"); auto Printed = rcc::mir::printLLVMConstant(*Parsed); @@ -92,12 +99,12 @@ void expectLayoutRoundTrip(TestContext &Context, std::string_view Text, void testScalarConstants(TestContext &Context) { expectRoundTrip(Context, "i1 true", 1); - expectRoundTrip(Context, "i65 -1", 9); + expectRoundTrip(Context, "i65 -1", 12); expectRoundTrip(Context, "half 0xH3C00", 2); expectRoundTrip(Context, "bfloat 0xR3F80", 2); expectRoundTrip(Context, "float 1.250000e+00", 4); expectRoundTrip(Context, "double 0x3FF0000000000000", 8); - expectRoundTrip(Context, "x86_fp80 f0x4000C000000000000000", 10); + expectRoundTrip(Context, "x86_fp80 f0x4000C000000000000000", 16); expectRoundTrip(Context, "fp128 f0x3FFF0000000000000000000000000000", 16); expectRoundTrip(Context, "ptr null", 8); expectRoundTrip(Context, "i32 undef", 4); @@ -186,7 +193,7 @@ void testExplicitHexIntegerConstants(TestContext &Context) { expectIntegerWords(Context, "i16 s0xFF", SignedFF); expectIntegerWords(Context, "i8 s0x1FF", SignedFF8); - expectRoundTrip(Context, "i65 s0x01", 9); + expectRoundTrip(Context, "i65 s0x01", 12); Context.expect(!rcc::mir::parseLLVMConstant("i32 u0x", Options) && !rcc::mir::parseLLVMConstant("i32 u0X1", Options), "explicit LLVM hexadecimal integers must use the fixed spelling"); @@ -363,7 +370,6 @@ void testDataLayoutAndNamedTypes(TestContext &Context) { .Name = "loop", .Definition = "{ %loop }", .NumericName = false}, }; static constexpr rcc::mir::LLVMConstantSyntaxOptions LayoutOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:64:64-p1:32:16:64-i64:64:128-i128:128-v96:128:256-a:0:64", .NamedTypes = Definitions, }; @@ -385,7 +391,6 @@ void testDataLayoutAndNamedTypes(TestContext &Context) { void testAddressSpacePointerWidths(TestContext &Context) { constexpr rcc::mir::LLVMConstantSyntaxOptions HeterogeneousLayoutOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:64:64-p1:32:16:64", .NamedTypes = {}, }; @@ -395,39 +400,29 @@ void testAddressSpacePointerWidths(TestContext &Context) { AddressSpaceOnePointer.has_value() && *AddressSpaceOnePointer == 32, "LLVM data layout must provide pointer width by address space"); - constexpr rcc::mir::LLVMConstantSyntaxOptions LegacyOptions{ - .DefaultPointerSizeInBits = 64, - .DataLayout = {}, - .NamedTypes = {}, - }; - auto LegacyPointer = rcc::mir::llvmPointerSizeInBits(7, LegacyOptions); - Context.expect(LegacyPointer.has_value() && *LegacyPointer == 64, - "legacy pointer-width fallback must apply without an explicit data layout"); + auto MissingPointer = rcc::mir::llvmPointerSizeInBits(7); + Context.expect(!MissingPointer, + "pointer width lookup must reject a missing explicit data layout"); } void testDataLayoutBoundaryRules(TestContext &Context) { static constexpr rcc::mir::LLVMConstantSyntaxOptions IntegerAlignmentOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:64:64-i24:128:128", .NamedTypes = {}, }; static constexpr rcc::mir::LLVMConstantSyntaxOptions HistoricalAggregateOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:64:64-a0:64:128", .NamedTypes = {}, }; static constexpr rcc::mir::LLVMConstantSyntaxOptions ZeroAggregateOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:64:64-a:0:64", .NamedTypes = {}, }; static constexpr rcc::mir::LLVMConstantSyntaxOptions NonBytePointerOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:33:8:8:32", .NamedTypes = {}, }; static constexpr rcc::mir::LLVMConstantSyntaxOptions PointerFlagsOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-pue1(storage):33:8:8:32-po2(allones):64:64", .NamedTypes = {}, }; @@ -440,7 +435,6 @@ void testDataLayoutBoundaryRules(TestContext &Context) { expectLayoutRoundTrip(Context, "ptr addrspace(1) null", PointerFlagsOptions, 5, 1); static constexpr rcc::mir::LLVMConstantSyntaxOptions InvalidIndexSizeOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-p:33:8:8:34", .NamedTypes = {}, }; @@ -450,7 +444,6 @@ void testDataLayoutBoundaryRules(TestContext &Context) { "LLVM pointer index size larger than its representation must be rejected"); static constexpr rcc::mir::LLVMConstantSyntaxOptions NonLayoutOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = "e-m:e-n8:16:32-S128-Fi64-P1-G2-A3-ni:1:2-ve-s-p:64:64", .NamedTypes = {}, }; @@ -458,7 +451,6 @@ void testDataLayoutBoundaryRules(TestContext &Context) { const auto ExpectInvalidDataLayout = [&Context](std::string_view DataLayout) { const rcc::mir::LLVMConstantSyntaxOptions InvalidOptions{ - .DefaultPointerSizeInBits = 0, .DataLayout = DataLayout, .NamedTypes = {}, }; diff --git a/backend/unittests/MIR/MIParserTest.cpp b/backend/unittests/MIR/MIParserTest.cpp index e57cdfb..815a18e 100644 --- a/backend/unittests/MIR/MIParserTest.cpp +++ b/backend/unittests/MIR/MIParserTest.cpp @@ -221,7 +221,9 @@ bb.1."exit block" (landing-pad, bbsections Cold): rcc::mir::MIParserContext ParserContext; ParserContext.Metadata.push_back( {.TextID = 0, .Reference = rcc::MachineMetadataReference::embeddedIR(0)}); - ParserContext.DefaultPointerSizeInBits = 64; + ParserContext.PointerSizeInBits = [](std::uint32_t) -> rcc::Expected { + return 64; + }; rcc::mir::MIParser Parser(*Function, *Target, "body.mir", Body, ParserContext); const auto Parsed = Parser.parse(); const bool ParseSucceeded = @@ -507,7 +509,9 @@ void testLLVMInlineAsmAndConstantMemorySyntax(TestContext &Context) { %1:gpr64 = TEST_LOAD $g0 :: (load (s64) from unknown-address + 4) )"; rcc::mir::MIParserContext ParserContext; - ParserContext.DefaultPointerSizeInBits = 64; + ParserContext.PointerSizeInBits = [](std::uint32_t) -> rcc::Expected { + return 64; + }; rcc::mir::MIParser Parser(*Function, *Target, "llvm-compatible.mir", Body, ParserContext); auto Parsed = Parser.parse(); Context.expect(Parsed.has_value(), "LLVM inline-asm and constant-pointer MMO syntax must parse"); @@ -553,7 +557,9 @@ void testLLVMCompareExchangeMemorySyntax(TestContext &Context) { %3:_(s8) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s8)) )"; rcc::mir::MIParserContext ParserContext; - ParserContext.DefaultPointerSizeInBits = 64; + ParserContext.PointerSizeInBits = [](std::uint32_t) -> rcc::Expected { + return 64; + }; rcc::mir::MIParser Parser(*Function, *Target, "llvm-cmpxchg.mir", Body, ParserContext); const auto Parsed = Parser.parse(); Context.expect(Parsed.has_value(), "LLVM one-ordering compare-exchange MMO syntax must parse"); diff --git a/backend/unittests/MIR/MIRDocumentTest.cpp b/backend/unittests/MIR/MIRDocumentTest.cpp index c655e64..52e5d65 100644 --- a/backend/unittests/MIR/MIRDocumentTest.cpp +++ b/backend/unittests/MIR/MIRDocumentTest.cpp @@ -489,10 +489,8 @@ void testDocumentTransaction(TestContext &Context) { auto Readable = rcc::mir::printMIRDocument( *Document, *Target, - rcc::mir::MIRDocumentPrinterOptions{.Mode = rcc::mir::MIPrintMode::Readable, - .EmitEmbeddedIR = true, - .DataLayout = {}, - .DefaultPointerSizeInBits = 0}); + rcc::mir::MIRDocumentPrinterOptions{ + .Mode = rcc::mir::MIPrintMode::Readable, .EmitEmbeddedIR = true, .DataLayout = {}}); Context.expect(Readable.has_value(), "readable MIR document printing must succeed"); if (!Readable) return; @@ -504,10 +502,8 @@ void testDocumentTransaction(TestContext &Context) { auto WithoutEmbeddedIR = rcc::mir::printMIRDocument( *Document, *Target, - rcc::mir::MIRDocumentPrinterOptions{.Mode = rcc::mir::MIPrintMode::Complete, - .EmitEmbeddedIR = false, - .DataLayout = {}, - .DefaultPointerSizeInBits = 0}); + rcc::mir::MIRDocumentPrinterOptions{ + .Mode = rcc::mir::MIPrintMode::Complete, .EmitEmbeddedIR = false, .DataLayout = {}}); Context.expect(!WithoutEmbeddedIR && WithoutEmbeddedIR.error().message().find( "requires embedded LLVM IR") != std::string_view::npos, "printer must reject output that omits required embedded LLVM IR"); @@ -574,6 +570,42 @@ void testHeterogeneousPointerLayout(TestContext &Context) { ConstantDescription != nullptr && ConstantDescription->Size == 4, "embedded data layout must determine p1 register and generic-constant widths"); + rcc::mir::MIRDocumentParserOptions OverrideOptions; + OverrideOptions.DataLayout = "e-p:64:64-p1:64:64"; + OverrideOptions.MachineInstructions.VerifyAfterParse = false; + OverrideOptions.VerifyMachineFunctions = false; + auto Overridden = rcc::mir::parseMIRDocument( + *Target, "overridden-layout.mir", std::string(HeterogeneousPointerDocument), OverrideOptions); + const rcc::MachineFunction *OverriddenFunction = + Overridden.succeeded() ? Overridden.document()->unit().function("pointer_layout") : nullptr; + const rcc::MachineConstantPoolEntry *OverriddenConstant = + OverriddenFunction == nullptr + ? nullptr + : OverriddenFunction->constantPool().entry(rcc::ConstantPoolIndex::fromValue(0)); + const rcc::MachineConstantPoolEntryDesc *OverriddenConstantDescription = + OverriddenConstant == nullptr ? nullptr : OverriddenConstant->description(); + const auto OverriddenPointerType = rcc::LLT::makePointer(1, 64); + Context.expect(Overridden.succeeded() && OverriddenFunction != nullptr && + OverriddenPointerType.has_value() && + OverriddenFunction->registerInfo().virtualRegisters().size() == 1 && + OverriddenFunction->registerInfo().virtualRegisters().front().Type == + *OverriddenPointerType && + OverriddenConstantDescription != nullptr && + OverriddenConstantDescription->Size == 8, + "explicit target DataLayout must override embedded LLVM IR layout"); + if (!Overridden.succeeded()) + printDiagnostics(Overridden); + + if (Overridden.succeeded()) { + rcc::mir::MIRDocumentPrinterOptions OverridePrinterOptions; + OverridePrinterOptions.EmitEmbeddedIR = false; + OverridePrinterOptions.DataLayout = OverrideOptions.DataLayout; + auto OverriddenOutput = + rcc::mir::printMIRDocument(*Overridden.document(), *Target, OverridePrinterOptions); + Context.expect(OverriddenOutput.has_value(), + "matching target DataLayout must allow omitting overridden embedded IR"); + } + rcc::mir::MIRDocumentPrinterOptions PrinterOptions; PrinterOptions.EmitEmbeddedIR = false; auto WithoutLayout = rcc::mir::printMIRDocument(*Parsed.document(), *Target, PrinterOptions); @@ -609,8 +641,8 @@ void testHeterogeneousPointerLayout(TestContext &Context) { PrinterOptions.DataLayout = "e-p:64:64-p1:64:64"; auto Mismatched = rcc::mir::printMIRDocument(*Parsed.document(), *Target, PrinterOptions); - Context.expect(!Mismatched && - Mismatched.error().message().find("exactly match") != std::string_view::npos, + Context.expect(!Mismatched && Mismatched.error().message().find( + "pointer virtual-register width") != std::string_view::npos, "mismatched output DataLayout must be rejected when embedded IR is omitted"); } diff --git a/backend/unittests/Tooling/PipelineDriverTest.cpp b/backend/unittests/Tooling/PipelineDriverTest.cpp index 5815712..28df900 100644 --- a/backend/unittests/Tooling/PipelineDriverTest.cpp +++ b/backend/unittests/Tooling/PipelineDriverTest.cpp @@ -26,7 +26,6 @@ printDocument(const rcc::mir::MIRDocument &Document, const rcc::TargetDescriptio Options.Mode = rcc::mir::MIPrintMode::Complete; Options.EmitEmbeddedIR = true; Options.DataLayout = Invocation.DataLayout; - Options.DefaultPointerSizeInBits = 64; return rcc::mir::printMIRDocument(Document, Target, std::move(Options)); } -- cgit v1.2.3