Message ID | ri68r11zkmp.fsf@virgil.suse.cz |
---|---|
State | New |
Headers | show |
Series | [wwwdocs] Porting-to-14: Mention new pragma GCC Target behavior | expand |
On Thu, Apr 25, 2024 at 02:34:22PM +0200, Martin Jambor wrote: > when looking at a package build issue with GCC 14, Michal Jireš noted a > different behavior of pragma GCC Target. This snippet tries to describe > the gist of the problem. I have left it in the C section even though it > is not really C specific, but could not think of a good name for a new > section for it. Ideas (and any other suggestions for improvements) > welcome, of course. The change was more subtle. We used to define/undefine the ISA macros in C in GCC 13 and older as well, but only when using integrated preprocessor during compilation, so it didn't work that way with -save-temps or separate -E and -S/-c steps. While in C++ it behaved as if the define/undefines aren't done at all (they were done, but after preprocessing/lexing everything, so didn't affect anything). In GCC 14, it behaves in C++ the same as in C in older versions, and additionally they are defined/undefined also when using separate preprocessing, in both C and C++. Jakub
Hi, On Thu, Apr 25 2024, Jakub Jelinek wrote: > On Thu, Apr 25, 2024 at 02:34:22PM +0200, Martin Jambor wrote: >> when looking at a package build issue with GCC 14, Michal Jireš noted a >> different behavior of pragma GCC Target. This snippet tries to describe >> the gist of the problem. I have left it in the C section even though it >> is not really C specific, but could not think of a good name for a new >> section for it. Ideas (and any other suggestions for improvements) >> welcome, of course. > > The change was more subtle. > We used to define/undefine the ISA macros in C in GCC 13 and older as well, > but only when using integrated preprocessor during compilation, > so it didn't work that way with -save-temps or separate -E and -S/-c > steps. > While in C++ it behaved as if the define/undefines aren't done at all > (they were done, but after preprocessing/lexing everything, so didn't > affect anything). > In GCC 14, it behaves in C++ the same as in C in older versions, and > additionally they are defined/undefined also when using separate > preprocessing, in both C and C++. > I see, thanks for the correction. Would the following then perhaps describe the situation accurately? Note that I have moved the whole thing to C++ section because it seems porting issues in C because of this are quite unlikely. Michal, I assume that the file where this issue happened was written in C++, right? Martin diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index c825a68e..1e67b0b3 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -514,6 +514,51 @@ be included explicitly when compiling with GCC 14: </li> </ul> +<h3 id="gcc-targte-pragma">Pragma GCC Target now affects preprocessor symbols</h4> + +<p> +The behavior of pragma GCC Target and specifically how it affects ISA +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC +target</code> pragma defined and undefined corresponding ISA macros in +C when using integrated preprocessor during compilation but not when +preprocessor was invoked as a separate step or when using -save-temps. +In C++ the ISA macro definitions were performed in a way which did not +have any actual effect. + +In GCC 14 C++ behaves like C with integrated preprocessing in earlier +versions. Moreover, in both languages ISA macros are defined and +undefined as expected when preprocessing separately from compilation. + +<p> +This can lead to different behavior, especially in C++. For example, +functions the C++ snippet below will be (silently) compiled for an +incorrect instruction set by GCC 14. + +<pre> + #if ! __AVX2__ + #pragma GCC push_options + #pragma GCC target("avx2") + #endif + + /* Code to be compiled for AVX2. */ + + /* With GCC 14, __AVX2__ here will always be defined and pop_options + never called. */ + #if ! __AVX2__ + #pragma GCC pop_options + #endif + + /* With GCC 14, all following functions will be compiled for AVX2 + which was not intended. */ +</pre> + +<p> +The fix in this case would be to remember +whether <code>pop_options</code> needs to be performed in a new +user-defined macro. + + + <!-- <h2 id="fortran">Fortran language issues</h2> --> </body>
On Tue, Apr 30, 2024 at 11:12:30PM +0200, Martin Jambor wrote: > Would the following then perhaps describe the situation accurately? > Note that I have moved the whole thing to C++ section because it seems > porting issues in C because of this are quite unlikely. > > Michal, I assume that the file where this issue happened was written in > C++, right? > > Martin > > > > diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html > index c825a68e..1e67b0b3 100644 > --- a/htdocs/gcc-14/porting_to.html > +++ b/htdocs/gcc-14/porting_to.html > @@ -514,6 +514,51 @@ be included explicitly when compiling with GCC 14: > </li> > </ul> > > +<h3 id="gcc-targte-pragma">Pragma GCC Target now affects preprocessor symbols</h4> I'd use lowercase Target here > + > +<p> > +The behavior of pragma GCC Target and specifically how it affects ISA And here as well, perhaps even <code>#pragma GCC target</code>. Otherwise LGTM. > +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC > +target</code> pragma defined and undefined corresponding ISA macros in > +C when using integrated preprocessor during compilation but not when > +preprocessor was invoked as a separate step or when using -save-temps. > +In C++ the ISA macro definitions were performed in a way which did not > +have any actual effect. > + > +In GCC 14 C++ behaves like C with integrated preprocessing in earlier > +versions. Moreover, in both languages ISA macros are defined and > +undefined as expected when preprocessing separately from compilation. > + > +<p> > +This can lead to different behavior, especially in C++. For example, > +functions the C++ snippet below will be (silently) compiled for an > +incorrect instruction set by GCC 14. > + > +<pre> > + #if ! __AVX2__ > + #pragma GCC push_options > + #pragma GCC target("avx2") > + #endif > + > + /* Code to be compiled for AVX2. */ > + > + /* With GCC 14, __AVX2__ here will always be defined and pop_options > + never called. */ > + #if ! __AVX2__ > + #pragma GCC pop_options > + #endif > + > + /* With GCC 14, all following functions will be compiled for AVX2 > + which was not intended. */ > +</pre> > + > +<p> > +The fix in this case would be to remember > +whether <code>pop_options</code> needs to be performed in a new > +user-defined macro. > + > + > + > <!-- <h2 id="fortran">Fortran language issues</h2> --> > > </body> Jakub
On Tue, 30 Apr 2024, Martin Jambor wrote: > +<h3 id="gcc-targte-pragma">Pragma GCC Target now affects preprocessor symbols</h4> Note the id: should be "gcc-target-pragma", though I even suggest to simplify and say "target-pragma". > +The behavior of pragma GCC Target and specifically how it affects ISA Seconding Jakub's "And here as well, perhaps even <code>#pragma GCC target</code>." > +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC > +target</code> pragma defined and undefined corresponding ISA macros in > +C when using integrated preprocessor during compilation but not when "...the integrated preprocessor..." > +preprocessor was invoked as a separate step or when using -save-temps. "...the preprocessor..." and <code>-save-temps</code>, or better "the <code>-save-temps</code> option". > +This can lead to different behavior, especially in C++. For example, > +functions the C++ snippet below will be (silently) compiled for an > +incorrect instruction set by GCC 14. "functions" above looks like it's extraneous and should be skipped? > + /* With GCC 14, __AVX2__ here will always be defined and pop_options > + never called. */ > + #if ! __AVX2__ > + #pragma GCC pop_options > + #endif Maybe a bit subtle, I would not say a #pragma is called; how about invoked or activated? > +<p> > +The fix in this case would be to remember > +whether <code>pop_options</code> needs to be performed in a new > +user-defined macro. "The fix in this case is to remember" (or "...remembering...") Gerald
Hi, On Wed, May 01 2024, Gerald Pfeifer wrote: > On Tue, 30 Apr 2024, Martin Jambor wrote: >> +<h3 id="gcc-targte-pragma">Pragma GCC Target now affects preprocessor symbols</h4> > > Note the id: should be "gcc-target-pragma", though I even suggest to > simplify and say "target-pragma". > >> +The behavior of pragma GCC Target and specifically how it affects ISA > > Seconding Jakub's > > "And here as well, perhaps even <code>#pragma GCC target</code>." > >> +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC >> +target</code> pragma defined and undefined corresponding ISA macros in >> +C when using integrated preprocessor during compilation but not when > > "...the integrated preprocessor..." > >> +preprocessor was invoked as a separate step or when using -save-temps. > > "...the preprocessor..." > > and <code>-save-temps</code>, or better "the <code>-save-temps</code> > option". > >> +This can lead to different behavior, especially in C++. For example, >> +functions the C++ snippet below will be (silently) compiled for an >> +incorrect instruction set by GCC 14. > > "functions" above looks like it's extraneous and should be skipped? > >> + /* With GCC 14, __AVX2__ here will always be defined and pop_options >> + never called. */ >> + #if ! __AVX2__ >> + #pragma GCC pop_options >> + #endif > > Maybe a bit subtle, I would not say a #pragma is called; how about invoked > or activated? > >> +<p> >> +The fix in this case would be to remember >> +whether <code>pop_options</code> needs to be performed in a new >> +user-defined macro. > > "The fix in this case is to remember" (or "...remembering...") > Thanks for your suggestions, this is what I am going to commit in a moment. Martin diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index c825a68e..a20d82c2 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -514,6 +514,48 @@ be included explicitly when compiling with GCC 14: </li> </ul> +<h3 id="target-pragma">Pragma GCC target now affects preprocessor symbols</h4> + +<p> +The behavior of pragma GCC target and specifically how it affects ISA +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC +target</code> pragma defined and undefined corresponding ISA macros in +C when using the integrated preprocessor during compilation but not +when the preprocessor was invoked as a separate step or when using +the <code>-save-temps</code> option. In C++ the ISA macro definitions +were performed in a way which did not have any actual effect. + +In GCC 14 C++ behaves like C with integrated preprocessing in earlier +versions. Moreover, in both languages ISA macros are defined and +undefined as expected when preprocessing separately from compilation. + +<p> +This can lead to different behavior, especially in C++. For example, +a part of the C++ snippet below will be (silently) compiled for an +incorrect instruction set by GCC 14. + +<pre> + #if ! __AVX2__ + #pragma GCC push_options + #pragma GCC target("avx2") + #endif + + /* Code to be compiled for AVX2. */ + + /* With GCC 14, __AVX2__ here will always be defined and pop_options + never invoked. */ + #if ! __AVX2__ + #pragma GCC pop_options + #endif + + /* With GCC 14, all following functions will be compiled for AVX2 + which was not intended. */ +</pre> + +<p> +The fix in this case is to remember whether <code>pop_options</code> +needs to be performed in a new user-defined macro. + <!-- <h2 id="fortran">Fortran language issues</h2> --> </body>
On Thu, 2 May 2024, Martin Jambor wrote: > Thanks for your suggestions, this is what I am going to commit in a > moment. Thanks! > diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html > > +<h3 id="target-pragma">Pragma GCC target now affects preprocessor symbols</h4> A small detail I missed: <h3> closed by </h4> :-) I'll fix this in a second. > +<p> > +The behavior of pragma GCC target and specifically how it affects ISA > +macros has changed in GCC 14. In GCC 13 and older, the <code>GCC > +target</code> pragma defined and undefined corresponding ISA macros in > +C when using the integrated preprocessor during compilation but not > +when the preprocessor was invoked as a separate step or when using > +the <code>-save-temps</code> option. In C++ the ISA macro definitions > +were performed in a way which did not have any actual effect. > + > +In GCC 14 C++ behaves like C with integrated preprocessing in earlier > +versions. Moreover, in both languages ISA macros are defined and > +undefined as expected when preprocessing separately from compilation. I assume this should be two paragraphs? I'll make this change and some other tweaks. Gerald
diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index c825a68e..ae9a3cde 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -490,6 +490,43 @@ in C23. GCC will probably continue to support old-style function definitions even once C23 is used as the default language dialect. +<h4 id="gcc-targte-pragma">Pragma GCC Target now affects preprocessor symbols</h4> + +<p> +The behavior of pragma GCC Target has changed in GCC 14. For example, +GCC 13 and below defines <code>__AVX2__</code> only when the target +is specified on the command line. This has been considered <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87299">a +bug</a> and since it was fixed in GCC 14, <code>__AVX2__</code> is now also +defined with <code>#pragma GCC target("avx2")</code>. + +<p> +Therefore, if macros expand to something like the snippet below, +functions will be (silently) compiled for an incorrect instruction +set. + +<pre> + #if ! __AVX2__ + #pragma GCC push_options + #pragma GCC target("avx2") + #endif + + /* Code to be compiled for AVX2. */ + + /* With GCC 14, __AVX2__ here will always be defined and pop_options + never called. */ + #if ! __AVX2__ + #pragma GCC pop_options + #endif + + /* With GCC 14, all following functions will be compiled for AVX2 + which was not intended. */ +</pre> + +<p> +The fix in this case would be to remember +whether <code>pop_options</code> needs to be performed in a new +user-defined macro. + <h2 id="cxx">C++ language issues</h2> <h3 id="header-dep-changes">Header dependency changes</h3>