Skip to content

GCC PCH Breakage Triggered by fmt Scoped #pragma GCC optimize("Og") #4757

@bc-lee

Description

@bc-lee

fmt uses a scoped optimization pragma in include/fmt/base.h:

FMT_PRAGMA_GCC(push_options)
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
FMT_PRAGMA_GCC(optimize("Og"))
#endif
...
FMT_PRAGMA_GCC(pop_options)

This is correct in normal compilation. However, with GCC + PCH, this can leave the compiler in an inconsistent state after PCH restore and break unrelated code.

Example failure:
error: the last argument must be an 8-bit immediate
from _mm_srli_si128(x, 2) in <emmintrin.h>.

The same code compiles fine without PCH.

Related Bugs

I originally reported as GCC bug(RHBZ 2457604): https://bugzilla.redhat.com/show_bug.cgi?id=2457604

Also similar bug report in GCC bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105120

Similar bug report suggest that #pragma GCC optimize state is not fully or consistently restored across PCH boundaries.

Workarounds

Current options are:

  • avoid using PCH with affected GCC versions
  • avoid affected GCC versions

Proposed Workaround in fmt

Please add an opt-out macro to disable the optimization pragma:

#if !defined(FMT_DISABLE_DEBUG_OPTIMIZE_PRAGMA)
FMT_PRAGMA_GCC(push_options)
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
FMT_PRAGMA_GCC(optimize("Og"))
#endif
#endif // !defined(FMT_DISABLE_DEBUG_OPTIMIZE_PRAGMA)
...
#if !defined(FMT_DISABLE_DEBUG_OPTIMIZE_PRAGMA)
FMT_PRAGMA_GCC(pop_options)
#endif // !defined(FMT_DISABLE_DEBUG_OPTIMIZE_PRAGMA)

Rationale

  • This is a QoI/debug optimization, not required for correctness
  • Default behavior remains unchanged
  • Provides a reliable escape hatch for GCC + PCH users
  • Avoids forcing users to drop PCH or fmt usage

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions