[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #8 from Richard Biener --- (In reply to David Brown from comment #7) > (In reply to rguent...@suse.de from comment #6) > > Can you provide a specific example that you would allow this way? > > > > > > I'd go back to my original example : > > > __attribute__((optimize("-fwrapv"))) > static inline int wrapped_add(int a, int b) { > return a + b; > } > > int foo(int x, int y, int z) { > return wrapped_add(wrapped_add(x, y), z); > } > > If you want to disable inlining of "wrapped_add" due to the change in the > semantics of integer arithmetic, that's fair enough. But if I /really/ want > inlining, and write something like : > > __attribute__((optimize("-fwrapv"), always_inline)) > static inline int wrapped_add(int a, int b) { > return a + b; > } > > then I want the code treated as : > > return (__wrapping_int) a + (__wrapping_int) b; > > or > > return __wrapping_add_int(a, b); > > If the way gcc marks and handles "-fwrapv" arithmetic does not support > something like that, which would allow inline mixing with other code, then > that would result in a compiler warning or error message. There is no way to do something like that for signed integer division because the way GCC supports is using unsigned integer arithmetic and then an unsigned to signed conversion. GCC also currently does not support re-writing the inlined function on-the-fly. > It might be best to have a new attribute name here rather than using > "always_inline" - I have not thought through the consequences. > > It might also be that if the compiler can be changed to support inlining of > a given optimisation attribute, then the attribute in question can be > whitelisted for inlining for everyone. I suppose what I am saying is that > if the compiler can't be sure that inlining is safe, then it could be > cautious by default while letting the programmer override that caution > explicitly. Indeed what we are missing is a diagnostic on the cases where always_inline (or any other exception) overrides the explicit list of problematic option mismatches. For an example I was more looking into a case where there it is not one of the explicitly rejected cases. Like if people do __attribute__((optimize("-fno-tree-pre"))) static inline int foo (...) { ... } int bar (...) { ... foo (); ... } there isn't a way to honor disabling PRE for the inlined code portion but still enabling it for the code originating from bar. So we can't fulfil users expectation honoring the optimize attribute and inlining at the same time. Would you prioritize inlining here? We most of the time prioritize the 'optimize' attribute and -Winline diagnoses this fact.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #6 from rguenther at suse dot de --- > Am 28.06.2022 um 14:53 schrieb david at westcontrol dot com > : > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 > > --- Comment #5 from David Brown --- > (In reply to Richard Biener from comment #4) >> (In reply to frankhb1989 from comment #3) >>> There is a more specific instance here: can_inline_edge_by_limits_p in >>> ipa-inline.cc treats flags and "optimize" attributes differently. >> >> A bit up there's a blacklist we maintain where inlining is not OK because it >> results in semantic differences. >> >> Generally we it's hard to second-guess the users intention when looking >> at an inline edge with different optimization settings of caller and callee. >> For C++ comdats there might be even multiple variants with different >> optimization level (but we only keep one, special-casing this a bit). > > I appreciate the "err on the side of caution" attitude. Perhaps there could > be > an extra "I know what I'm doing" attribute that lets you override the > blacklisting in a particular case. This would only really make sense in cases > where the attribute can be attached to the expressions and statements within > the function (I think "-fwrapv" would be in this category). In cases where > this is not possible, an error or warning message would be in order as the > compiler can't do what the programmer is asking. Can you provide a specific example that you would allow this way? > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #7 from David Brown --- (In reply to rguent...@suse.de from comment #6) > > Am 28.06.2022 um 14:53 schrieb david at westcontrol dot com > > : > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 > > > > --- Comment #5 from David Brown --- > > (In reply to Richard Biener from comment #4) > >> (In reply to frankhb1989 from comment #3) > >>> There is a more specific instance here: can_inline_edge_by_limits_p in > >>> ipa-inline.cc treats flags and "optimize" attributes differently. > >> > >> A bit up there's a blacklist we maintain where inlining is not OK because > >> it > >> results in semantic differences. > >> > >> Generally we it's hard to second-guess the users intention when looking > >> at an inline edge with different optimization settings of caller and > >> callee. > >> For C++ comdats there might be even multiple variants with different > >> optimization level (but we only keep one, special-casing this a bit). > > > > I appreciate the "err on the side of caution" attitude. Perhaps there > > could be > > an extra "I know what I'm doing" attribute that lets you override the > > blacklisting in a particular case. This would only really make sense in > > cases > > where the attribute can be attached to the expressions and statements within > > the function (I think "-fwrapv" would be in this category). In cases where > > this is not possible, an error or warning message would be in order as the > > compiler can't do what the programmer is asking. > > Can you provide a specific example that you would allow this way? > > I'd go back to my original example : __attribute__((optimize("-fwrapv"))) static inline int wrapped_add(int a, int b) { return a + b; } int foo(int x, int y, int z) { return wrapped_add(wrapped_add(x, y), z); } If you want to disable inlining of "wrapped_add" due to the change in the semantics of integer arithmetic, that's fair enough. But if I /really/ want inlining, and write something like : __attribute__((optimize("-fwrapv"), always_inline)) static inline int wrapped_add(int a, int b) { return a + b; } then I want the code treated as : return (__wrapping_int) a + (__wrapping_int) b; or return __wrapping_add_int(a, b); If the way gcc marks and handles "-fwrapv" arithmetic does not support something like that, which would allow inline mixing with other code, then that would result in a compiler warning or error message. It might be best to have a new attribute name here rather than using "always_inline" - I have not thought through the consequences. It might also be that if the compiler can be changed to support inlining of a given optimisation attribute, then the attribute in question can be whitelisted for inlining for everyone. I suppose what I am saying is that if the compiler can't be sure that inlining is safe, then it could be cautious by default while letting the programmer override that caution explicitly.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #5 from David Brown --- (In reply to Richard Biener from comment #4) > (In reply to frankhb1989 from comment #3) > > There is a more specific instance here: can_inline_edge_by_limits_p in > > ipa-inline.cc treats flags and "optimize" attributes differently. > > A bit up there's a blacklist we maintain where inlining is not OK because it > results in semantic differences. > > Generally we it's hard to second-guess the users intention when looking > at an inline edge with different optimization settings of caller and callee. > For C++ comdats there might be even multiple variants with different > optimization level (but we only keep one, special-casing this a bit). I appreciate the "err on the side of caution" attitude. Perhaps there could be an extra "I know what I'm doing" attribute that lets you override the blacklisting in a particular case. This would only really make sense in cases where the attribute can be attached to the expressions and statements within the function (I think "-fwrapv" would be in this category). In cases where this is not possible, an error or warning message would be in order as the compiler can't do what the programmer is asking.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #4 from Richard Biener --- (In reply to frankhb1989 from comment #3) > There is a more specific instance here: can_inline_edge_by_limits_p in > ipa-inline.cc treats flags and "optimize" attributes differently. A bit up there's a blacklist we maintain where inlining is not OK because it results in semantic differences. Generally we it's hard to second-guess the users intention when looking at an inline edge with different optimization settings of caller and callee. For C++ comdats there might be even multiple variants with different optimization level (but we only keep one, special-casing this a bit).
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #3 from frankhb1989 at gmail dot com --- There is a more specific instance here: can_inline_edge_by_limits_p in ipa-inline.cc treats flags and "optimize" attributes differently. While it is reasonable to reject inlining for semantic mismatch from different global flags, "opts_for_fn (caller->decl) != opts_for_fn (callee->decl)" looks quite unnatural. In practice it means missing of valid opportunity of inlining, unless the programmer knows what should go under the hood and decides to propagate "always_inline" plus the "optimize" attributes manually in the declarations of *all* callees (including lambda-expressions in C++), *recursively*. Adding "__attribute__((flatten))" can be a workaround sometimes, but it does not always generated desired code, and often too slow. This is somewhat worse than the case of "-fwrapv" whose semantic is easier to reason in the generated code.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 Martin Sebor changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2021-07-02 CC||msebor at gcc dot gnu.org Status|UNCONFIRMED |NEW --- Comment #2 from Martin Sebor --- Compiling the test case with -Winline shows the problem: pr101279.c: In function ‘foo’: pr101279.c:2:19: warning: inlining failed in call to ‘wrapped_add’: optimization level attribute mismatch [-Winline] 2 | static inline int wrapped_add(int a, int b) { | ^~~ pr101279.c:7:12: note: called from here 7 | return wrapped_add(wrapped_add(x, y), z); |^ pr101279.c:2:19: warning: inlining failed in call to ‘wrapped_add’: optimization level attribute mismatch [-Winline] 2 | static inline int wrapped_add(int a, int b) { | ^~~ pr101279.c:7:12: note: called from here 7 | return wrapped_add(wrapped_add(x, y), z); |^ Declaring wrapped_add() with attribute always_inline avoids the warning but also loses the -fwrapv option. This also seems somewhat surprising and could stand be made clearer in the manual. The manual says "this attribute inlines the function independent of any restrictions that otherwise apply to inlining." but I see no such restrictions discussed under the optimize attribute or in the inlining setion (https://gcc.gnu.org/onlinedocs/gcc/Inline.html). But this report isn't just about attribute optimize but rather about the general inconsistency of the interplay between inlining and each function attribute, and the lack of documentation of it. Confirmed. I'll see if I can add a few words to the manual for now.
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 --- Comment #1 from Andrew Pinski --- See also https://gcc.gnu.org/legacy-ml/gcc/2009-02/msg00408.html which was a way forward for wrapv but there was not much work on it really since that year. The work on this has a huge impact to the IR really.