On 6/2/25 5:44 PM, Andrew Pinski wrote:
From: Gwenole Beauchesne <gb.de...@gmail.com>
Handle '#pragma GCC optimize' earlier as the __OPTIMIZE__ macro may need
to be defined as well for certain usages. Add additional tests for the
'#pragma GCC target' case with auto-vectorization enabled and multiple
combinations of namespaces and/or class member functions.
This is similar to what was done for `#pramga GCC target` in
r14-4967-g8697d3a1dcf327,
to fix the similar issue there.
Add more complete tests for PR c++/41201 after git commit
r14-4967-g8697d3a1dcf327.
OK next week if no concerns from C maintainers.
PR c++/41201
PR c++/48026
gcc/c-family/ChangeLog:
* c-pragma.cc (init_pragma): Use c_register_pragma_with_early_handler
instead of c_register_pragma for `#pragma GCC optimize`.
gcc/testsuite/ChangeLog:
* c-c++-common/pragma-optimize-1.c: New test.
* g++.target/i386/vect-pragma-target-1.C: New test.
* g++.target/i386/vect-pragma-target-2.C: New test.
* gcc.target/i386/vect-pragma-target-1.c: New test.
* gcc.target/i386/vect-pragma-target-2.c: New test.
Signed-off-by: Gwenole Beauchesne <gb.de...@gmail.com>
Co-authored-by: Andrew Pinski <quic_apin...@quicinc.com>
---
gcc/c-family/c-pragma.cc | 4 +-
.../c-c++-common/pragma-optimize-1.c | 10 +
.../g++.target/i386/vect-pragma-target-1.C | 6 +
.../g++.target/i386/vect-pragma-target-2.C | 6 +
.../gcc.target/i386/vect-pragma-target-1.c | 194 ++++++++++++++++++
.../gcc.target/i386/vect-pragma-target-2.c | 7 +
6 files changed, 226 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/c-c++-common/pragma-optimize-1.c
create mode 100644 gcc/testsuite/g++.target/i386/vect-pragma-target-1.C
create mode 100644 gcc/testsuite/g++.target/i386/vect-pragma-target-2.C
create mode 100644 gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 8b5cdcc56ea..137b83bf5b1 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1847,7 +1847,9 @@ init_pragma (void)
c_register_pragma_with_early_handler ("GCC", "target",
handle_pragma_target,
handle_pragma_target);
- c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
+ c_register_pragma_with_early_handler ("GCC", "optimize",
+ handle_pragma_optimize,
+ handle_pragma_optimize);
c_register_pragma_with_early_handler ("GCC", "push_options",
handle_pragma_push_options,
handle_pragma_push_options);
diff --git a/gcc/testsuite/c-c++-common/pragma-optimize-1.c
b/gcc/testsuite/c-c++-common/pragma-optimize-1.c
new file mode 100644
index 00000000000..1446e5aee05
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pragma-optimize-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+/* PR c++/48026 */
+/* Make sure `#pragma GCC optimize` affects the pre-defined macros too */
+
+#pragma GCC optimize ("no-fast-math")
+#ifdef __FAST_MATH__
+# error Hey yo, What you doing on FAST_MATH??
+#endif
diff --git a/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C
b/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C
new file mode 100644
index 00000000000..2f360cf50e1
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */
+#include "../../gcc.target/i386/vect-pragma-target-1.c"
diff --git a/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C
b/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C
new file mode 100644
index 00000000000..b85bc93d845
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */
+#include "../../gcc.target/i386/vect-pragma-target-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c
b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c
new file mode 100644
index 00000000000..f5e71e453ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c
@@ -0,0 +1,194 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */
+#ifndef CHECK_DEFINES
+#define CHECK_DEFINES 0
+#endif
+
+#define N 1024
+
+/* Optimization flags and tree vectorizer shall be disabled at this point */
+#if CHECK_DEFINES && defined(__OPTIMIZE__)
+#error "__OPTIMIZE__ is defined (not compiled with -O0?)"
+#endif
+
+#pragma GCC push_options
+#pragma GCC optimize ("O2", "tree-vectorize")
+
+/* Optimization flags and tree vectorizer shall be enabled at this point */
+#if CHECK_DEFINES && !defined(__OPTIMIZE__)
+#error "__OPTIMIZE__ is not defined"
+#endif
+
+#pragma GCC push_options
+#pragma GCC target ("sse4.2")
+#ifdef __cplusplus
+namespace {
+#endif
+
+/* Target flags up to including SSE4.2 shall be enabled at this point */
+#if CHECK_DEFINES && !defined(__SSE3__)
+#error "Target flag (SSE3) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSSE3__)
+#error "Target flag (SSSE3) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSE4_1__)
+#error "Target flag (SSE4.1) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSE4_2__)
+#error "Target flag (SSE4.2) is not defined"
+#endif
+
+void
+__attribute__((__noinline__, __used__))
+vec_saxpy_i32(int y[N], const int a[N], const int x[N])
+{
+ int i;
+ for (i = 0; i < N; i++)
+ y[i] += a[i] * x[i];
+}
+
+#ifdef __cplusplus
+}
+#endif
+#pragma GCC pop_options
+
+/* Target flags up to including SSE4.2 shall be disabled at this point */
+#if CHECK_DEFINES && defined(__SSE3__)
+#error "Target flag (SSE3) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSSE3__)
+#error "Target flag (SSSE3) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSE4_1__)
+#error "Target flag (SSE4.1) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSE4_2__)
+#error "Target flag (SSE4.2) is still defined"
+#endif
+
+#pragma GCC push_options
+#pragma GCC target ("avx2", "fma")
+#ifdef __cplusplus
+struct A {
+#endif
+
+/* Target flags up to including AVX2+FMA shall be enabled at this point */
+#if CHECK_DEFINES && !defined(__SSE3__)
+#error "Target flag (SSE3) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSSE3__)
+#error "Target flag (SSSE3) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSE4_1__)
+#error "Target flag (SSE4.1) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__SSE4_2__)
+#error "Target flag (SSE4.2) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__AVX__)
+#error "Target flag (AVX) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__AVX2__)
+#error "Target flag (AVX2) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__FMA__)
+#error "Target flag (FMA) is not defined"
+#endif
+
+void
+__attribute__((__noinline__, __used__))
+vec_saxpy_f32(float y[N], const float a[N], const float x[N])
+{
+ int i;
+ for (i = 0; i < N; i++)
+ y[i] += a[i] * x[i];
+}
+
+#ifdef __cplusplus
+};
+#endif
+#pragma GCC pop_options
+
+/* Target flags up to including AVX2+FMA shall be disabled at this point */
+#if CHECK_DEFINES && defined(__SSE3__)
+#error "Target flag (SSE3) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSSE3__)
+#error "Target flag (SSSE3) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSE4_1__)
+#error "Target flag (SSE4.1) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__SSE4_2__)
+#error "Target flag (SSE4.2) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__AVX__)
+#error "Target flag (AVX) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__AVX2__)
+#error "Target flag (AVX2) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__FMA__)
+#error "Target flag (FMA) is still defined"
+#endif
+
+#pragma GCC push_options
+#pragma GCC target ("arch=x86-64-v4")
+#ifdef __cplusplus
+namespace avx512 {
+struct A {
+#endif
+
+/* Essential AVX512 target flags shall be enabled at this point */
+#if CHECK_DEFINES && !defined(__AVX512F__)
+#error "Target flag (AVX512F) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__AVX512VL__)
+#error "Target flag (AVX512VL) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__AVX512DQ__)
+#error "Target flag (AVX512DQ) is not defined"
+#endif
+#if CHECK_DEFINES && !defined(__AVX512BW__)
+#error "Target flag (AVX512BW) is not defined"
+#endif
+
+void
+__attribute__((__noinline__, __used__))
+vec_saxpy_i16(short y[N], const short a[N], const short x[N])
+{
+ int i;
+ for (i = 0; i < N; i++)
+ y[i] += a[i] * x[i];
+}
+
+#ifdef __cplusplus
+};
+}
+#endif
+#pragma GCC pop_options
+
+/* Essential AVX512 target flags shall be disabled at this point */
+#if CHECK_DEFINES && defined(__AVX512F__)
+#error "Target flag (AVX512F) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__AVX512VL__)
+#error "Target flag (AVX512VL) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__AVX512DQ__)
+#error "Target flag (AVX512DQ) is still defined"
+#endif
+#if CHECK_DEFINES && defined(__AVX512BW__)
+#error "Target flag (AVX512BW) is still defined"
+#endif
+
+#pragma GCC pop_options
+
+/* Optimization flags and tree vectorizer shall be disabled at this point */
+#if CHECK_DEFINES && defined(__OPTIMIZE__)
+#error "__OPTIMIZE__ is still defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c
b/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c
new file mode 100644
index 00000000000..349680453a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */
+/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */
+#define CHECK_DEFINES 1
+#include "vect-pragma-target-1.c"