Date: Wed, 01 Jan 2025 23:24:19 +0000 From: bugzilla-noreply@freebsd.org To: toolchain@FreeBSD.org Subject: [Bug 276170] LLVM bug prevents from enabling PGO optimization for Python 3.11+ Message-ID: <bug-276170-29464-4xpH0CSFRB@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-276170-29464@https.bugs.freebsd.org/bugzilla/> References: <bug-276170-29464@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D276170 Dimitry Andric <dim@FreeBSD.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|New |In Progress CC| |emaste@freebsd.org --- Comment #44 from Dimitry Andric <dim@FreeBSD.org> --- After some more investigation I found the cause, which is (again) the fact = that assertions are _disabled_ on stable and release branches. This particular "error" is occurring in contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp, on line 422: 414 if (CodeGenOpts.hasProfileClangUse()) { 415 auto ReaderOrErr =3D llvm::IndexedInstrProfReader::create( 416 CodeGenOpts.ProfileInstrumentUsePath, *FS, 417 CodeGenOpts.ProfileRemappingFile); 418 // We're checking for profile read errors in CompilerInvocation= , so if 419 // there was an error it should've already been caught. If it hasn't been 420 // somehow, trip an assertion. 421 assert(ReaderOrErr); 422 PGOReader =3D std::move(ReaderOrErr.get()); 423 } llvm::IndexedInstrProfReader::create() returns a llvm::Expected<> instance, which is similar to std::expected: it can contain either a "good" return va= lue, or an error. In some llvm build configurations, when you attempt to use the return value without checking whether it contains an error, you get "Expected<T> must be checked before access or destruction". This occurs even if the Expected<> object contains a valid value, in which case you get "Expected<T> value was= in success state". When llvm is built with assertions (WITH_LLVM_ASSERTIONS, which is on by default on -CURRENT, but not on stable or release branches), the assert() statement on line 421 is calling llvm::Expected<>::operator bool(), which checks whether the contained object is valid, and if so it resets the check= ed state: /// Bool conversion. Returns true if this Error is in a failure state, /// and false if it is in an accept state. If the error is in a Success s= tate /// it will be considered checked. explicit operator bool() { setChecked(getPtr() =3D=3D nullptr); return getPtr() !=3D nullptr; } Then in line 422 the contained object is moved out of the 'ReaderOrErr' variable, into the 'PGOReader' variable. Finally, the 'ReaderOrErr' variabl= e, which is now empty, is destroyed. However, when llvm is built without assertions (WITHOUT_LLVM_ASSERTIONS), t= he assert() statement on line 421 does nothing, and the 'ReaderOrErr' variabl= e is unaffected. Then in line 422, llvm::Expected<>::get() is called: /// Returns a reference to the stored T value. reference get() { assertIsChecked(); return *getStorage(); } The first thing get() does is looking if the Expected<> object was checked,= and if not, it prints "Expected<T> must be checked before access or destruction" and the whole program dies. Finally, assertIsChecked() is only really doing something if the global llvm macro LLVM_ENABLE_ABI_BREAKING_CHECKS is defined: void assertIsChecked() const { #if LLVM_ENABLE_ABI_BREAKING_CHECKS if (LLVM_UNLIKELY(Unchecked)) fatalUncheckedExpected(); #endif } In the upstream build system, LLVM_ENABLE_ABI_BREAKING_CHECKS is typically 0 when assertions are off, and 1 when assertions are on. In the FreeBSD case, this use to always be defined as 1 in lib/clang/include/llvm/Config/abi-breaking.h, until base 1c83996beda7 ("Adj= ust LLVM_ENABLE_ABI_BREAKING_CHECKS depending on NDEBUG"): 15 /* Define to enable checks that alter the LLVM C++ ABI */ 16 #ifdef NDEBUG 17 #define LLVM_ENABLE_ABI_BREAKING_CHECKS 0 18 #else 19 #define LLVM_ENABLE_ABI_BREAKING_CHECKS 1 20 #endif Unfortunately 14.2 does not have this commit, so the combination of MK_LLVM_ASSERTIONS=3Dno and LLVM_ENABLE_ABI_BREAKING_CHECKS=3D1 leads to the scenario describe above: the assert() statement in CodeGenModule.cpp line 4= 21 does nothing, but ReaderOrErr.get() still performs the check and aborts. I merged base 1c83996beda7 to stable/14 in base 86de9cd1f1b5, and to stable= /13 in base 44be5a00bedd, but this is unfortunately not available in 14.2-RELEA= SE or 13.4-RELEASE, so for those releases there isn't much I can do except to = try to roll it into a Erratum. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-276170-29464-4xpH0CSFRB>