diff options
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 130 | ||||
-rw-r--r-- | llvm/lib/Support/BLAKE3/CMakeLists.txt | 3 | ||||
-rw-r--r-- | llvm/lib/Support/FileCollector.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Support/VirtualFileSystem.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Threading.inc | 2 |
5 files changed, 138 insertions, 11 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 5e0b29f..46084c5 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -900,6 +900,30 @@ writeSignedDecimal (char *dst, int value) return dst; } +// Compute the ULP of the input using a definition from: +// Jean-Michel Muller. On the definition of ulp(x). [Research Report] RR-5504, +// LIP RR-2005-09, INRIA, LIP. 2005, pp.16. inria-00070503 +static APFloat harrisonUlp(const APFloat &X) { + const fltSemantics &Sem = X.getSemantics(); + switch (X.getCategory()) { + case APFloat::fcNaN: + return APFloat::getQNaN(Sem); + case APFloat::fcInfinity: + return APFloat::getInf(Sem); + case APFloat::fcZero: + return APFloat::getSmallest(Sem); + case APFloat::fcNormal: + break; + } + if (X.isDenormal() || X.isSmallestNormalized()) + return APFloat::getSmallest(Sem); + int Exp = ilogb(X); + if (X.getExactLog2() != INT_MIN) + Exp -= 1; + return scalbn(APFloat::getOne(Sem), Exp - (Sem.precision - 1), + APFloat::rmNearestTiesToEven); +} + namespace detail { /* Constructors. */ void IEEEFloat::initialize(const fltSemantics *ourSemantics) { @@ -5306,12 +5330,110 @@ Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S, return Ret; } +// The double-double lattice of values corresponds to numbers which obey: +// - abs(lo) <= 1/2 * ulp(hi) +// - roundTiesToEven(hi + lo) == hi +// +// nextUp must choose the smallest output > input that follows these rules. +// nexDown must choose the largest output < input that follows these rules. APFloat::opStatus DoubleAPFloat::next(bool nextDown) { assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); - auto Ret = Tmp.next(nextDown); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); - return Ret; + // nextDown(x) = -nextUp(-x) + if (nextDown) { + changeSign(); + APFloat::opStatus Result = next(/*nextDown=*/false); + changeSign(); + return Result; + } + switch (getCategory()) { + case fcInfinity: + // nextUp(+inf) = +inf + // nextUp(-inf) = -getLargest() + if (isNegative()) + makeLargest(true); + return opOK; + + case fcNaN: + // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag. + // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not + // change the payload. + if (getFirst().isSignaling()) { + // For consistency, propagate the sign of the sNaN to the qNaN. + makeNaN(false, isNegative(), nullptr); + return opInvalidOp; + } + return opOK; + + case fcZero: + // nextUp(pm 0) = +getSmallest() + makeSmallest(false); + return opOK; + + case fcNormal: + break; + } + + const APFloat &HiOld = getFirst(); + const APFloat &LoOld = getSecond(); + + APFloat NextLo = LoOld; + NextLo.next(/*nextDown=*/false); + + // We want to admit values where: + // 1. abs(Lo) <= ulp(Hi)/2 + // 2. Hi == RTNE(Hi + lo) + auto InLattice = [](const APFloat &Hi, const APFloat &Lo) { + return Hi + Lo == Hi; + }; + + // Check if (HiOld, nextUp(LoOld) is in the lattice. + if (InLattice(HiOld, NextLo)) { + // Yes, the result is (HiOld, nextUp(LoOld)). + Floats[1] = std::move(NextLo); + + // TODO: Because we currently rely on semPPCDoubleDoubleLegacy, our maximum + // value is defined to have exactly 106 bits of precision. This limitation + // results in semPPCDoubleDouble being unable to reach its maximum canonical + // value. + DoubleAPFloat Largest{*Semantics, uninitialized}; + Largest.makeLargest(/*Neg=*/false); + if (compare(Largest) == cmpGreaterThan) + makeInf(/*Neg=*/false); + + return opOK; + } + + // Now we need to handle the cases where (HiOld, nextUp(LoOld)) is not the + // correct result. We know the new hi component will be nextUp(HiOld) but our + // lattice rules make it a little ambiguous what the correct NextLo must be. + APFloat NextHi = HiOld; + NextHi.next(/*nextDown=*/false); + + // nextUp(getLargest()) == INFINITY + if (NextHi.isInfinity()) { + makeInf(/*Neg=*/false); + return opOK; + } + + // IEEE 754-2019 5.3.1: + // "If x is the negative number of least magnitude in x's format, nextUp(x) is + // -0." + if (NextHi.isZero()) { + makeZero(/*Neg=*/true); + return opOK; + } + + // abs(NextLo) must be <= ulp(NextHi)/2. We want NextLo to be as close to + // negative infinity as possible. + NextLo = neg(scalbn(harrisonUlp(NextHi), -1, rmTowardZero)); + if (!InLattice(NextHi, NextLo)) + // RTNE may mean that Lo must be < ulp(NextHi) / 2 so we bump NextLo. + NextLo.next(/*nextDown=*/false); + + Floats[0] = std::move(NextHi); + Floats[1] = std::move(NextLo); + + return opOK; } APFloat::opStatus diff --git a/llvm/lib/Support/BLAKE3/CMakeLists.txt b/llvm/lib/Support/BLAKE3/CMakeLists.txt index eae2b02..90311ae 100644 --- a/llvm/lib/Support/BLAKE3/CMakeLists.txt +++ b/llvm/lib/Support/BLAKE3/CMakeLists.txt @@ -26,7 +26,8 @@ endmacro() if (CAN_USE_ASSEMBLER) if (MSVC) check_symbol_exists(_M_X64 "" IS_X64) - if (IS_X64) + check_symbol_exists(_M_ARM64EC "" IS_ARM64EC) + if (IS_X64 AND NOT IS_ARM64EC) enable_language(ASM_MASM) set(LLVM_BLAKE3_ASM_FILES blake3_sse2_x86-64_windows_msvc.asm diff --git a/llvm/lib/Support/FileCollector.cpp b/llvm/lib/Support/FileCollector.cpp index 29436f8..edb5313 100644 --- a/llvm/lib/Support/FileCollector.cpp +++ b/llvm/lib/Support/FileCollector.cpp @@ -313,5 +313,6 @@ private: IntrusiveRefCntPtr<vfs::FileSystem> FileCollector::createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS, std::shared_ptr<FileCollector> Collector) { - return new FileCollectorFileSystem(std::move(BaseFS), std::move(Collector)); + return makeIntrusiveRefCnt<FileCollectorFileSystem>(std::move(BaseFS), + std::move(Collector)); } diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index e489282..5d42488 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -397,7 +397,8 @@ void RealFileSystem::printImpl(raw_ostream &OS, PrintType Type, } IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { - static IntrusiveRefCntPtr<FileSystem> FS(new RealFileSystem(true)); + static IntrusiveRefCntPtr<FileSystem> FS = + makeIntrusiveRefCnt<RealFileSystem>(true); return FS; } @@ -2217,9 +2218,9 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create( ArrayRef<std::pair<std::string, std::string>> RemappedFiles, - bool UseExternalNames, FileSystem &ExternalFS) { + bool UseExternalNames, llvm::IntrusiveRefCntPtr<FileSystem> ExternalFS) { std::unique_ptr<RedirectingFileSystem> FS( - new RedirectingFileSystem(&ExternalFS)); + new RedirectingFileSystem(ExternalFS)); FS->UseExternalNames = UseExternalNames; StringMap<RedirectingFileSystem::Entry *> Entries; @@ -2228,7 +2229,7 @@ std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create( SmallString<128> From = StringRef(Mapping.first); SmallString<128> To = StringRef(Mapping.second); { - auto EC = ExternalFS.makeAbsolute(From); + auto EC = ExternalFS->makeAbsolute(From); (void)EC; assert(!EC && "Could not make absolute path"); } @@ -2250,7 +2251,7 @@ std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create( } assert(Parent && "File without a directory?"); { - auto EC = ExternalFS.makeAbsolute(To); + auto EC = ExternalFS->makeAbsolute(To); (void)EC; assert(!EC && "Could not make absolute path"); } diff --git a/llvm/lib/Support/Windows/Threading.inc b/llvm/lib/Support/Windows/Threading.inc index 8dd7c88..b11f216 100644 --- a/llvm/lib/Support/Windows/Threading.inc +++ b/llvm/lib/Support/Windows/Threading.inc @@ -136,6 +136,7 @@ HMODULE loadSystemModuleSecure(LPCWSTR lpModuleName) { } // namespace llvm::sys::windows SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) { +#ifdef THREAD_POWER_THROTTLING_CURRENT_VERSION HMODULE kernelM = llvm::sys::windows::loadSystemModuleSecure(L"kernel32.dll"); if (kernelM) { // SetThreadInformation is only available on Windows 8 and later. Since we @@ -166,6 +167,7 @@ SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) { : 0); } } +#endif // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority // Begin background processing mode. The system lowers the resource scheduling |