diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2115,6 +2115,12 @@ This specifies pointer types with the specified address spaces as :ref:`Non-Integral Pointer Type ` s. The ``0`` address space cannot be specified as non-integral. +``fe::`` + This specifies the size and alignment of memory required to store floating + point environment. If this specifier is absent or ```` is zero, it is + assumed that the environment size is equal to one stack word, which is + evaluated from the stack alignment. If ```` is omitted, the + alignment is assumed to be the same as natural alignment of the stack. On every specification that takes a ``:``, specifying the ```` alignment is optional. If omitted, the preceding ``:`` diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -123,6 +123,8 @@ unsigned AllocaAddrSpace; MaybeAlign StackNaturalAlign; unsigned ProgramAddrSpace; + unsigned FPEnvironmentSize; + MaybeAlign FPEnvironmentAlign; MaybeAlign FunctionPtrAlign; FunctionPtrAlignType TheFunctionPtrAlignType; @@ -212,6 +214,8 @@ FunctionPtrAlign = DL.FunctionPtrAlign; TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType; ProgramAddrSpace = DL.ProgramAddrSpace; + FPEnvironmentAlign = DL.FPEnvironmentAlign; + FPEnvironmentSize = DL.FPEnvironmentSize; ManglingMode = DL.ManglingMode; LegalIntWidths = DL.LegalIntWidths; Alignments = DL.Alignments; @@ -285,6 +289,9 @@ unsigned getProgramAddressSpace() const { return ProgramAddrSpace; } + unsigned getFPEnvironmentSize() const { return FPEnvironmentSize; } + MaybeAlign getFPEnvironmentAlign() const { return FPEnvironmentAlign; } + bool hasMicrosoftFastStdCallMangling() const { return ManglingMode == MM_WinCOFFX86; } diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -179,6 +179,7 @@ AllocaAddrSpace = 0; StackNaturalAlign.reset(); ProgramAddrSpace = 0; + FPEnvironmentSize = 0; FunctionPtrAlign.reset(); TheFunctionPtrAlignType = FunctionPtrAlignType::Independent; ManglingMode = MM_None; @@ -255,6 +256,22 @@ continue; } + if (Tok == "fe") { + if (Rest.empty()) + report_fatal_error("Missing size specification for FP environment in " + "datalayout string"); + Split = split(Rest, ':'); + Rest = Split.second; + FPEnvironmentSize = inBytes(getInt(Split.first)); + if (!Rest.empty()) { + unsigned Alignment = inBytes(getInt(Rest)); + if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment)) + report_fatal_error("Alignment is neither 0 nor a power of 2"); + FPEnvironmentAlign = MaybeAlign(Alignment); + } + continue; + } + char Specifier = Tok.front(); Tok = Tok.substr(1); diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp --- a/llvm/unittests/IR/DataLayoutTest.cpp +++ b/llvm/unittests/IR/DataLayoutTest.cpp @@ -56,4 +56,13 @@ DL.getValueOrABITypeAlignment(MaybeAlign(), FourByteAlignType)); } +TEST(DataLayoutTest, FPEnvironmentProperties) { + EXPECT_EQ(0, DataLayout("").getFPEnvironmentSize()); + EXPECT_EQ(0, DataLayout("fe:0").getFPEnvironmentSize()); + EXPECT_EQ(4, DataLayout("fe:32").getFPEnvironmentSize()); + EXPECT_EQ(MaybeAlign(), DataLayout("fe:32").getFPEnvironmentAlign()); + EXPECT_EQ(MaybeAlign(0), DataLayout("fe:32:0").getFPEnvironmentAlign()); + EXPECT_EQ(MaybeAlign(4), DataLayout("fe:32:32").getFPEnvironmentAlign()); +} + } // anonymous namespace