Tested on x86_64-pc-linux-gnu with --enable-languages=c,c++ -- >8 --
Handle '#pragma GCC optimize' earlier as the __OPTIMIZE__ macro may need to be defined as well for certain usages. This is a follow-up to r14-4967-g8697d3a1. Also add more tests for the '#pragma GCC target' case with auto-vectorization enabled and multiple combinations of namespaces and/or class member functions. gcc/c-family/ChangeLog: PR c++/48026 * c-pragma.cc (init-pragma): Register `#pragma GCC optimize' in preprocess-only mode, and enable early handling. gcc/testsuite/ChangeLog: PR c++/48026 PR c++/41201 * 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-1.c: New test. Signed-off-by: Gwenole Beauchesne <gb.de...@gmail.com> --- gcc/c-family/c-pragma.cc | 4 +- .../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 + 5 files changed, 216 insertions(+), 1 deletion(-) 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 849f8ac8c8b..26d4c0c71e0 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -1852,7 +1852,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/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" -- 2.39.2