Bug 2223951
| Summary: | Possible regression since f37/GCC 12.3.1 in handling of __attribute__((always_inline, optimize("-O3"))) | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Martin Osvald 🛹 <mosvald> | ||||||||||
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> | ||||||||||
| Status: | CLOSED NOTABUG | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||||||||
| Severity: | medium | Docs Contact: | |||||||||||
| Priority: | unspecified | ||||||||||||
| Version: | rawhide | CC: | dmalcolm, fweimer, jakub, jlaw, jwakely, mcermak, mpolacek, msebor, nickc, sipoyare | ||||||||||
| Target Milestone: | --- | ||||||||||||
| Target Release: | --- | ||||||||||||
| Hardware: | x86_64 | ||||||||||||
| OS: | Linux | ||||||||||||
| Whiteboard: | |||||||||||||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |||||||||||
| Doc Text: | Story Points: | --- | |||||||||||
| Clone Of: | Environment: | ||||||||||||
| Last Closed: | 2023-07-19 12:37:36 UTC | Type: | --- | ||||||||||
| Regression: | --- | Mount Type: | --- | ||||||||||
| Documentation: | --- | CRM: | |||||||||||
| Verified Versions: | Category: | --- | |||||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||||
| Embargoed: | |||||||||||||
| Attachments: |
|
||||||||||||
|
Description
Martin Osvald 🛹
2023-07-19 11:52:35 UTC
Created attachment 1976494 [details]
srpm
Created attachment 1976495 [details]
f36-build.log
this passes without errors
Created attachment 1976496 [details]
f37-build.log
shows the error
Created attachment 1976497 [details]
f39-build.log
shows the error
buf_len code:
./cyrus-imapd-3.8.0/lib/util.c:
~~~
1189 #ifdef HAVE_DECLARE_OPTIMIZE
1190 EXPORTED inline size_t buf_len(const struct buf *buf)
1191 __attribute__((always_inline, optimize("-O3")));
1192 #endif
1193 EXPORTED inline size_t buf_len(const struct buf *buf)
1194 {
1195 return buf->len;
1196 }
~~~
note that it fails even if I remove the optimize("-O3")
With always_inline attribute you ask the compiler to error if it couldn't inline the function, which is exactly what you got.
__attribute__((always_inline, optimize("-O3"))) is in itself non-sense, either you want to always inline the function,
then what optimization level it has doesn't matter much, you get what optimization level has the function into which it is inlined.
Also, making an exported function always_inline inside of a *.c file (rather than putting the inline function definition and
the attribute into a header file) doesn't make much sense, without LTO it then isn't really inlined into anything but callers within
the same function.
GCC treats various option differences as preventing inlining, some can differ in one direction only and not in the other, some the other way around, etc.
E.g.
/* There are some options that change IL semantics which means
we cannot inline in these cases for correctness reason.
Not even for always_inline declared functions. */
else if (check_match (flag_wrapv)
|| check_match (flag_trapv)
|| check_match (flag_pcc_struct_return)
|| check_maybe_down (optimize_debug)
/* When caller or callee does FP math, be sure FP codegen flags
compatible. */
|| ((caller_info->fp_expressions && callee_info->fp_expressions)
&& (check_maybe_up (flag_rounding_math)
|| check_maybe_up (flag_trapping_math)
|| check_maybe_down (flag_unsafe_math_optimizations)
|| check_maybe_down (flag_finite_math_only)
|| check_maybe_up (flag_signaling_nans)
|| check_maybe_down (flag_cx_limited_range)
|| check_maybe_up (flag_signed_zeros)
|| check_maybe_down (flag_associative_math)
|| check_maybe_down (flag_reciprocal_math)
|| check_maybe_down (flag_fp_int_builtin_inexact)
/* Strictly speaking only when the callee contains function
calls that may end up setting errno. */
|| check_maybe_up (flag_errno_math)))
/* We do not want to make code compiled with exceptions to be
brought into a non-EH function unless we know that the callee
does not throw.
This is tracked by DECL_FUNCTION_PERSONALITY. */
|| (check_maybe_up (flag_non_call_exceptions)
&& DECL_FUNCTION_PERSONALITY (callee->decl))
|| (check_maybe_up (flag_exceptions)
&& DECL_FUNCTION_PERSONALITY (callee->decl))
/* When devirtualization is disabled for callee, it is not safe
to inline it as we possibly mangled the type info.
Allow early inlining of always inlines. */
|| (!early && check_maybe_down (flag_devirtualize)))
Without trying it it isn't clear which of the cases this actually is.
And the log quickly shows the reason. IMAP.c (created from IMAP.xs) which calls buf_len is compiled with -fwrapv option, while lib/util.c is not. As whether operations on signed integers are wrapping or have undefined behavior or trapping aren't in GCC encoded in the IL, but come from per-function flags, it is really not possible to do such inlining. You can either drop the bogus always_inline, it doesn't help much, such trivial function is inlined whenever possible anyway, or compile IMAP.c without -flto=auto (or add -fno-lto), such that that TU which uses -fwrapv isn't LTO optimized together with the rest, etc. |