diff options
Diffstat (limited to 'gcc/testsuite')
220 files changed, 10437 insertions, 762 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28f918a4324..1560c27c25d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,392 @@ +2011-11-07 Dodji Seketeli <dodji@redhat.com> + + Support C++11 alias-declaration + PR c++/45114 + * g++.dg/cpp0x/alias-decl-0.C: New test case. + * g++.dg/cpp0x/alias-decl-1.C: Likewise. + * g++.dg/cpp0x/alias-decl-3.C: Likewise. + * g++.dg/cpp0x/alias-decl-4.C: Likewise. + * g++.dg/cpp0x/alias-decl-6.C: Likewise. + * g++.dg/cpp0x/alias-decl-7.C: Likewise. + * g++.dg/cpp0x/alias-decl-8.C: Likewise. + * g++.dg/cpp0x/alias-decl-9.C: Likewise. + * g++.dg/cpp0x/alias-decl-10.C: Likewise. + * g++.dg/ext/alias-decl-attr1.C: Likewise. + * g++.dg/ext/alias-decl-attr2.C: Likewise. + * g++.dg/ext/alias-decl-attr3.C: Likewise. + * g++.dg/ext/alias-decl-attr4.C: Likewise. + +2011-11-07 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/pragma-align-2.c: Compile with -std=gnu99. + +2011-11-07 Janus Weil <janus@gcc.gnu.org> + + PR fortran/50919 + * gfortran.dg/typebound_call_21.f03: New. + +2011-11-07 Nathan Sidwell <nathan@acm.org> + + * gcc.dg/profile-dir-1.c: Adjust final scan. + * gcc.dg/profile-dir-2.c: Adjust final scan. + * gcc.dg/profile-dir-3.c: Adjust final scan. + * gcc.misc-tests/gcov.exp: Adjust regexp. + * gcc.misc-tests/gcov-12.c: New. + * gcc.misc-tests/gcov-13.c: New. + * gcc.misc-tests/gcovpart-13b.c: New. + * gcc.misc-tests/gcov-14.c: New. + +2011-11-07 Jason Merrill <jason@redhat.com> + + PR c++/35688 + * g++.dg/ext/visibility/template8.C: New. + +2011-11-07 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50789 + * gcc.target/i386/avx2-gather-1.c: New test. + * gcc.target/i386/avx2-gather-2.c: New test. + * gcc.target/i386/avx2-gather-3.c: New test. + * gcc.target/i386/avx2-gather-4.c: New test. + +2011-11-07 Uros Bizjak <ubizjak@gmail.com> + + * gcc.target/i386/pr49781-1.c (dg-options): Add -mtune=generic. + +2011-11-07 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/45723 + * gfortran.dg/open_dev_null.f90: Remove testcase. + +2011-11-07 Uros Bizjak <ubizjak@gmail.com> + + * lib/target-supports.exp (check_effective_target_sync_int_128): + Don't cache the result. + (check_effective_target_sync_long_long): Ditto. + +2011-11-07 Sergey Ostanevich <sergos.gnu@gmail.com> + + PR rtl-optimization/47698 + * gcc.target/i386/47698.c: New test. + +2011-11-06 Jason Merrill <jason@redhat.com> + + PR c++/35688 + * g++.dg/ext/visibility/template7.C: New. + +2011-11-07 Terry Guo <terry.guo@arm.com> + + * gcc.target/arm/wmul-1.c: Adjust optimization level. + * gcc.target/arm/wmul-2.c: Ditto. + * gcc.target/arm/wmul-3.c: Ditto. + * gcc.target/arm/wmul-4.c: Ditto. + +2011-11-06 Joseph Myers <joseph@codesourcery.com> + + * g++.dg/cpp0x/alignof3.C, gcc.dg/c1x-align-1.c, + gcc.dg/c1x-align-2.c, gcc.dg/c1x-align-3.c, gcc.dg/c1x-align-4.c, + gcc.dg/c90-align-1.c, gcc.dg/c99-align-1.c: New tests. + * gcc.dg/gnu89-const-expr-1.c, gcc.dg/gnu90-const-expr-1.c, + gcc.dg/gnu99-const-expr-1.c, gcc.dg/gnu99-static-1.c: Update + expected diagnostics. + +2011-11-06 Andrew MacLeod <amacleod@redhat.com> + Richard Henderson <rth@redhat.com> + Aldy Hernandez <aldyh@redhat.com> + + Merged from cxx-mem-model. + + * lib/target-supports.exp (check_effective_target_sync_int_128, + check_effective_target_sync_long_long): Check whether the target + supports 64 and 128 bit __sync builtins. + (check_effective_target_cas_char): New. + (check_effective_target_cas_int): New. + * gcc.dg/dg.exp: Exclude simulate-thread tests. + * gcc.dg/atomic-noinline[-aux].c: New. Make a variety of atomics calls. + * gcc.dg/atomic-generic[-aux].c: New. Test that generic functions + produce the expected library calls. + * gcc.dg/atomic-fence.c: New functional tests. + * gcc.dg/atomic-param.c: New. Checl for illegal number of parameters. + * gcc.dg/atomic-invalid.c: New. Test invalid parameters. + * gcc.dg/atomic-lockfree[-aux].c: New tests. + * gcc.dg/atomic-compare-exchange-{1-5}.c: New functional tests. + * gcc.dg/atomic-op-[1-5].c: New. Test atomic fetch functionality. + * gcc.dg/atomic-exchange-{1-5}.c: New functional tests. + * gcc.dg/atomic-load-{1-5}.c: New functional tests. + * gcc.dg/atomic-store-{1-5}.c: New functional tests. + * gcc.dg/simulate-thread/atomic-load-int128.c: New. Verify int128 loads + are atomic. + * gcc.dg/simulate-thread/atomic-load-longlong.c: New. Verify 8 byte + loads are atomic. + * gcc.dg/simulate-thread/atomic-load-int.c: New. Verify 4 byte loads + are atomic. + * gcc.dg/simulate-thread/atomic-load-short.c: New. Verify 2 byte loads + are atomic. + * gcc.dg/simulate-thread/atomic-other-int128.c: New. Verify other + int128 operations are atomic. + * gcc.dg/simulate-thread/atomic-other-int.c: New. Verify other 4 byte + operations are atomic. + * gcc.dg/simulate-thread/atomic-other-longlong.c: New. Verify 8 byte + operations are atomic. + * gcc.dg/simulate-thread/atomic-other-short.c: New. Verify other 2 byte + operations are atomic. + * gcc.dg/simulate-thread/speculative-store.c: New. Verify speculative + stores aren't moved out of a loop. + * gcc.dg/simulate-thread/strict-align-global.c: New. Verify small + globals don't overwrite neighbouring globals. + * gcc.dg/simulate-thread/subfields.c: New. Verify struct component + writes dont overwrite neighbouring components. + * c-c++-common/gomp/atomic-10.c: Use cas_int; match __atomic builtin. + * c-c++-common/gomp/atomic-3.c: Likewise. + * c-c++-common/gomp/atomic-9.c: Likewise. + * gcc.dg/gomp/atomic-1.c, gcc.dg/gomp/atomic-2.c, + gcc.dg/gomp/atomic-3.c, gcc.dg/gomp/atomic-4.c, gcc.dg/gomp/atomic-7.c, + gcc.dg/gomp/atomic-8.c, gcc.dg/gomp/atomic-9.c, + gcc.dg/gomp/atomic-10.c, gcc.dg/gomp/atomic-12.c, + gcc.dg/gomp/atomic-13.c, gcc.dg/gomp/atomic-14.c, + gcc.dg/gomp/atomic-15.c: Move to c-c++-common/gomp/. + * g++.dg/gomp/atomic-1.C, g++.dg/gomp/atomic-2.C, + g++.dg/gomp/atomic-3.C, g++.dg/gomp/atomic-4.C, g++.dg/gomp/atomic-7.C, + g++.dg/gomp/atomic-8.C, g++.dg/gomp/atomic-9.C, + g++.dg/gomp/atomic-10.C, g++.dg/gomp/atomic-11.C, + g++.dg/gomp/atomic-12.C, g++.dg/gomp/atomic-13.C, + g++.dg/gomp/atomic-15.C: Remove. + * gcc.dg/gomp/gomp.exp, g++.dg/gomp/gomp.exp: Run c-c++-common tests. + * gcc.dg/gomp/atomic-11.c: Remove test. + +2011-11-06 Ira Rosen <ira.rosen@linaro.org> + + * gcc.dg/vect/bb-slp-cond-1.c: New test. + * gcc.dg/vect/slp-cond-1.c: New test. + * gcc.dg/vect/slp-cond-2.c: New test. + +2011-11-05 David S. Miller <davem@davemloft.net> + + * lib/test-supports.exp + (check_effective_target_ultrasparc_vis2_hw): New proc. + (check_effective_target_ultrasparc_vis3_hw): New proc. + * gcc.target/sparc/vec-init-1.inc: New vector init common code. + * gcc.target/sparc/vec-init-2.inc: Likewise. + * gcc.target/sparc/vec-init-3.inc: Likewise. + * gcc.target/sparc/vec-init-1-vis1.c: New test. + * gcc.target/sparc/vec-init-1-vis2.c: New test. + * gcc.target/sparc/vec-init-1-vis3.c: New test. + * gcc.target/sparc/vec-init-2-vis1.c: New test. + * gcc.target/sparc/vec-init-2-vis2.c: New test. + * gcc.target/sparc/vec-init-2-vis3.c: New test. + * gcc.target/sparc/vec-init-3-vis1.c: New test. + * gcc.target/sparc/vec-init-3-vis2.c: New test. + * gcc.target/sparc/vec-init-3-vis3.c: New test. + +2011-11-05 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.c-torture/execute/ieee/mul-subnormal-single-1.x: + Disable test on Epiphany. + * gcc.c-torture/execute/20101011-1.c: Disable test on Epiphany. + * gcc.dg/stack-usage-1.c [__epiphany__] (SIZE): Define. + * gcc.dg/pragma-pack-3.c: Disable test on Epiphany. + * g++.dg/parse/pragma3.C: Likewise. + * stackalign/builtin-apply-2.c (STACK_ARGUMENTS_SIZE): Define. + (bar): Use it. + * gcc.dg/weak/typeof-2.c [epiphany-*-*]: Add option -mshort-calls. + * gcc.dg/tls/thr-cse-1.c: Likewise. + * g++.dg/opt/devirt2.C: Likewise. + * gcc.dg/20020312-2.c [epiphany-*-*] (PIC_REG): Define. + * gcc.dg/builtin-apply2.c [__epiphany__]: (STACK_ARGUMENTS_SIZE): 20. + * gcc.target/epiphany: New directory. + +2011-11-05 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/quad_2.f90: New. + +2011-11-05 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/strlenopt-22g.c: New wrapper around... + * gcc.dg/strlenopt-22.c: ...this. Do not define USE_GNU and adjust. + +2011-11-04 Jason Merrill <jason@redhat.com> + + PR c++/26714 + * g++.dg/init/lifetime2.C: New. + * g++.dg/cpp0x/initlist-lifetime2.C: New. + + PR c++/48370 + * g++.dg/init/lifetime1.C: Test cleanup order. + +2011-11-04 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/other/offsetof7.C: New test. + +2011-11-04 Hans-Peter Nilsson <hp@axis.com> + + * lib/gcc-dg.exp (gcc_force_conventional_output): New global + variable, default empty, -ffat-lto-objects for effective_target_lto. + (gcc-dg-test-1): Add options from dg-final methods. + * lib/scanasm.exp (scan-assembler_required_options) + (scan-assembler-not_required_options): New procs. + +2011-10-09 Magnus Fromreide <magfr@lysator.liu.se> + + * g++.dg/cpp0x/enum21a.C: Test that enum x { y, } does + generate a pedwarn in c++98-mode. + * g++.dg/cpp0x/enum21b.C: Test that enum x { y, } + don't generate a pedwarn in c++0x-mode. + +2011-11-04 Olivier Goffart <olivier@woboq.com> + + PR c++/50965 + * g++.dg/cpp0x/nsdmi1.C: Add more cases. + +2011-11-04 Jiangning Liu <jiangning.liu@arm.com> + + PR rtl-optimization/38644 + * gcc.target/arm/stack-red-zone.c: New. + +2011-11-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/48420 + * g++.dg/warn/Wconversion-null-3.C: New. + +2011-11-04 Ed Smith-Rowland <3dw4rd@verizon.net> + + PR c++/50941 + * g++.dg/cpp0x/udlit-strint-length.C: New. + +2011-11-04 Jason Merrill <jason@redhat.com> + + PR c++/48370 + * g++.dg/cpp0x/initlist-lifetime1.C: New. + * g++.dg/init/lifetime1.C: New. + * g++.dg/init/ref21.C: New. + * g++.dg/eh/array1.C: New. + +2011-11-04 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50763 + * gcc.dg/pr50763-5.c: New test. + +2011-11-04 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50763 + * g++.dg/pr50763-4.C: New test. + +2011-11-04 Jakub Jelinek <jakub@redhat.com> + + * gcc.dg/torture/vec-cvt-1.c: Enable commented out inttoflttestui + test. + + * gcc.dg/torture/vec-cvt-1.c: Enable flttointtestui test. + + * gcc.dg/torture/vec-cvt-1.c: New test. + +2011-11-04 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/specs/private1[-sub].ads: New test. + +2011-11-04 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/43829 + * gfortran.dg/function_optimize_7.f90: Disable sum inlining. + * gfortran.dg/inline_sum_1.f90: New. + * gfortran.dg/inline_sum_2.f90: New. + * gfortran.dg/inline_sum_bounds_check_1.f90: New. + * gfortran.dg/inline_sum_bounds_check_2.f90: New. + * gfortran.dg/inline_product_1.f90: New. + +2011-11-03 Tobias Burnus <burnus@net-b.de> + + PR fortran/50933 + * gfortran.dg/bind_c_dts_5.f90: New. + +2011-11-03 Tobias Burnus <burnus@net-b.de> + + PR fortran/50960 + * gfortran.dg/module_parameter_array_refs_2.f90: New. + +2011-11-03 Richard Guenther <rguenther@suse.de> + + PR middle-end/50079 + * g++.dg/init/copy7.C: Remove testcase. + +2011-11-03 Martin Jambor <mjambor@suse.cz> + + * g++.dg/ipa/devirt-c-1.C: Add dump scans. + * g++.dg/ipa/devirt-c-2.C: Likewise. + * g++.dg/ipa/devirt-c-7.C: New test. + * g++.dg/ipa/devirt-c-8.C: Likewise. + +2011-11-03 Ira Rosen <ira.rosen@linaro.org> + + PR tree-optimization/50912 + * gnat.dg/loop_optimization10.ad[sb]: New test. + * gnat.dg/loop_optimization10_pkg.ads: New helper. + +2011-11-02 Jason Merrill <jason@redhat.com> + + PR c++/50930 + * g++.dg/cpp0x/nsdmi-list2.C: New. + +2011-11-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/50810 + * g++.dg/cpp0x/warn_cxx0x2.C: New. + * g++.dg/cpp0x/warn_cxx0x3.C: Likewise. + +2011-11-02 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50769 + * gfortran.dg/pr50769.f90: New test. + +2011-11-02 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.target/sparc/20111102-1.c: New test. + +2011-11-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/50956 + * g++.dg/warn/Wcast-qual2.C: New. + +2011-11-02 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50763 + * g++.dg/pr50763-3.C: New test. + +2011-11-02 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50672 + * g++.dg/pr50672.C: New test. + +2011-11-02 Uros Bizjak <ubizjak@gmail.com> + + * gcc.target/i386/avx-cvt-2.c (dg-options): Add -mtune=generic. + * gcc.target/i386/avx2-cvt-2.c (dg-options): Ditto. + * gcc.target/i386/sse2-cvt-2.c (dg-options): Ditto. + + * gcc.target/i386/vectorize4-avx.c (scan-assembler): Remove xfail. + +2011-11-02 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/50902 + * gcc.dg/torture/pr50902.c: New testcase. + +2010-11-02 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/50890 + * gcc.dg/torture/pr50890.c: New testcase. + +2011-11-01 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44277 + * g++.dg/warn/Wzero-as-null-pointer-constant-1.C: New. + * g++.dg/cpp0x/Wzero-as-null-pointer-constant-1.C: Likewise. + +2011-11-01 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50908 + * gcc.dg/pr50908.c: New test. + * gcc.dg/pr50908-2.c: Same. + * gcc.dg/pr50908-3.c: Same. + 2011-11-01 Ira Rosen <ira.rosen@linaro.org> * gcc.dg/vect/no-scevccp-outer-6-global.c: Expect to vectorize @@ -62,7 +451,7 @@ 2011-10-28 Paolo Carlini <paolo.carlini@oracle.com> Revert: - 2011-10-28 Paolo Carlini <paolo.carlini@oracle.com> + 2011-10-28 Paolo Carlini <paolo.carlini@oracle.com> PR c++/50864 * g++.dg/template/crash109.C: New. diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-1.c b/gcc/testsuite/c-c++-common/gomp/atomic-1.c index 3e4bc569ba7..3e4bc569ba7 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-1.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-1.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-10.c b/gcc/testsuite/c-c++-common/gomp/atomic-10.c index 936d0c1f223..21d035e15c9 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-10.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-10.c @@ -1,6 +1,7 @@ /* PR middle-end/28046 */ /* { dg-do compile } */ /* { dg-options "-fopenmp -fdump-tree-ompexp" } */ +/* { dg-require-effective-target cas_int } */ int a[3], b; struct C { int x; int y; } c; @@ -20,5 +21,5 @@ foo (void) *baz () += bar (); } -/* { dg-final { scan-tree-dump-times "__sync_fetch_and_add" 4 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "__atomic_fetch_add" 4 "ompexp" } } */ /* { dg-final { cleanup-tree-dump "ompexp" } } */ diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-12.c b/gcc/testsuite/c-c++-common/gomp/atomic-12.c index 618c4c8e648..618c4c8e648 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-12.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-12.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-13.c b/gcc/testsuite/c-c++-common/gomp/atomic-13.c index 0146825f2bb..0146825f2bb 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-13.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-13.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-14.c b/gcc/testsuite/c-c++-common/gomp/atomic-14.c index f8fc9d87257..f8fc9d87257 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-14.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-14.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-15.c b/gcc/testsuite/c-c++-common/gomp/atomic-15.c index 13a9e0ce48a..13a9e0ce48a 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-15.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-15.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-2.c b/gcc/testsuite/c-c++-common/gomp/atomic-2.c index 720ec9e8ba0..720ec9e8ba0 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-2.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-2.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-3.c b/gcc/testsuite/c-c++-common/gomp/atomic-3.c index 7ea792d3457..5b9e60cde8b 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-3.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-3.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp -fdump-tree-ompexp" } */ +/* { dg-require-effective-target cas_int } */ int *xyzzy; @@ -9,5 +10,5 @@ void f1(void) xyzzy++; } -/* { dg-final { scan-tree-dump-times "xyzzy, 4" 1 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "xyzzy, 4" 1 "ompexp" } } */ /* { dg-final { cleanup-tree-dump "ompexp" } } */ diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-4.c b/gcc/testsuite/c-c++-common/gomp/atomic-4.c index 7f27370d535..7f27370d535 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-4.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-4.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-7.c b/gcc/testsuite/c-c++-common/gomp/atomic-7.c index 612e97f4530..612e97f4530 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-7.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-7.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-8.c b/gcc/testsuite/c-c++-common/gomp/atomic-8.c index 2f04151f0ed..2f04151f0ed 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-8.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-8.c diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-9.c b/gcc/testsuite/c-c++-common/gomp/atomic-9.c index 2fafbd4097a..ff5cb4091f9 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-9.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-9.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp -fdump-tree-ompexp" } */ +/* { dg-require-effective-target cas_int } */ volatile int *bar(void); @@ -9,5 +10,5 @@ void f1(void) *bar() += 1; } -/* { dg-final { scan-tree-dump-times "__sync_fetch_and_add" 1 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "__atomic_fetch_add" 1 "ompexp" } } */ /* { dg-final { cleanup-tree-dump "ompexp" } } */ diff --git a/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-1.C b/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-1.C new file mode 100644 index 00000000000..aad273792ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-1.C @@ -0,0 +1,161 @@ +// { dg-options "-std=c++0x -Wzero-as-null-pointer-constant" } + +struct A; + +typedef int (A::*pointmemfun) (int); +typedef int (A::*pointdmem); +typedef int (*pointfun) (int); + +pointmemfun pmfs; +pointdmem pdms; +pointfun pfs; +int* ps; + +void f() +{ + pointmemfun pmf(0); // { dg-warning "zero as null pointer" } + pointdmem pdm(0); // { dg-warning "zero as null pointer" } + pointfun pf(0); // { dg-warning "zero as null pointer" } + int* p(0); // { dg-warning "zero as null pointer" } + + pointmemfun pmfn(nullptr); + pointdmem pdmn(nullptr); + pointfun pfn(nullptr); + int* pn(nullptr); + + pmf = 0; // { dg-warning "zero as null pointer" } + + pdm = 0; // { dg-warning "zero as null pointer" } + + pf = 0; // { dg-warning "zero as null pointer" } + + p = 0; // { dg-warning "zero as null pointer" } + + pmf = nullptr; + + pdm = nullptr; + + pf = nullptr; + + p = nullptr; + + if (pmf) + ; + + if (pdm) + ; + + if (pf) + ; + + if (p) + ; + + if (!pmf) + ; + + if (!pdm) + ; + + if (!pf) + ; + + if (!p) + ; + + if (pmf == 0) // { dg-warning "zero as null pointer" } + ; + + if (pdm == 0) // { dg-warning "zero as null pointer" } + ; + + if (pf == 0) // { dg-warning "zero as null pointer" } + ; + + if (p == 0) // { dg-warning "zero as null pointer" } + ; + + if (0 == pmf) // { dg-warning "zero as null pointer" } + ; + + if (0 == pdm) // { dg-warning "zero as null pointer" } + ; + + if (0 == pf) // { dg-warning "zero as null pointer" } + ; + + if (0 == p) // { dg-warning "zero as null pointer" } + ; + + if (pmf != 0) // { dg-warning "zero as null pointer" } + ; + + if (pdm != 0) // { dg-warning "zero as null pointer" } + ; + + if (pf != 0) // { dg-warning "zero as null pointer" } + ; + + if (p != 0) // { dg-warning "zero as null pointer" } + ; + + if (0 != pmf) // { dg-warning "zero as null pointer" } + ; + + if (0 != pdm) // { dg-warning "zero as null pointer" } + ; + + if (0 != pf) // { dg-warning "zero as null pointer" } + ; + + if (0 != p) // { dg-warning "zero as null pointer" } + ; + + if (pmf == nullptr) + ; + + if (pdm == nullptr) + ; + + if (pf == nullptr) + ; + + if (p == nullptr) + ; + + if (nullptr == pmf) + ; + + if (nullptr == pdm) + ; + + if (nullptr == pf) + ; + + if (nullptr == p) + ; + + if (pmf != nullptr) + ; + + if (pdm != nullptr) + ; + + if (pf != nullptr) + ; + + if (p != nullptr) + ; + + if (nullptr != pmf) + ; + + if (nullptr != pdm) + ; + + if (nullptr != pf) + ; + + if (nullptr != p) + ; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C new file mode 100644 index 00000000000..c5760cfe537 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C @@ -0,0 +1,37 @@ +// { dg-options "-std=c++0x" } + +template<template<class> class TT> struct X { }; +template<class> struct Y { }; +template<class T> using Z = Y<T>; + +void f(X<Y>); +void g(X<Z>); + +void +foo() +{ + // Below x and y don't have the same type, because Y and Z don't + // designate the same template ... + X<Y> y; + X<Z> z; + + // ... So these must fail to compile. + f(z); // { dg-error "" } + g(y); // { dg-error "" } +} + +template<class> struct A0 {}; +template<class T> using AA0 = A0<T>; +template<class T> using AAA0 = AA0<T>; + +void f0(A0<int>); +void +g0() +{ + AA0<int> a; + AAA0<int> b; + f0(a); + f0(b); +} + + diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C new file mode 100644 index 00000000000..d0eda5ff1b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C @@ -0,0 +1,15 @@ +// { dg-options "-std=c++0x" } + +// These also represent tests for printing alias declarations and +// their instantiations. + +template<class T, class U> struct A0 {}; +template<class T, class U> using AA0 = A0<T, U>; +template<class T> struct AA0<int, T> {}; // { dg-error "partial specialization" } + +template <class U> using Ptr = U*; +template<class U> struct Ptr<U*> {}; // { dg-error "partial specialization" } + +struct A { + using A = int;//{ dg-error "nested|has|same name as|class|in which|declared" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C new file mode 100644 index 00000000000..856e4297af5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C @@ -0,0 +1,18 @@ +// { dg-options "-std=c++0x" } + +template <class T> using Ptr = T*; +Ptr<unsigned>; // { dg-error "does not declare anything" } +Ptr<char><int>; // { dg-error "not a template|does not declare anything" } +template class Ptr<int>;//{ dg-error "explicit instantiation|non-class templ|does not decl|anything" } + +template <class T> using Arg = T; +struct A {}; +template class Arg<A>;// { dg-error "explicit instantiation|non-class templ" } + +template <template <class> class TT, class T> using Instantiate = TT<T>; +template <class> struct Vector {}; +template class Instantiate<Vector, int>; // OK Vector<int> can be explicitely instantiated + +template <class T> struct S {}; +template<class T> using SFor = S<T>; +template class SFor<int>; // OK, S<int> can be explicitely instantiated diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C new file mode 100644 index 00000000000..2e03dd897b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C @@ -0,0 +1,33 @@ +// { dg-options "-std=c++0x" } + +template<class T> struct S0 {}; +template<class T> using AS0 = S0<T>; + +template<template<class> class TT> +void f(TT<int>); + +template class AS0<char>; + +void +foo() +{ + AS0<int> a; + f(a); +} + +template<class T, class U> struct Vector{}; +template<class T> struct Alloc {}; + +template<class T> using Vec = Vector<T, Alloc<T> >; + +template<class T> void g(Vector<T, Alloc<T> >); + +template<template<class T> class TT> void h(TT<int>); // { dg-error "provided for" } + +void +bar() +{ + Vec<int> a; + g(a); + h(a); // { dg-error "no matching function|wrong number of template arguments" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-3.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-3.C new file mode 100644 index 00000000000..5484efce19e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-3.C @@ -0,0 +1,42 @@ +// { dg-options "-std=c++0x" } + +// Exercise some member alias templates ... + +template<class T, class U> class A0 {}; + +template<class T> +struct A1 { + template<class U> struct S {}; + template<class U> using AA0 = A0<T, U>; + + void f(A0<T, int>); + + void + foo() + { + AA0<int> a; + const AA0<int> b; + f(a); + f(b); + } +}; + +void +bar() +{ + A1<int> a1; + a1.foo(); + A1<int>::AA0<int> a1aa0; + a1.f(a1aa0); +} + +// ... some simple member alias ... +struct B { + using A = int; +}; + +B::A a; + +// ... and some simple alias + +using Int = int; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-4.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-4.C new file mode 100644 index 00000000000..876944e23c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-4.C @@ -0,0 +1,14 @@ +// { dg-options "-std=c++0x" } + +// [temp.alias]/3: +// The type-id in an alias template declaration shall not refer +// to the alias template being declared. The type produced by an +// alias template specialization shall not directly or indirectly +// make use of that specialization. + +template <class T> struct A; +template <class T> using B = typename A<T>::U; // { dg-error "type" } +template <class T> struct A { + typedef B<T> U; +}; +B<short> b; // { dg-error "invalid type" } diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-5.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-5.C new file mode 100644 index 00000000000..1a4cbd5e5bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-5.C @@ -0,0 +1,34 @@ +// { dg-options "-std=c++0x" } + +// alias template of a partial specialization + +template<class T, class U, class W> struct S0 {}; +template<class T, class U> struct S0<T, U, char> {}; +template<class T> using AS0 = S0<T, int, char>; +void foo(S0<bool, int, char>); + +AS0<bool> a; // OK + +void +f() +{ + foo(a); //OK +} + +// alias template of an explicit specialization of a member template + +template<class T> +struct S1 { + template<class U> + struct M {}; +}; +template<class T> using AM = S1<int>::M<T>; +void bar(S1<int>::M<bool>); + +AM<bool> b; //OK. + +void +g() +{ + bar(b); //OK +} diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-6.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-6.C new file mode 100644 index 00000000000..f60b2ea7fc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-6.C @@ -0,0 +1,12 @@ +// { dg-options "-std=c++0x" } + +// Alias template of non-class types. + +template <class T, class U> struct same; +template <class T> struct same<T,T> {}; + +template <class T> using Ptr = T*; +template <template <class> class T> struct A { + template <class U> using X = T<U>; +}; +same<A<Ptr>::X<int>,int*> s; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-7.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-7.C new file mode 100644 index 00000000000..96c349a0da6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-7.C @@ -0,0 +1,23 @@ +// { dg-options "-std=c++0x" } + +// Add arguments to unbound template template parameter. + +template <template <class> class Template> +struct Internal { + template <class Arg> using Bind = Template<Arg>; +}; + +template <template <class> class Template, class Arg> +using Instantiate = Template<Arg>; // After parsing #1, the + // BOUND_TEMPLATE_TEMPLATE_PARM + // parameter Template gets + // the UNBOUND_CLASS_TEMPLATE + // Internal<Template>::template Bind + // as an argument, and the + // parameter Arg gets Argument as + // an argument. And we build + // 'Bind<Argument>'. + +template <template <class> class Template, class Argument> +using Bind = Instantiate<Internal<Template>::template Bind, Argument>; //#1 + diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-8.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-8.C new file mode 100644 index 00000000000..c926df7539b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-8.C @@ -0,0 +1,32 @@ +// { dg-options "-std=c++0x" } + +struct A { + template <class U> using C = U; +}; + +// The particularity of the below struct is to have more than 7 +// fields. In this case, looking up a member here should exercise +// cp/search.c:lookup_field_1 in such a way that it finds it in the +// CLASSTYPE_SORTED_FIELDS of struct A7. +struct A7 { + int f0; + int f1; + int f2; + int f3; + int f4; + int f5; + int f6; + int f7; + template <class U> using C = U; +}; + +template <class T> +struct B { + typename T::template C<int> n; //#0 +}; + +// These should trigger the lookup +// of template C inside class A or +// A7, via #0. +B<A> b; +B<A7> c; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-9.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-9.C new file mode 100644 index 00000000000..dcf642d7683 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-9.C @@ -0,0 +1,9 @@ +// { dg-options "-std=c++0x" } + +template <class T> +struct A { + using Result = T; +}; +template <class A> using Arg = typename A::Result; +Arg<A<int>> b; + diff --git a/gcc/testsuite/g++.dg/cpp0x/alignof3.C b/gcc/testsuite/g++.dg/cpp0x/alignof3.C new file mode 100644 index 00000000000..50c6ac915e1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alignof3.C @@ -0,0 +1,6 @@ +// { dg-do compile } +// { dg-options "-std=c++0x -pedantic" } +int main(void) +{ + alignof(void (void)); // { dg-warning "function type" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/auto1.C b/gcc/testsuite/g++.dg/cpp0x/auto1.C index 9e274b62239..f5c0ea6e4d3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto1.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto1.C @@ -1,8 +1,8 @@ -// { dg-options "-std=c++98 -Wc++0x-compat" } +// { dg-options "-std=c++98 -Wc++11-compat" } -// Test warning for use of auto in C++98 mode with C++0x +// Test warning for use of auto in C++98 mode with C++11 // compatibility warnings void f() { - auto int x = 5; // { dg-warning "will change meaning" } + auto int x = 5; // { dg-warning "changes meaning" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/bracket3.C b/gcc/testsuite/g++.dg/cpp0x/bracket3.C index 4ef7a0e9d30..f86aa041a24 100644 --- a/gcc/testsuite/g++.dg/cpp0x/bracket3.C +++ b/gcc/testsuite/g++.dg/cpp0x/bracket3.C @@ -1,10 +1,10 @@ -// { dg-options "-std=c++98 -Wc++0x-compat" } +// { dg-options "-std=c++98 -Wc++11-compat" } template<int N> struct X {}; -X<1 >> 2> x; // { dg-warning "will be treated as|suggest parentheses" } +X<1 >> 2> x; // { dg-warning "is treated as|suggest parentheses" } // From cp/parser.c typedef int Y; template <int V> struct Foo {}; -Foo<Y () >> 5> r; // { dg-warning "will be treated as|suggest parentheses" } +Foo<Y () >> 5> r; // { dg-warning "is treated as|suggest parentheses" } diff --git a/gcc/testsuite/g++.dg/cpp0x/enum21a.C b/gcc/testsuite/g++.dg/cpp0x/enum21a.C new file mode 100644 index 00000000000..5526811a635 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum21a.C @@ -0,0 +1,4 @@ +// { dg-do compile } +// { dg-options "-pedantic -std=c++98" } + +enum x { y, }; // { dg-warning "comma at end of enumerator list" } diff --git a/gcc/testsuite/g++.dg/cpp0x/enum21b.C b/gcc/testsuite/g++.dg/cpp0x/enum21b.C new file mode 100644 index 00000000000..48989128d89 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum21b.C @@ -0,0 +1,4 @@ +// { dg-do compile } +// { dg-options "-pedantic -std=c++0x" } + +enum x { y, }; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime1.C new file mode 100644 index 00000000000..e43ce5d62cd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime1.C @@ -0,0 +1,34 @@ +// Test that we properly extend the lifetime of the initializer_list +// array even if the initializer_list is a subobject. +// { dg-options -std=c++0x } +// { dg-do run } + +#include <initializer_list> + +extern "C" void abort(); +bool ok; + +bool do_throw; + +struct A { + A(int) { if (do_throw) throw 42; } + ~A() { if (!ok) abort(); } +}; + +typedef std::initializer_list<A> AL; +typedef std::initializer_list<AL> AL2; +typedef std::initializer_list<AL2> AL3; + +struct B { + AL al; + const AL& alr; +}; + +int main(int argc, const char** argv) +{ + do_throw = (argc > 1); // always false, but optimizer can't tell + AL ar[] = {{1,2},{3,4}}; + B b = {{5,6},{7,8}}; + AL3 al3 = {{{1},{2},{3}}}; + ok = true; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime2.C new file mode 100644 index 00000000000..16ae1ac6e07 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-lifetime2.C @@ -0,0 +1,64 @@ +// Test that we properly extend the lifetime of the initializer_list +// array even if the initializer_list is a subobject. +// { dg-options -std=c++0x } +// { dg-do run } + +#include <initializer_list> + +extern "C" void abort(); +bool ok; + +bool do_throw; + +struct A { + A(int) { if (do_throw) throw 42; } + ~A() { if (!ok) abort(); } +}; + +typedef std::initializer_list<A> AL; +typedef std::initializer_list<AL> AL2; +typedef std::initializer_list<AL2> AL3; + +struct B { + AL al; + const AL& alr; +}; + +struct A2 +{ + const A& a1; + const A& a2; +}; + +struct C { + AL ar[2]; + B b; + AL3 al3; + A2 a2; + A2 a2r[2]; + C(): + ar{{1,2},{3,4}}, + b{{5,6},{7,8}}, + al3{{{1},{2},{3}}}, + a2{1,2}, + a2r{{1,2},{3,4}} + { ok = true; } +}; + +struct D { + AL ar[2] = {{1,2},{3,4}}; + B b = {{5,6},{7,8}}; + AL3 al3 = {{{1},{2},{3}}}; + A2 a2 = {1,2}; + A2 a2r[2] = {{1,2},{3,4}}; + D() { ok = true; } +}; + +int main(int argc, const char** argv) +{ + do_throw = (argc > 1); // always false, but optimizer can't tell + ok = false; + C c; + ok = false; + D d; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C new file mode 100644 index 00000000000..a6321ffb605 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C @@ -0,0 +1,32 @@ +// PR c++/50930 +// { dg-options -std=c++0x } + +struct nmc { + nmc() = default; + nmc(nmc&&) = delete; // line 3 +}; + +struct A { // line 6 + nmc n{}; + nmc n2 = {}; +} a; // line 8 + +// ------ + +struct lock_t { + int lock[4]; +}; + +struct pthread_mutex_t { + volatile lock_t __spinlock; +}; + +struct mutex { + pthread_mutex_t m = { }; + mutex() = default; +}; + +int main() +{ + mutex mx; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C index f6381d0fdb4..159c16de851 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C @@ -31,8 +31,8 @@ int main() { A a1; if (a1.i != 42) return 1; - A a2 = { 24 }; - if (a2.i != 24) return 2; + A a2{}; + if (a2.i != 42) return 2; A a3[1]; if (a3[0].i != 42) return 3; @@ -43,7 +43,7 @@ int main() C<int,3> c1; if (c1.m != 3) return 5; - C<int,3> c2 { 5 }; + C<int,5> c2 {}; if (c2.m != 5) return 6; D<int,3> d1; diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-string-length.C b/gcc/testsuite/g++.dg/cpp0x/udlit-string-length.C new file mode 100644 index 00000000000..86903e8355a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-string-length.C @@ -0,0 +1,46 @@ +// { dg-options "-std=c++0x" } +// PR c++/50941 + +typedef decltype(sizeof(0)) size_type; + +constexpr size_type +operator"" _len(const char*, size_type len) +{ + return len; +} + +constexpr size_type +operator"" _len(const wchar_t*, size_type len) +{ + return len; +} + +constexpr size_type +operator"" _len(const char16_t*, size_type len) +{ + return len; +} + +constexpr size_type +operator"" _len(const char32_t*, size_type len) +{ + return len; +} + +static_assert( ""_len == 0, "Ouch"); +static_assert(u8""_len == 0, "Ouch"); +static_assert( L""_len == 0, "Ouch"); +static_assert( u""_len == 0, "Ouch"); +static_assert( U""_len == 0, "Ouch"); + +static_assert( "1"_len == 1, "Ouch"); +static_assert(u8"1"_len == 1, "Ouch"); +static_assert( L"1"_len == 1, "Ouch"); +static_assert( u"1"_len == 1, "Ouch"); +static_assert( U"1"_len == 1, "Ouch"); + +static_assert( "123"_len == 3, "Ouch"); +static_assert(u8"123"_len == 3, "Ouch"); +static_assert( L"123"_len == 3, "Ouch"); +static_assert( u"123"_len == 3, "Ouch"); +static_assert( U"123"_len == 3, "Ouch"); diff --git a/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x.C b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x.C index 5ad9b61b83a..5c5eeffb350 100644 --- a/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x.C +++ b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x.C @@ -1,6 +1,6 @@ -// { dg-options "-std=gnu++98 -Wc++0x-compat" } -int static_assert; // { dg-warning "will become a keyword" } -int nullptr; // { dg-warning "will become a keyword" } +// { dg-options "-std=gnu++98 -Wc++11-compat" } +int static_assert; // { dg-warning "is a keyword" } +int nullptr; // { dg-warning "is a keyword" } void foo() { diff --git a/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x2.C b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x2.C new file mode 100644 index 00000000000..116b2331762 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x2.C @@ -0,0 +1,4 @@ +// PR c++/50810 +// { dg-options "-std=gnu++98 -Wc++11-compat" } + +signed char data[] = { 0xff }; // { dg-warning "narrowing" } diff --git a/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x3.C b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x3.C new file mode 100644 index 00000000000..c3df9d99ed3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x3.C @@ -0,0 +1,4 @@ +// PR c++/50810 +// { dg-options "-std=gnu++98 -Wc++11-compat -Wno-narrowing" } + +signed char data[] = { 0xff }; diff --git a/gcc/testsuite/g++.dg/dg.exp b/gcc/testsuite/g++.dg/dg.exp index 0144eef2a4f..ad1f7e23700 100644 --- a/gcc/testsuite/g++.dg/dg.exp +++ b/gcc/testsuite/g++.dg/dg.exp @@ -49,6 +49,7 @@ set tests [prune $tests $srcdir/$subdir/torture/*] set tests [prune $tests $srcdir/$subdir/graphite/*] set tests [prune $tests $srcdir/$subdir/tm/*] set tests [prune $tests $srcdir/$subdir/guality/*] +set tests [prune $tests $srcdir/$subdir/simulate-thread/*] # Main loop. dg-runtest $tests "" $DEFAULT_CXXFLAGS diff --git a/gcc/testsuite/g++.dg/eh/array1.C b/gcc/testsuite/g++.dg/eh/array1.C new file mode 100644 index 00000000000..157450a9592 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/array1.C @@ -0,0 +1,15 @@ +// Test that we have one EH cleanup region for the whole array +// rather than one for each element. +// { dg-options -fdump-tree-gimple } +// { dg-final { scan-tree-dump-times "catch" 1 "gimple" } } + +struct A +{ + A(); + ~A(); +}; + +void f() +{ + A a[10] = { }; +} diff --git a/gcc/testsuite/g++.dg/ext/alias-decl-attr1.C b/gcc/testsuite/g++.dg/ext/alias-decl-attr1.C new file mode 100644 index 00000000000..e83fe441275 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-decl-attr1.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x" } + +template <unsigned Len, unsigned Align> +struct aligned_storage +{ + using type __attribute__((aligned((Align)))) = + char[Len]; +}; + +template<typename T> +struct X +{ + typename aligned_storage<sizeof(T),__alignof(T)>::type data; +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof (X<double>) == __alignof (double)> dummy; diff --git a/gcc/testsuite/g++.dg/ext/alias-decl-attr2.C b/gcc/testsuite/g++.dg/ext/alias-decl-attr2.C new file mode 100644 index 00000000000..83e557c43fb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-decl-attr2.C @@ -0,0 +1,42 @@ +// { dg-options "-std=c++0x" } + +template<typename T> +struct X { + using layout_type __attribute ((aligned(__alignof(double)))) = + char[sizeof(T)]; + layout_type data; +}; + +template<typename T> +struct Y { + using layout_type __attribute ((aligned(__alignof(T)))) = + char[sizeof(T)]; + layout_type data; +}; + +template<typename T> +struct Z { + using layout_type __attribute ((aligned(__alignof(T)))) = + char[sizeof(T)]; + struct Z2 { + layout_type data; + } in; +}; + +template<typename T> +struct A; + +template <typename T> +struct A<T*> { + using layout_type __attribute ((aligned(__alignof(T)))) = + char[sizeof(T)]; + layout_type data; +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof(X<double>) == __alignof(double)> d1; +StaticAssert<__alignof(Y<double>) == __alignof(double)> d2; +StaticAssert<__alignof(Z<double>) == __alignof(double)> d3; +StaticAssert<__alignof(A<double*>) == __alignof(double)> d4; diff --git a/gcc/testsuite/g++.dg/ext/alias-decl-attr3.C b/gcc/testsuite/g++.dg/ext/alias-decl-attr3.C new file mode 100644 index 00000000000..369aa10e65e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-decl-attr3.C @@ -0,0 +1,21 @@ +// { dg-options "-std=c++0x" } +// { dg-do run } + +template <class T> +int +align_of_type_wide_array() +{ + using type_wide_array __attribute((aligned(__alignof(T)))) + = unsigned char[sizeof (T)]; + + return __alignof(type_wide_array); +} + +int +main () +{ + if (align_of_type_wide_array<int>() == __alignof(int)) + return 0; + else + return 1; +} diff --git a/gcc/testsuite/g++.dg/ext/alias-decl-attr4.C b/gcc/testsuite/g++.dg/ext/alias-decl-attr4.C new file mode 100644 index 00000000000..c4dd0487789 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-decl-attr4.C @@ -0,0 +1,34 @@ +// { dg-options "-std=c++0x" } +// { dg-do run } + +using global_vector_type __attribute__((vector_size(16))) = float; + +template <class T> struct A +{ + using type = T; +}; + +template < typename Val > struct S +{ + using vector_type __attribute__((vector_size(16))) = + typename A<Val>::type + typedef Val vector_type2 __attribute__((vector_size(16))); + int pr_size() { return sizeof(vector_type); } + int pr_size2() { return sizeof(vector_type2); } +}; + +int main() +{ + if (sizeof (S<float>::vector_type) != sizeof (global_vector_type)) + return 1; + if (sizeof (S<float>::vector_type2) != sizeof (global_vector_type)) + return 2; + + S<float> x; + if (x.pr_size() != sizeof (global_vector_type)) + return 3; + if (x.pr_size2() != sizeof (global_vector_type)) + return 4; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/template7.C b/gcc/testsuite/g++.dg/ext/visibility/template7.C new file mode 100644 index 00000000000..5197fb1c960 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template7.C @@ -0,0 +1,29 @@ +// PR c++/35688 +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } + +// { dg-final { scan-hidden "_ZN1s6vectorI1AEC1Ev" } } +// { dg-final { scan-hidden "_ZN1s3fooI1AEEvT_" } } + +namespace s __attribute__((visibility("default"))) { + template <class T> + class vector { + public: + vector() { } + }; + template <class T> + void foo(T t) { + } +} + +class A { +public: + A() { } +}; + +s::vector<A> v; + +int main() { + A a; + s::foo(a); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/template8.C b/gcc/testsuite/g++.dg/ext/visibility/template8.C new file mode 100644 index 00000000000..e491882e057 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template8.C @@ -0,0 +1,26 @@ +// PR c++/35688 +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } + +// { dg-final { scan-hidden "_Z1gI1BEvT_" } } +// { dg-final { scan-hidden "_Z1gI1AI1BEEvT_" } } + +// Test that template argument visibility takes priority even over an +// explicit visibility attribute on a template. + +template <class T> +struct __attribute ((visibility ("default"))) A { }; +template <class T> +void g(T) __attribute ((visibility ("default"))); + +struct B { }; + +template <class T> +void g(T) +{ } + +int main() +{ + g(B()); + g(A<B>()); +} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-1.C b/gcc/testsuite/g++.dg/gomp/atomic-1.C deleted file mode 100644 index 3e4bc569ba7..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-1.C +++ /dev/null @@ -1,99 +0,0 @@ -/* { dg-do compile } */ - -int x; -volatile int y; -volatile unsigned char z; - -void f1(void) -{ - #pragma omp atomic - x++; - #pragma omp atomic - x--; - #pragma omp atomic - ++x; - #pragma omp atomic - --x; - #pragma omp atomic - x += 1; - #pragma omp atomic - x -= y; - #pragma omp atomic - x |= 1; - #pragma omp atomic - x &= 1; - #pragma omp atomic - x ^= 1; - #pragma omp atomic - x *= 3; - #pragma omp atomic - x /= 3; - #pragma omp atomic - x /= 3; - #pragma omp atomic - x <<= 3; - #pragma omp atomic - x >>= 3; -} - -void f2(void) -{ - #pragma omp atomic - y++; - #pragma omp atomic - y--; - #pragma omp atomic - ++y; - #pragma omp atomic - --y; - #pragma omp atomic - y += 1; - #pragma omp atomic - y -= x; - #pragma omp atomic - y |= 1; - #pragma omp atomic - y &= 1; - #pragma omp atomic - y ^= 1; - #pragma omp atomic - y *= 3; - #pragma omp atomic - y /= 3; - #pragma omp atomic - y /= 3; - #pragma omp atomic - y <<= 3; - #pragma omp atomic - y >>= 3; -} - -void f3(void) -{ - #pragma omp atomic - z++; - #pragma omp atomic - z--; - #pragma omp atomic - ++z; - #pragma omp atomic - --z; - #pragma omp atomic - z += 1; - #pragma omp atomic - z |= 1; - #pragma omp atomic - z &= 1; - #pragma omp atomic - z ^= 1; - #pragma omp atomic - z *= 3; - #pragma omp atomic - z /= 3; - #pragma omp atomic - z /= 3; - #pragma omp atomic - z <<= 3; - #pragma omp atomic - z >>= 3; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-10.C b/gcc/testsuite/g++.dg/gomp/atomic-10.C deleted file mode 100644 index fe64f0f0631..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-10.C +++ /dev/null @@ -1,24 +0,0 @@ -// PR middle-end/28046 -// { dg-do compile } -// { dg-options "-fopenmp -fdump-tree-ompexp" } - -int a[3], b; -struct C { int x; int y; } c; - -int bar (void), *baz (void); - -void -foo (void) -{ -#pragma omp atomic - a[2] += bar (); -#pragma omp atomic - b += bar (); -#pragma omp atomic - c.y += bar (); -#pragma omp atomic - *baz () += bar (); -} - -// { dg-final { scan-tree-dump-times "__sync_fetch_and_add" 4 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } -// { dg-final { cleanup-tree-dump "ompexp" } } diff --git a/gcc/testsuite/g++.dg/gomp/atomic-11.C b/gcc/testsuite/g++.dg/gomp/atomic-11.C deleted file mode 100644 index 618c4c8e648..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-11.C +++ /dev/null @@ -1,306 +0,0 @@ -/* PR middle-end/45423 */ -/* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-gimple -g0" } */ -/* atomicvar should never be referenced in between the barrier and - following #pragma omp atomic_load. */ -/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */ -/* { dg-final { cleanup-tree-dump "gimple" } } */ - -#ifdef __cplusplus -bool atomicvar, c; -#else -_Bool atomicvar, c; -#endif -int i, atomicvar2, c2; - -int -foo (void) -{ - #pragma omp barrier - #pragma omp atomic - atomicvar |= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar |= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar |= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar |= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar |= c; - #pragma omp barrier - #pragma omp atomic - atomicvar ^= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar ^= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar ^= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar ^= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar ^= c; - #pragma omp barrier - #pragma omp atomic - atomicvar &= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar &= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar &= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar &= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar &= c; - #pragma omp barrier - #pragma omp atomic - atomicvar += -1; - #pragma omp barrier - #pragma omp atomic - atomicvar += 0; - #pragma omp barrier - #pragma omp atomic - atomicvar += 1; - #pragma omp barrier - #pragma omp atomic - atomicvar += 2; - #pragma omp barrier - #pragma omp atomic - atomicvar += c; - #pragma omp barrier - #pragma omp atomic - atomicvar -= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar -= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar -= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar -= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar -= c; - #pragma omp barrier - #pragma omp atomic - atomicvar *= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar *= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar *= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar *= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar *= c; - #pragma omp barrier - #pragma omp atomic - atomicvar /= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar /= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar /= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar /= c; - #pragma omp barrier - #pragma omp atomic - atomicvar <<= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar <<= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar <<= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar <<= i; - #pragma omp barrier - #pragma omp atomic - atomicvar >>= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar >>= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar >>= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar >>= i; - #pragma omp barrier - #pragma omp atomic - atomicvar++; - #pragma omp barrier - #pragma omp atomic - ++atomicvar; - #pragma omp barrier -#ifndef __cplusplus - #pragma omp atomic - atomicvar--; - #pragma omp barrier - #pragma omp atomic - --atomicvar; - #pragma omp barrier -#endif - return 0; -} - -int -bar (void) -{ - #pragma omp barrier - #pragma omp atomic - atomicvar2 |= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 |= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 |= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 |= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 |= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 ^= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 ^= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 ^= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 ^= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 ^= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 &= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 &= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 &= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 &= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 &= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 += -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 += 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 += 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 += 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 += c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 -= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 -= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 -= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 -= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 -= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 *= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 *= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 *= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 *= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 *= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 /= -1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 /= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 /= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 /= c2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 <<= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 <<= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 <<= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 <<= i; - #pragma omp barrier - #pragma omp atomic - atomicvar2 >>= 0; - #pragma omp barrier - #pragma omp atomic - atomicvar2 >>= 1; - #pragma omp barrier - #pragma omp atomic - atomicvar2 >>= 2; - #pragma omp barrier - #pragma omp atomic - atomicvar2 >>= i; - #pragma omp barrier - #pragma omp atomic - atomicvar2++; - #pragma omp barrier - #pragma omp atomic - ++atomicvar2; - #pragma omp barrier - #pragma omp atomic - atomicvar2--; - #pragma omp barrier - #pragma omp atomic - --atomicvar2; - #pragma omp barrier - return 0; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-12.C b/gcc/testsuite/g++.dg/gomp/atomic-12.C deleted file mode 100644 index 6c1f965021d..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-12.C +++ /dev/null @@ -1,9 +0,0 @@ -/* PR middle-end/45423 */ -/* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -O2" } */ -/* atomicvar should never be referenced in between the barrier and - following #pragma omp atomic_load. */ -/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */ -/* { dg-final { cleanup-tree-dump "gimple" } } */ - -#include "atomic-11.C" diff --git a/gcc/testsuite/g++.dg/gomp/atomic-13.C b/gcc/testsuite/g++.dg/gomp/atomic-13.C deleted file mode 100644 index f8fc9d87257..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-13.C +++ /dev/null @@ -1,43 +0,0 @@ -/* PR middle-end/45423 */ -/* { dg-do compile } */ -/* { dg-options "-fopenmp" } */ - -#ifdef __cplusplus -bool *baz (); -#else -_Bool *baz (); -#endif -int *bar (); - -int -foo (void) -{ - #pragma omp barrier - #pragma omp atomic - (*bar ())++; - #pragma omp barrier - #pragma omp atomic - ++(*bar ()); - #pragma omp barrier - #pragma omp atomic - (*bar ())--; - #pragma omp barrier - #pragma omp atomic - --(*bar ()); - #pragma omp barrier - #pragma omp atomic - (*baz ())++; - #pragma omp barrier - #pragma omp atomic - ++(*baz ()); -#ifndef __cplusplus - #pragma omp barrier - #pragma omp atomic - (*baz ())--; - #pragma omp barrier - #pragma omp atomic - --(*baz ()); - #pragma omp barrier -#endif - return 0; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-15.C b/gcc/testsuite/g++.dg/gomp/atomic-15.C deleted file mode 100644 index 95eb8b4534d..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-15.C +++ /dev/null @@ -1,46 +0,0 @@ -// { dg-do compile } -// { dg-options "-fopenmp" } - -int x = 6; - -int -main () -{ - int v; - #pragma omp atomic - x = x * 7 + 6; // { dg-error "expected" } - #pragma omp atomic - x = x * 7 ^ 6; // { dg-error "expected" } - #pragma omp atomic update - x = x - 8 + 6; // { dg-error "expected" } - #pragma omp atomic - x = x ^ 7 | 2; // { dg-error "expected" } - #pragma omp atomic - x = x / 7 * 2; // { dg-error "expected" } - #pragma omp atomic - x = x / 7 / 2; // { dg-error "expected" } - #pragma omp atomic capture - v = x = x | 6; // { dg-error "invalid operator" } - #pragma omp atomic capture - { v = x; x = x * 7 + 6; } // { dg-error "expected" } - #pragma omp atomic capture - { v = x; x = x * 7 ^ 6; } // { dg-error "expected" } - #pragma omp atomic capture - { v = x; x = x - 8 + 6; } // { dg-error "expected" } - #pragma omp atomic capture - { v = x; x = x ^ 7 | 2; } // { dg-error "expected" } - #pragma omp atomic capture - { v = x; x = x / 7 * 2; } // { dg-error "expected" } - #pragma omp atomic capture - { v = x; x = x / 7 / 2; } // { dg-error "expected" } - #pragma omp atomic capture - { x = x * 7 + 6; v = x; } // { dg-error "expected" } - #pragma omp atomic capture - { x = x * 7 ^ 6; v = x; } // { dg-error "expected" } - #pragma omp atomic capture - { x = x - 8 + 6; v = x; } // { dg-error "expected" } - #pragma omp atomic capture - { x = x ^ 7 | 2; v = x; } // { dg-error "expected" } - (void) v; - return 0; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-2.C b/gcc/testsuite/g++.dg/gomp/atomic-2.C deleted file mode 100644 index 720ec9e8ba0..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-2.C +++ /dev/null @@ -1,23 +0,0 @@ -/* { dg-do compile } */ - -float x, y; - -void f1(void) -{ - #pragma omp atomic - x++; - #pragma omp atomic - x--; - #pragma omp atomic - ++x; - #pragma omp atomic - --x; - #pragma omp atomic - x += 1; - #pragma omp atomic - x -= y; - #pragma omp atomic - x *= 3; - #pragma omp atomic - x /= 3; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-3.C b/gcc/testsuite/g++.dg/gomp/atomic-3.C deleted file mode 100644 index 7ea792d3457..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-3.C +++ /dev/null @@ -1,13 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-ompexp" } */ - -int *xyzzy; - -void f1(void) -{ - #pragma omp atomic - xyzzy++; -} - -/* { dg-final { scan-tree-dump-times "xyzzy, 4" 1 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } */ -/* { dg-final { cleanup-tree-dump "ompexp" } } */ diff --git a/gcc/testsuite/g++.dg/gomp/atomic-4.C b/gcc/testsuite/g++.dg/gomp/atomic-4.C deleted file mode 100644 index 7f27370d535..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-4.C +++ /dev/null @@ -1,24 +0,0 @@ -/* { dg-do compile } */ - -int a[4]; -int *p; -struct S { int x; int y[4]; } s; -int *bar(void); - -void f1(void) -{ - #pragma omp atomic - a[4] += 1; - #pragma omp atomic - *p += 1; - #pragma omp atomic - s.x += 1; - #pragma omp atomic - s.y[*p] += 1; - #pragma omp atomic - s.y[*p] *= 42; - #pragma omp atomic - *bar() += 1; - #pragma omp atomic - *bar() *= 42; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-7.C b/gcc/testsuite/g++.dg/gomp/atomic-7.C deleted file mode 100644 index 612e97f4530..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-7.C +++ /dev/null @@ -1,23 +0,0 @@ -/* { dg-do compile } */ - -double x, y; - -void f2(void) -{ - #pragma omp atomic - y++; - #pragma omp atomic - y--; - #pragma omp atomic - ++y; - #pragma omp atomic - --y; - #pragma omp atomic - y += 1; - #pragma omp atomic - y -= x; - #pragma omp atomic - y *= 3; - #pragma omp atomic - y /= 3; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-8.C b/gcc/testsuite/g++.dg/gomp/atomic-8.C deleted file mode 100644 index 2f04151f0ed..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-8.C +++ /dev/null @@ -1,21 +0,0 @@ -/* { dg-do compile } */ - -long double z; - -void f3(void) -{ - #pragma omp atomic - z++; - #pragma omp atomic - z--; - #pragma omp atomic - ++z; - #pragma omp atomic - --z; - #pragma omp atomic - z += 1; - #pragma omp atomic - z *= 3; - #pragma omp atomic - z /= 3; -} diff --git a/gcc/testsuite/g++.dg/gomp/atomic-9.C b/gcc/testsuite/g++.dg/gomp/atomic-9.C deleted file mode 100644 index 2fafbd4097a..00000000000 --- a/gcc/testsuite/g++.dg/gomp/atomic-9.C +++ /dev/null @@ -1,13 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-ompexp" } */ - -volatile int *bar(void); - -void f1(void) -{ - #pragma omp atomic - *bar() += 1; -} - -/* { dg-final { scan-tree-dump-times "__sync_fetch_and_add" 1 "ompexp" { target i?86-*-* x86_64-*-* ia64-*-* powerpc*-*-* alpha*-*-* } } } */ -/* { dg-final { cleanup-tree-dump "ompexp" } } */ diff --git a/gcc/testsuite/g++.dg/gomp/gomp.exp b/gcc/testsuite/g++.dg/gomp/gomp.exp index 9f60bc1c5f3..b99d302ddf5 100644 --- a/gcc/testsuite/g++.dg/gomp/gomp.exp +++ b/gcc/testsuite/g++.dg/gomp/gomp.exp @@ -27,7 +27,7 @@ if ![check_effective_target_fopenmp] { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" "-fopenmp" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/gomp/*.c]] "" "-fopenmp" # All done. dg-finish diff --git a/gcc/testsuite/g++.dg/init/copy7.C b/gcc/testsuite/g++.dg/init/copy7.C deleted file mode 100644 index 20e1e47dbb9..00000000000 --- a/gcc/testsuite/g++.dg/init/copy7.C +++ /dev/null @@ -1,39 +0,0 @@ -// PR c++/39480 -// It isn't always safe to call memcpy with identical arguments. -// { dg-do run } - -extern "C" void abort(); -extern "C" void * -memcpy(void *dest, void *src, __SIZE_TYPE__ n) -{ - if (dest == src) - abort(); - else - { - __SIZE_TYPE__ i; - for (i = 0; i < n; i++) - ((char *)dest)[i] = ((const char*)src)[i]; - } -} - -struct A -{ - double d[10]; -}; - -struct B: public A -{ - char bc; -}; - -B b; - -void f(B *a1, B* a2) -{ - *a1 = *a2; -} - -int main() -{ - f(&b,&b); -} diff --git a/gcc/testsuite/g++.dg/init/lifetime1.C b/gcc/testsuite/g++.dg/init/lifetime1.C new file mode 100644 index 00000000000..57f8c62179a --- /dev/null +++ b/gcc/testsuite/g++.dg/init/lifetime1.C @@ -0,0 +1,29 @@ +// PR c++/48370 +// { dg-do run } + +extern "C" void abort(); + +int last = 4; + +struct A { + int i; + A(int i): i(i) { } + ~A() { if (i > last) abort(); last = i; } +}; + +struct D { int i; }; + +struct B: D, A { B(int i): A(i) { } }; +struct E: D, virtual A { E(int i): A(i) { } }; + +struct C +{ + const A& ar1; + const A& ar2; + const A& ar3; +}; + +int main() +{ + C c = { 1, B(2), E(3) }; +} diff --git a/gcc/testsuite/g++.dg/init/lifetime2.C b/gcc/testsuite/g++.dg/init/lifetime2.C new file mode 100644 index 00000000000..293bd692e9c --- /dev/null +++ b/gcc/testsuite/g++.dg/init/lifetime2.C @@ -0,0 +1,23 @@ +// PR c++/26714 +// { dg-do run } + +extern "C" void abort(); + +bool ok = false; +struct A +{ + A() { } + ~A() { if (!ok) abort(); } +}; + +struct B +{ + const A &a1; + const A &a2; + B() : a1(A()),a2(A()) { ok = true; } +}; + +int main() +{ + B b; +} diff --git a/gcc/testsuite/g++.dg/init/ref21.C b/gcc/testsuite/g++.dg/init/ref21.C new file mode 100644 index 00000000000..db4ac4a300f --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ref21.C @@ -0,0 +1,7 @@ +struct A +{ + const int &i1; + const int &i2; +}; + +A a = { 1, 2 }; diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-1.C b/gcc/testsuite/g++.dg/ipa/devirt-c-1.C index df2230d4c66..dcd8046597c 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-c-1.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-1.C @@ -1,7 +1,7 @@ /* Verify that ipa-cp correctly detects the dynamic type of an object under construction when doing devirtualization. */ /* { dg-do run } */ -/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ extern "C" void abort (void); @@ -69,3 +69,8 @@ int main (int argc, char *argv[]) bah (); return 0; } + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*A::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-2.C b/gcc/testsuite/g++.dg/ipa/devirt-c-2.C index d37fe50cda2..b9a36e29f87 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-c-2.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-2.C @@ -1,7 +1,7 @@ /* Verify that ipa-cp correctly detects the dynamic type of an object under construction when doing devirtualization. */ /* { dg-do run } */ -/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ extern "C" void abort (void); @@ -77,3 +77,8 @@ int main (int argc, char *argv[]) bah (); return 0; } + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*A::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-7.C b/gcc/testsuite/g++.dg/ipa/devirt-c-7.C new file mode 100644 index 00000000000..89d04328c18 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-7.C @@ -0,0 +1,87 @@ +/* Verify that ipa-cp will not get confused by placement new constructing an + object within another one when looking for dynamic type change . */ +/* { dg-do run } */ +/* { dg-options "-O3 -Wno-attributes" } */ + +extern "C" void abort (void); +namespace std { + typedef __SIZE_TYPE__ size_t; +} +inline void* __attribute__ ((always_inline)) +operator new(std::size_t, void* __p) throw() +{ + return __p; +} + +class A +{ +public: + char data[256]; + A(); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C +{ +public: + C(); + virtual double foo (double i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +double C::foo (double i) +{ + return i + 3.5; +} + +static int __attribute__ ((noinline)) middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +__attribute__ ((always_inline)) C::C () +{ +} + +A::A () +{ +} + +static __attribute__ ((noinline)) void bah () +{ + class B b; + + C *c = new ((void *) &b.data) C; + + if (middleman (&b, get_input ()) != 3) + abort (); +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-8.C b/gcc/testsuite/g++.dg/ipa/devirt-c-8.C new file mode 100644 index 00000000000..309644d92ac --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-8.C @@ -0,0 +1,82 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + A(); + virtual int foo (int i); +}; + +class B : public A +{ +public: + B(); + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int __attribute__ ((noinline)) +middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +inline __attribute__ ((always_inline)) A::A () +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +inline __attribute__ ((always_inline)) B::B () +{ +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*A::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/opt/devirt2.C b/gcc/testsuite/g++.dg/opt/devirt2.C index b068f4dedd7..1198abdd776 100644 --- a/gcc/testsuite/g++.dg/opt/devirt2.C +++ b/gcc/testsuite/g++.dg/opt/devirt2.C @@ -1,5 +1,8 @@ // { dg-do compile } // { dg-options "-O2" } +/* Using -mshort-calls avoids loading the function addresses in + registers and thus getting the counts wrong. */ +// { dg-additional-options "-mshort-calls" {target epiphany-*-*} } // { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* } } } } } // The IA64 and HPPA compilers generate external declarations in addition // to the call so those scans need to be more specific. diff --git a/gcc/testsuite/g++.dg/other/offsetof7.C b/gcc/testsuite/g++.dg/other/offsetof7.C new file mode 100644 index 00000000000..0ce2ee02aa8 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/offsetof7.C @@ -0,0 +1,17 @@ +// PR c++/50608 +// Testcase by <dberger@oubliette.org> +// { dg-do compile } + +struct A { + int offset; +}; + +struct B: public A { +}; + +struct C { + A a; + B b; +}; + +int fails = __builtin_offsetof (C, b.offset); diff --git a/gcc/testsuite/g++.dg/parse/pragma3.C b/gcc/testsuite/g++.dg/parse/pragma3.C index 36d7a8c6284..57793b385d0 100644 --- a/gcc/testsuite/g++.dg/parse/pragma3.C +++ b/gcc/testsuite/g++.dg/parse/pragma3.C @@ -1,5 +1,6 @@ // PR c++/25294 -// { dg-do run } +// Epiphany makes struct S 8-byte aligned. +// { dg-do run { target { ! epiphany-*-* } } } extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/pr50672.C b/gcc/testsuite/g++.dg/pr50672.C new file mode 100644 index 00000000000..fb310082edc --- /dev/null +++ b/gcc/testsuite/g++.dg/pr50672.C @@ -0,0 +1,101 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ +typedef int BoxCoordinate; +typedef int BoxDimension; +const BoxDimension X = 0; +const BoxDimension Y = 1; +const BoxDimension NDimensions = 2; +class BoxPoint { + BoxCoordinate point[NDimensions]; +public: + bool isValid() const; + void operator += (const BoxPoint& p) { + if (isValid() && p.isValid()) { + point[X] += p.point[X]; + } + } + const BoxCoordinate& operator [] (const BoxDimension& dimension) const { + return point[dimension]; + } +}; +class BoxRegion { +public: + BoxCoordinate& origin(BoxDimension d) const; + BoxCoordinate& space(BoxDimension d) const; +}; +inline bool operator <= (const BoxPoint& p, const BoxRegion& r) { + for (BoxDimension d = X; + d <= Y; + d++) if (p[d] < r.origin(d) || p[d] >= r.origin(d) + r.space(d)) +return false; + return true; +} +typedef struct _WidgetRec *Widget; +struct GraphGC { + BoxPoint offsetIfSelected; +}; +class GraphNode; +class GraphEdge { +public: + GraphNode *from() const; + GraphNode *to() const; +}; +class LineGraphEdge: public GraphEdge { +protected: + virtual void drawLine(Widget w, const GraphGC& gc) const; + void _print(const GraphGC &gc) const; +}; +class ArcGraphEdge: public LineGraphEdge { + static bool center(const BoxPoint& p1, const BoxPoint& p2, + const BoxPoint& p3, double& x, double& y); + void makeLine(Widget w, const GraphGC& gc) const; +}; +class GraphNode { +public: + bool& selected(); + GraphEdge *firstTo() const; + GraphEdge *nextTo(GraphEdge *ref) const; + virtual const BoxPoint& pos() const = 0; + virtual const BoxRegion& region(const GraphGC& gc) const = 0; + virtual bool isHint() const; +}; +class PosGraphNode: public GraphNode { }; +class RegionGraphNode: public PosGraphNode { }; +class HintGraphNode: public RegionGraphNode { }; +void ArcGraphEdge::makeLine(Widget w, const GraphGC& gc) const { + HintGraphNode *arc_hint = 0; + RegionGraphNode *arc_from = 0; + RegionGraphNode *arc_to = 0; + bool make_arc = true; + if (from()->isHint() && to()->isHint()) { + make_arc = false; + } + else if (from()->isHint() && from()->firstTo() != 0) { + if (arc_hint == 0 || arc_from == 0 || arc_to == 0 + || arc_hint->nextTo(arc_hint->firstTo()) != 0) { + make_arc = false; + } + } + if (!make_arc) { + if (w != 0) LineGraphEdge::drawLine(w, gc); + else LineGraphEdge::_print(gc); + return; + } + BoxPoint pos_from = arc_from->pos(); + BoxRegion region_from = arc_from->region(gc); + BoxPoint pos_to = arc_to->pos(); + BoxRegion region_to = arc_to->region(gc); + BoxPoint pos_hint = arc_hint->pos(); + if (arc_hint->selected()) { + pos_hint += gc.offsetIfSelected; + } + if (pos_hint <= region_from || pos_hint <= region_to) { + return; + } + double cx, cy; + bool ok = center(pos_from, pos_hint, pos_to, cx, cy); + if (!ok) { + if (w != 0) LineGraphEdge::drawLine(w, gc); + else LineGraphEdge::_print(gc); + } +} diff --git a/gcc/testsuite/g++.dg/pr50763-3.C b/gcc/testsuite/g++.dg/pr50763-3.C new file mode 100644 index 00000000000..b66be87b1b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr50763-3.C @@ -0,0 +1,57 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +class v2d { +public: + double x; + double y; +}; + +class v3d { +public: + double x; + v3d() {} + v3d(const v2d & cr2Dv) {} +}; + +class e2d { +protected: + v2d _Min; + v2d _Max; +public: + int cop2d(const v2d & rPnt) const; + v2d clp2d(const v2d & rPnt) const; +}; + +inline int e2d::cop2d(const v2d & rPnt) const { + int bRet = 1; + if (rPnt.x < _Min.x) bRet = 0; + else if (rPnt.x > _Max.x) bRet = 0; + else if (rPnt.y > _Max.y) bRet = 0; + return bRet; +} + +inline v2d e2d::clp2d(const v2d & rPnt) const { + v2d sRet = rPnt; + if (rPnt.x < _Min.x) sRet.x = _Min.x; + if (rPnt.y < _Min.y) sRet.y = _Min.y; + if (rPnt.x > _Max.x) sRet.x = _Max.x; + if (rPnt.y > _Max.y) sRet.y = _Max.y; + return sRet; +} + +class sExt { +protected: + e2d _Dom; + long eval() const; + long evalPoint(const v2d & crUV, v3d & rPnt) const; +}; + +long sExt::evalPoint(const v2d & crUV, v3d & rPnt) const { + v3d sUV = crUV; + if (!_Dom.cop2d(crUV)) { + sUV = _Dom.clp2d(crUV); + } + eval(); +} diff --git a/gcc/testsuite/g++.dg/pr50763-4.C b/gcc/testsuite/g++.dg/pr50763-4.C new file mode 100644 index 00000000000..2605d81925b --- /dev/null +++ b/gcc/testsuite/g++.dg/pr50763-4.C @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +float +clamp (const float x) +{ + return x <= 1 ? 1 : x; +} + +template < class T > struct VECTOR +{ + float x; +}; +template < class TV > class JOINT +{ + virtual void Constrain_Angles (VECTOR < float >&angles) const; +}; + +template < class TV > class ANGLE_JOINT:public JOINT < TV > +{ + virtual ~ ANGLE_JOINT () + { + } + void Constrain_Angles (VECTOR < float >&angles) const + { + VECTOR < float >v; + if (v.x) + v.x = clamp (angles.x); + else + v.x = angles.x; + angles.x = v.x; + } +}; +template ANGLE_JOINT < int >::~ANGLE_JOINT (); diff --git a/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C b/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C new file mode 100644 index 00000000000..7e0041ee382 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C @@ -0,0 +1,73 @@ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that atomic int and atomic char work properly. */ + +using namespace std; + +#include <atomic> +#include <limits.h> +#include <stdio.h> +#include "simulate-thread.h" + +atomic<int> atomi; +atomic<char> atomc; + +/* No need for parallel threads to do anything */ +void simulate_thread_other_threads() +{ +} + +/* Verify after every instruction is executed, that the atmoic int and + char have one of the 2 legitimate values. */ +int simulate_thread_step_verify() +{ + if (atomi != 0 && atomi != INT_MAX) + { + printf ("FAIL: invalid intermediate result for atomi (%d).\n", + (int)atomi); + return 1; + } + if (atomc != 0 && atomc != CHAR_MAX) + { + printf ("FAIL: invalid intermediate result for atomc (%d).\n", + (int)atomc); + return 1; + } + return 0; +} + + +/* Verify that both atmoics have the corerct value. */ +int simulate_thread_final_verify() +{ + if (atomi != INT_MAX) + { + printf ("FAIL: invalid final result for atomi (%d).\n", + (int)atomi); + return 1; + } + if (atomc != CHAR_MAX) + { + printf ("FAIL: invalid final result for atomc (%d).\n", + (int)atomc); + return 1; + } + return 0; +} + +/* Test a store to an atomic int and an atomic char. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + atomi = INT_MAX; + atomc = CHAR_MAX; +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C b/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C new file mode 100644 index 00000000000..be3232d7087 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C @@ -0,0 +1,58 @@ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ +/* { dg-final { simulate-thread } } */ + +using namespace std; + +#include <atomic> +#include <limits.h> +#include <stdio.h> +#include "simulate-thread.h" + +atomic_int atomi; + +/* Non-atomic. Use a type wide enough to possibly coerce GCC into + moving things around. */ +long double j; + + +/* Test that an atomic store synchronizes with an atomic load. + + In this case, test that the store to <j> happens-before the atomic + store to <atomi>. Make sure the compiler does not reorder the + stores. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + j = 13.0; + atomi.store(1); +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} + +void simulate_thread_other_threads() +{ +} + +/* Verify that side-effects before an atomic store are correctly + synchronized with the an atomic load to the same location. */ +int simulate_thread_step_verify() +{ + if (atomi.load() == 1 && j != 13.0) + { + printf ("FAIL: invalid synchronization for atomic load/store.\n"); + return 1; + } + return 0; +} + + +int simulate_thread_final_verify() +{ + return simulate_thread_step_verify(); +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C new file mode 100644 index 00000000000..077514a3ff5 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C @@ -0,0 +1,77 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-load-data-races=0 --param allow-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that setting <var.a> does not touch either <var.b> or <var.c>. + In the C++ memory model, non contiguous bitfields ("a" and "c" + here) should be considered as distinct memory locations, so we + can't use bit twiddling to set either one. */ + +#include <stdio.h> +#include "simulate-thread.h" + +#define CONSTA 12 + +static int global; +struct S +{ + unsigned int a : 4; + unsigned char b; + unsigned int c : 6; +} var; + +__attribute__((noinline)) +void set_a() +{ + var.a = CONSTA; +} + +void simulate_thread_other_threads() +{ + ++global; + var.b = global; + var.c = global; +} + +int simulate_thread_step_verify() +{ + int ret = 0; + if (var.b != global) + { + printf ("FAIL: Unexpected value: var.b is %d, should be %d\n", + var.b, global); + ret = 1; + } + if (var.c != global) + { + printf ("FAIL: Unexpected value: var.c is %d, should be %d\n", + var.c, global); + ret = 1; + } + return ret; +} + +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify(); + if (var.a != CONSTA) + { + printf ("FAIL: Unexpected value: var.a is %d, should be %d\n", + var.a, CONSTA); + ret = 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + set_a(); +} + +int main() +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/bitfields.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C new file mode 100644 index 00000000000..3acf21f876f --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C @@ -0,0 +1,80 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-load-data-races=0 --param allow-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that setting <var.a> does not touch either <var.b> or <var.c>. + In the C++ memory model, non contiguous bitfields ("a" and "c" + here) should be considered as distinct memory locations, so we + can't use bit twiddling to set either one. */ + +#include <stdio.h> +#include "simulate-thread.h" + +#define CONSTA 12 + +static int global; +struct S +{ + /* On x86-64, the volatile causes us to access <a> with a 32-bit + access, and thus trigger this test. */ + volatile unsigned int a : 4; + + unsigned char b; + unsigned int c : 6; +} var; + +__attribute__((noinline)) +void set_a() +{ + var.a = CONSTA; +} + +void simulate_thread_other_threads() +{ + ++global; + var.b = global; + var.c = global; +} + +int simulate_thread_step_verify() +{ + int ret = 0; + if (var.b != global) + { + printf ("FAIL: Unexpected value: var.b is %d, should be %d\n", + var.b, global); + ret = 1; + } + if (var.c != global) + { + printf ("FAIL: Unexpected value: var.c is %d, should be %d\n", + var.c, global); + ret = 1; + } + return ret; +} + +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify(); + if (var.a != CONSTA) + { + printf ("FAIL: Unexpected value: var.a is %d, should be %d\n", + var.a, CONSTA); + ret = 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + set_a(); +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/warn/Wcast-qual2.C b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C new file mode 100644 index 00000000000..23dbb4d39b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C @@ -0,0 +1,4 @@ +// PR c++/50956 +// { dg-options "-Wcast-qual" } + +void* p = (void*)"txt"; // { dg-warning "cast" } diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-null-3.C b/gcc/testsuite/g++.dg/warn/Wconversion-null-3.C new file mode 100644 index 00000000000..1942ee270bf --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wconversion-null-3.C @@ -0,0 +1,8 @@ +// PR c++/48420 + +void foo(int* p); + +void bar() { + const bool kDebugMode = false; + foo(kDebugMode); // { dg-warning "converting 'false'" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-1.C b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-1.C new file mode 100644 index 00000000000..d0f62b212ec --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-1.C @@ -0,0 +1,100 @@ +// { dg-options "-Wzero-as-null-pointer-constant" } + +struct A; + +typedef int (A::*pointmemfun) (int); +typedef int (A::*pointdmem); +typedef int (*pointfun) (int); + +pointmemfun pmfs; +pointdmem pdms; +pointfun pfs; +int* ps; + +void f() +{ + pointmemfun pmf(0); // { dg-warning "zero as null pointer" } + pointdmem pdm(0); // { dg-warning "zero as null pointer" } + pointfun pf(0); // { dg-warning "zero as null pointer" } + int* p(0); // { dg-warning "zero as null pointer" } + + pmf = 0; // { dg-warning "zero as null pointer" } + + pdm = 0; // { dg-warning "zero as null pointer" } + + pf = 0; // { dg-warning "zero as null pointer" } + + p = 0; // { dg-warning "zero as null pointer" } + + if (pmf) + ; + + if (pdm) + ; + + if (pf) + ; + + if (p) + ; + + if (!pmf) + ; + + if (!pdm) + ; + + if (!pf) + ; + + if (!p) + ; + + if (pmf == 0) // { dg-warning "zero as null pointer" } + ; + + if (pdm == 0) // { dg-warning "zero as null pointer" } + ; + + if (pf == 0) // { dg-warning "zero as null pointer" } + ; + + if (p == 0) // { dg-warning "zero as null pointer" } + ; + + if (0 == pmf) // { dg-warning "zero as null pointer" } + ; + + if (0 == pdm) // { dg-warning "zero as null pointer" } + ; + + if (0 == pf) // { dg-warning "zero as null pointer" } + ; + + if (0 == p) // { dg-warning "zero as null pointer" } + ; + + if (pmf != 0) // { dg-warning "zero as null pointer" } + ; + + if (pdm != 0) // { dg-warning "zero as null pointer" } + ; + + if (pf != 0) // { dg-warning "zero as null pointer" } + ; + + if (p != 0) // { dg-warning "zero as null pointer" } + ; + + if (0 != pmf) // { dg-warning "zero as null pointer" } + ; + + if (0 != pdm) // { dg-warning "zero as null pointer" } + ; + + if (0 != pf) // { dg-warning "zero as null pointer" } + ; + + if (0 != p) // { dg-warning "zero as null pointer" } + ; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c index 156fd7b0c61..fcf8c071246 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c @@ -28,6 +28,10 @@ /* Not all Linux kernels deal correctly the breakpoints generated by MIPS16 divisions by zero. They show up as a SIGTRAP instead. */ # define DO_TEST 0 +#elif defined (__epiphany__) + /* Epiphany does not have hardware division, and the software implementation + has truly undefined behaviour for division by 0. */ +# define DO_TEST 0 #else # define DO_TEST 1 #endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x index 418526599d5..d090cbf610e 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x @@ -1,3 +1,8 @@ +if [istarget "epiphany-*-*"] { + # The Epiphany single-precision floating point format does not + # support subnormals. + return 1 +} if [istarget "mips-sgi-irix6*"] { # IRIX 6 sets the MIPS IV flush to zero bit by default, so this test # isn't expected to work for n32 and n64 on MIPS IV targets. diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c index 0b3178f28d7..6e568eddb90 100644 --- a/gcc/testsuite/gcc.dg/20020312-2.c +++ b/gcc/testsuite/gcc.dg/20020312-2.c @@ -20,6 +20,8 @@ extern void abort (void); /* No pic register. */ #elif defined(__cris__) # define PIC_REG "0" +#elif defined(__epiphany__) +#define PIC_REG "r28" #elif defined(__fr30__) /* No pic register. */ #elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) diff --git a/gcc/testsuite/gcc.dg/atomic-compare-exchange-1.c b/gcc/testsuite/gcc.dg/atomic-compare-exchange-1.c new file mode 100644 index 00000000000..2ac54e80887 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-compare-exchange-1.c @@ -0,0 +1,85 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ + +extern void abort(void); + +char v = 0; +char expected = 0; +char max = ~0; +char desired = ~0; +char zero = 0; + +#define STRONG 0 +#define WEAK 1 + +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-compare-exchange-2.c b/gcc/testsuite/gcc.dg/atomic-compare-exchange-2.c new file mode 100644 index 00000000000..73b25977748 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-compare-exchange-2.c @@ -0,0 +1,85 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ + +extern void abort(void); + +short v = 0; +short expected = 0; +short max = ~0; +short desired = ~0; +short zero = 0; + +#define STRONG 0 +#define WEAK 1 + +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-compare-exchange-3.c b/gcc/testsuite/gcc.dg/atomic-compare-exchange-3.c new file mode 100644 index 00000000000..26097288c9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-compare-exchange-3.c @@ -0,0 +1,85 @@ +/* Test __atomic routines for existence and proper execution on 4 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_long } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for an int. */ + +extern void abort(void); + +int v = 0; +int expected = 0; +int max = ~0; +int desired = ~0; +int zero = 0; + +#define STRONG 0 +#define WEAK 1 + +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-compare-exchange-4.c b/gcc/testsuite/gcc.dg/atomic-compare-exchange-4.c new file mode 100644 index 00000000000..d89e72f8171 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-compare-exchange-4.c @@ -0,0 +1,86 @@ +/* Test __atomic routines for existence and proper execution on 8 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ + +/* Test the execution of __atomic_compare_exchange_n builtin for a long_long. */ + +extern void abort(void); + +long long v = 0; +long long expected = 0; +long long max = ~0; +long long desired = ~0; +long long zero = 0; + +#define STRONG 0 +#define WEAK 1 + +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-compare-exchange-5.c b/gcc/testsuite/gcc.dg/atomic-compare-exchange-5.c new file mode 100644 index 00000000000..e716dcb350c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-compare-exchange-5.c @@ -0,0 +1,86 @@ +/* Test __atomic routines for existence and proper execution on 16 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* } } } */ + +/* Test the execution of __atomic_compare_exchange_n builtin for an int_128. */ + +extern void abort(void); + +__int128_t v = 0; +__int128_t expected = 0; +__int128_t max = ~0; +__int128_t desired = ~0; +__int128_t zero = 0; + +#define STRONG 0 +#define WEAK 1 + +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-exchange-1.c b/gcc/testsuite/gcc.dg/atomic-exchange-1.c new file mode 100644 index 00000000000..fb78cdbca54 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-exchange-1.c @@ -0,0 +1,62 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_exchange_n builtin for a char. */ + +extern void abort(void); + +char v, count, ret; + +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count++) + abort (); + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-exchange-2.c b/gcc/testsuite/gcc.dg/atomic-exchange-2.c new file mode 100644 index 00000000000..153771a2cdc --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-exchange-2.c @@ -0,0 +1,62 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_X builtin for a short. */ + +extern void abort(void); + +short v, count, ret; + +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count++) + abort (); + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-exchange-3.c b/gcc/testsuite/gcc.dg/atomic-exchange-3.c new file mode 100644 index 00000000000..fbf8f6b966c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-exchange-3.c @@ -0,0 +1,62 @@ +/* Test __atomic routines for existence and proper execution on 4 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_long } */ + +/* Test the execution of the __atomic_X builtin for an int. */ + +extern void abort(void); + +int v, count, ret; + +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count++) + abort (); + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-exchange-4.c b/gcc/testsuite/gcc.dg/atomic-exchange-4.c new file mode 100644 index 00000000000..f0530fc462c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-exchange-4.c @@ -0,0 +1,63 @@ +/* Test __atomic routines for existence and proper execution on 8 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ + +/* Test the execution of the __atomic_X builtin for a long_long. */ + +extern void abort(void); + +long long v, count, ret; + +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count++) + abort (); + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-exchange-5.c b/gcc/testsuite/gcc.dg/atomic-exchange-5.c new file mode 100644 index 00000000000..13fd6d1b8ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-exchange-5.c @@ -0,0 +1,63 @@ +/* Test __atomic routines for existence and proper execution on 16 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* } } } */ + +/* Test the execution of the __atomic_X builtin for a 16 byte value. */ + +extern void abort(void); + +__int128_t v, count, ret; + +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count++) + abort (); + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count++) + abort (); + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-fence.c b/gcc/testsuite/gcc.dg/atomic-fence.c new file mode 100644 index 00000000000..1f6d1871a0b --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-fence.c @@ -0,0 +1,27 @@ +/* Test __atomic routines for existence and execution with each valid + memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + + +/* Test that __atomic_{thread,signal}_fence builtins execute. */ + +main () +{ + __atomic_thread_fence (__ATOMIC_RELAXED); + __atomic_thread_fence (__ATOMIC_CONSUME); + __atomic_thread_fence (__ATOMIC_ACQUIRE); + __atomic_thread_fence (__ATOMIC_RELEASE); + __atomic_thread_fence (__ATOMIC_ACQ_REL); + __atomic_thread_fence (__ATOMIC_SEQ_CST); + + __atomic_signal_fence (__ATOMIC_RELAXED); + __atomic_signal_fence (__ATOMIC_CONSUME); + __atomic_signal_fence (__ATOMIC_ACQUIRE); + __atomic_signal_fence (__ATOMIC_RELEASE); + __atomic_signal_fence (__ATOMIC_ACQ_REL); + __atomic_signal_fence (__ATOMIC_SEQ_CST); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-generic-aux.c b/gcc/testsuite/gcc.dg/atomic-generic-aux.c new file mode 100644 index 00000000000..a6b552a5dfd --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-generic-aux.c @@ -0,0 +1,45 @@ +/* Supply a set of generic atomic functions to test the compiler make the + calls properly. */ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +/* Test that the generic builtins make calls as expected. */ + +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> + +void +__atomic_exchange (size_t size, void *obj, void *val, void *ret, int model) +{ + /* Copy old value into *ret. */ + memcpy (ret, obj, size); + /* Copy val into object. */ + memcpy (obj, val, size); +} + + +bool +__atomic_compare_exchange (size_t size, void *obj, void *expected, + void *desired, int model1, int model2) +{ + if (!memcmp (obj, expected, size)) + { + memcpy (obj, desired, size); + return true; + } + memcpy (expected, obj, size); + return false; +} + + +void __atomic_load (size_t size, void *obj, void *ret, int model) +{ + memcpy (ret, obj, size); +} + + +void __atomic_store (size_t size, void *obj, void *val, int model) +{ + memcpy (obj, val, size); +} diff --git a/gcc/testsuite/gcc.dg/atomic-generic.c b/gcc/testsuite/gcc.dg/atomic-generic.c new file mode 100644 index 00000000000..8a5528c3653 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-generic.c @@ -0,0 +1,56 @@ +/* Test generic __atomic routines for proper function calling. + memory model. */ +/* { dg-options "-w" } */ +/* { dg-do run } */ +/* { dg-additional-sources "atomic-generic-aux.c" } */ + +/* Test that the generioc atomic builtins execute as expected.. + sync-mem-generic-aux.c supplies a functional external entry point for + the 4 generic functions. */ + +#include <stdlib.h> +#include <stdbool.h> + +extern void abort(); + +typedef struct test { + int array[10]; +} test_struct; + +test_struct zero = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +test_struct ones = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +test_struct a,b; + +int size = sizeof (test_struct); +/* Test for consistency on sizes 1, 2, 4, 8, 16 and 32. */ +main () +{ + test_struct c; + + __atomic_store (&a, &zero, __ATOMIC_RELAXED); + if (memcmp (&a, &zero, size)) + abort (); + + __atomic_exchange (&a, &ones, &c, __ATOMIC_SEQ_CST); + if (memcmp (&c, &zero, size)) + abort (); + if (memcmp (&a, &ones, size)) + abort (); + + __atomic_load (&a, &b, __ATOMIC_RELAXED); + if (memcmp (&b, &ones, size)) + abort (); + + if (!__atomic_compare_exchange (&a, &b, &zero, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort(); + if (memcmp (&a, &zero, size)) + abort (); + + if (__atomic_compare_exchange (&a, &b, &ones, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort(); + if (memcmp (&b, &zero, size)) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-invalid.c b/gcc/testsuite/gcc.dg/atomic-invalid.c new file mode 100644 index 00000000000..2b73c91e7c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-invalid.c @@ -0,0 +1,29 @@ +/* Test __atomic routines for invalid memory model errors. This only needs + to be tested on a single size. */ +/* { dg-do compile } */ +/* { dg-require-effective-target sync_int_long } */ + +#include <stddef.h> + +int i, e, b; +size_t s; + +main () +{ + __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST); /* { dg-error "failure memory model cannot be stronger" } */ + __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELEASE); /* { dg-error "invalid failure memory" } */ + __atomic_compare_exchange_n (&i, &e, 1, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL); /* { dg-error "invalid failure memory" } */ + + __atomic_exchange_n (&i, 1, __ATOMIC_CONSUME); /* { dg-error "invalid memory model" } */ + + __atomic_load_n (&i, __ATOMIC_RELEASE); /* { dg-error "invalid memory model" } */ + __atomic_load_n (&i, __ATOMIC_ACQ_REL); /* { dg-error "invalid memory model" } */ + + __atomic_store_n (&i, 1, __ATOMIC_ACQUIRE); /* { dg-error "invalid memory model" } */ + __atomic_store_n (&i, 1, __ATOMIC_CONSUME); /* { dg-error "invalid memory model" } */ + __atomic_store_n (&i, 1, __ATOMIC_ACQ_REL); /* { dg-error "invalid memory model" } */ + + i = __atomic_always_lock_free (s, NULL); /* { dg-error "non-constant argument" } */ + + __atomic_load_n (&i, 44); /* { dg-warning "invalid memory model" } */ +} diff --git a/gcc/testsuite/gcc.dg/atomic-load-1.c b/gcc/testsuite/gcc.dg/atomic-load-1.c new file mode 100644 index 00000000000..928f9b0f10b --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-load-1.c @@ -0,0 +1,66 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + + +/* Test the execution of the __atomic_load_n builtin for a char. */ + +extern void abort(void); + +char v, count; + +main () +{ + v = 0; + count = 0; + + if (__atomic_load_n (&v, __ATOMIC_RELAXED) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_ACQUIRE) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_CONSUME) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_SEQ_CST) != count++) + abort(); + else + v++; + + /* Now test the generic variants. */ + + __atomic_load (&v, &count, __ATOMIC_RELAXED); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_ACQUIRE); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_CONSUME); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_SEQ_CST); + if (count != v) + abort(); + else + v++; + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-load-2.c b/gcc/testsuite/gcc.dg/atomic-load-2.c new file mode 100644 index 00000000000..3d1df1cfffa --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-load-2.c @@ -0,0 +1,68 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + + +/* Test the execution of the __atomic_load_n builtin for a short. */ + +extern void abort(void); + +short v, count; + + +main () +{ + v = 0; + count = 0; + + if (__atomic_load_n (&v, __ATOMIC_RELAXED) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_ACQUIRE) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_CONSUME) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_SEQ_CST) != count++) + abort(); + else + v++; + + /* Now test the generic variants. */ + + __atomic_load (&v, &count, __ATOMIC_RELAXED); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_ACQUIRE); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_CONSUME); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_SEQ_CST); + if (count != v) + abort(); + else + v++; + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-load-3.c b/gcc/testsuite/gcc.dg/atomic-load-3.c new file mode 100644 index 00000000000..ec238be9e51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-load-3.c @@ -0,0 +1,65 @@ +/* Test __atomic routines for existence and proper execution on 4 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_long } */ + +extern void abort(void); + +int v, count; + + +main () +{ + v = 0; + count = 0; + + if (__atomic_load_n (&v, __ATOMIC_RELAXED) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_ACQUIRE) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_CONSUME) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_SEQ_CST) != count++) + abort(); + else + v++; + + /* Now test the generic variants. */ + + __atomic_load (&v, &count, __ATOMIC_RELAXED); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_ACQUIRE); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_CONSUME); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_SEQ_CST); + if (count != v) + abort(); + else + v++; + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-load-4.c b/gcc/testsuite/gcc.dg/atomic-load-4.c new file mode 100644 index 00000000000..5cb7659da70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-load-4.c @@ -0,0 +1,65 @@ +/* Test __atomic routines for existence and proper execution on 8 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ + +extern void abort(void); + +long long v, count; + +main () +{ + v = 0; + count = 0; + + if (__atomic_load_n (&v, __ATOMIC_RELAXED) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_ACQUIRE) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_CONSUME) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_SEQ_CST) != count++) + abort(); + else + v++; + + /* Now test the generic variants. */ + + __atomic_load (&v, &count, __ATOMIC_RELAXED); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_ACQUIRE); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_CONSUME); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_SEQ_CST); + if (count != v) + abort(); + else + v++; + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-load-5.c b/gcc/testsuite/gcc.dg/atomic-load-5.c new file mode 100644 index 00000000000..2991e4d6c7a --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-load-5.c @@ -0,0 +1,65 @@ +/* Test __atomic routines for existence and proper execution on 16 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* } } } */ + +extern void abort(void); + +__int128_t v, count; + +main () +{ + v = 0; + count = 0; + + if (__atomic_load_n (&v, __ATOMIC_RELAXED) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_ACQUIRE) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_CONSUME) != count++) + abort(); + else + v++; + + if (__atomic_load_n (&v, __ATOMIC_SEQ_CST) != count++) + abort(); + else + v++; + + /* Now test the generic variants. */ + + __atomic_load (&v, &count, __ATOMIC_RELAXED); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_ACQUIRE); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_CONSUME); + if (count != v) + abort(); + else + v++; + + __atomic_load (&v, &count, __ATOMIC_SEQ_CST); + if (count != v) + abort(); + else + v++; + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-lockfree-aux.c b/gcc/testsuite/gcc.dg/atomic-lockfree-aux.c new file mode 100644 index 00000000000..0ea872c302b --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-lockfree-aux.c @@ -0,0 +1,17 @@ +/* Test supply a __atomic_is_lock_free routine for lock-free tests. */ +/* Just compile it on its own. */ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +/* Test that __atomic_{is,always}_lock_free builtins execute. */ + +#include <stdlib.h> + +/* Supply a builtin external function which returns a non-standard value so + it can be detected that it was called. */ +int +__atomic_is_lock_free (size_t s, void *p) +{ + return 2; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-lockfree.c b/gcc/testsuite/gcc.dg/atomic-lockfree.c new file mode 100644 index 00000000000..225428223ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-lockfree.c @@ -0,0 +1,120 @@ +/* Test __atomic routines for existence and execution with each valid + memory model. */ +/* { dg-options "-w" } */ +/* { dg-do run } */ +/* { dg-additional-sources "atomic-lockfree-aux.c" } */ + +/* Test that __atomic_{is,always}_lock_free builtins execute. + sync-mem-lockfree-aux.c supplies and external entry point for + __atomic_is_lock_free which always returns a 2. We can detect the + external routine was called if 2 is returned since that is not a valid + result normally. */ + +#include <stdlib.h> + +extern void abort(); + +int r1, r2; + +/* Test for consistency on sizes 1, 2, 4, 8, 16 and 32. */ +main () +{ + + r1 = __atomic_always_lock_free (sizeof(char), 0); + r2 = __atomic_is_lock_free (sizeof(char), 0); + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + r1 = __atomic_always_lock_free (2, 0); + r2 = __atomic_is_lock_free (2, 0); + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + + r1 = __atomic_always_lock_free (4, 0); + r2 = __atomic_is_lock_free (4, 0); /* Try passing in a variable. */ + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + + r1 = __atomic_always_lock_free (8, 0); + r2 = __atomic_is_lock_free (8, 0); + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + + r1 = __atomic_always_lock_free (16, 0); + r2 = __atomic_is_lock_free (16, 0); + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + + r1 = __atomic_always_lock_free (32, 0); + r2 = __atomic_is_lock_free (32, 0); + /* If always lock free, then is_lock_free must also be true. */ + if (r1) + { + if (r2 != 1) + abort (); + } + else + { + /* If it is not lock free, then the external routine must be called. */ + if (r2 != 2) + abort (); + } + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-noinline-aux.c b/gcc/testsuite/gcc.dg/atomic-noinline-aux.c new file mode 100644 index 00000000000..b92fcfcd60f --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-noinline-aux.c @@ -0,0 +1,51 @@ +/* Supply a set of generic atomic functions to test the compiler make the + calls properly. */ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +/* Test that the generic builtins make calls as expected. This file provides + the exact entry points the test file will require. All these routines + simply set the first parameter to 1, and the caller will test for that. */ + +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> + + +char +__atomic_exchange_1 (char *p, char t, int i) +{ + *p = 1; +} + +short +__atomic_load_2 (short *p, int i) +{ + *p = 1; +} + +void +__atomic_store_1 (char *p, char v, int i) +{ + *p = 1; +} + +int __atomic_compare_exchange_2 (short *p, short *a, short b, int x, int y, int z) +{ + *p = 1; +} + +char __atomic_fetch_add_1 (char *p, char v, int i) +{ + *p = 1; +} + +short __atomic_fetch_add_2 (short *p, short v, short i) +{ + *p = 1; +} + +int __atomic_is_lock_free (int i, void *p) +{ + return 10; +} diff --git a/gcc/testsuite/gcc.dg/atomic-noinline.c b/gcc/testsuite/gcc.dg/atomic-noinline.c new file mode 100644 index 00000000000..06a93e0058e --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-noinline.c @@ -0,0 +1,56 @@ +/* Test generic __atomic routines for proper function calling. + memory model. */ +/* { dg-options "-w -fno-inline-atomics" } */ +/* { dg-do run } */ +/* { dg-additional-sources "atomic-noinline-aux.c" } */ + +/* Test that -fno-inline-atomics works as expected. + atomic-generic-aux provide the expected routines which simply set the + value of the first parameter to */ + +#include <stdlib.h> +#include <stdbool.h> + +extern void abort(); + +short as,bs,cs; +char ac,bc,cc; + +main () +{ + + ac = __atomic_exchange_n (&bc, cc, __ATOMIC_RELAXED); + if (bc != 1) + abort (); + + as = __atomic_load_n (&bs, __ATOMIC_SEQ_CST); + if (bs != 1) + abort (); + + __atomic_store_n (&ac, bc, __ATOMIC_RELAXED); + if (ac != 1) + abort (); + + __atomic_compare_exchange_n (&as, &bs, cs, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + if (as != 1) + abort (); + + ac = __atomic_fetch_add (&cc, 15, __ATOMIC_SEQ_CST); + if (cc != 1) + abort (); + + /* This should be translated to __atomic_fetch_add for the library */ + as = __atomic_add_fetch (&cs, 10, __ATOMIC_RELAXED); + + if (cs != 1) + abort (); + + /* The fake external function should return 10. */ + if (__atomic_is_lock_free (4, 0) != 10) + abort (); + + return 0; +} + + + diff --git a/gcc/testsuite/gcc.dg/atomic-op-1.c b/gcc/testsuite/gcc.dg/atomic-op-1.c new file mode 100644 index 00000000000..bc1716f7799 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-1.c @@ -0,0 +1,554 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_*OP builtin routines for a char. */ + +extern void abort(void); + +char v, count, res; +const char init = ~0; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (__atomic_fetch_add (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub() +{ + v = res = 20; + count = 0; + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (__atomic_fetch_and (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_fetch_and (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand () +{ + v = init; + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (__atomic_fetch_xor (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (__atomic_fetch_or (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch () +{ + v = 0; + count = 1; + + if (__atomic_add_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch () +{ + v = res = 20; + count = 0; + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch () +{ + v = init; + + if (__atomic_and_fetch (&v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + v = init; + if (__atomic_and_fetch (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch () +{ + v = init; + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch () +{ + v = init; + count = 0; + + if (__atomic_xor_fetch (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch () +{ + v = 0; + count = 1; + + if (__atomic_or_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add () +{ + v = 0; + count = 1; + + __atomic_add_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_CONSUME); + if (v != 2) + abort (); + + __atomic_add_fetch (&v, 1 , __ATOMIC_ACQUIRE); + if (v != 3) + abort (); + + __atomic_fetch_add (&v, 1, __ATOMIC_RELEASE); + if (v != 4) + abort (); + + __atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 5) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_SEQ_CST); + if (v != 6) + abort (); +} + + +void +test_sub() +{ + v = res = 20; + count = 0; + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_CONSUME); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, 1, __ATOMIC_ACQUIRE); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + __atomic_and_fetch (&v, 0, __ATOMIC_RELAXED); + if (v != 0) + abort (); + + v = init; + __atomic_fetch_and (&v, init, __ATOMIC_CONSUME); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, init, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_nand () +{ + v = init; + + __atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, init, __ATOMIC_RELEASE); + if (v != 0) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST); + if (v != init) + abort (); +} + + + +void +test_xor () +{ + v = init; + count = 0; + + __atomic_xor_fetch (&v, count, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + __atomic_or_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_CONSUME); + if (v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (&v, 4, __ATOMIC_ACQUIRE); + if (v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (&v, 8, __ATOMIC_RELEASE); + if (v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST); + if (v != 63) + abort (); +} + +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_nand (); + test_fetch_xor (); + test_fetch_or (); + + test_add_fetch (); + test_sub_fetch (); + test_and_fetch (); + test_nand_fetch (); + test_xor_fetch (); + test_or_fetch (); + + test_add (); + test_sub (); + test_and (); + test_nand (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-op-2.c b/gcc/testsuite/gcc.dg/atomic-op-2.c new file mode 100644 index 00000000000..8755340cca2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-2.c @@ -0,0 +1,555 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + + +/* Test the execution of the __atomic_*OP builtin routines for a short. */ + +extern void abort(void); + +short v, count, res; +const short init = ~0; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (__atomic_fetch_add (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub() +{ + v = res = 20; + count = 0; + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (__atomic_fetch_and (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_fetch_and (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand () +{ + v = init; + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (__atomic_fetch_xor (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (__atomic_fetch_or (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch () +{ + v = 0; + count = 1; + + if (__atomic_add_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch () +{ + v = res = 20; + count = 0; + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch () +{ + v = init; + + if (__atomic_and_fetch (&v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + v = init; + if (__atomic_and_fetch (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch () +{ + v = init; + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch () +{ + v = init; + count = 0; + + if (__atomic_xor_fetch (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch () +{ + v = 0; + count = 1; + + if (__atomic_or_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add () +{ + v = 0; + count = 1; + + __atomic_add_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_CONSUME); + if (v != 2) + abort (); + + __atomic_add_fetch (&v, 1 , __ATOMIC_ACQUIRE); + if (v != 3) + abort (); + + __atomic_fetch_add (&v, 1, __ATOMIC_RELEASE); + if (v != 4) + abort (); + + __atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 5) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_SEQ_CST); + if (v != 6) + abort (); +} + + +void +test_sub() +{ + v = res = 20; + count = 0; + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_CONSUME); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, 1, __ATOMIC_ACQUIRE); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + __atomic_and_fetch (&v, 0, __ATOMIC_RELAXED); + if (v != 0) + abort (); + + v = init; + __atomic_fetch_and (&v, init, __ATOMIC_CONSUME); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, init, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_nand () +{ + v = init; + + __atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, init, __ATOMIC_RELEASE); + if (v != 0) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST); + if (v != init) + abort (); +} + + + +void +test_xor () +{ + v = init; + count = 0; + + __atomic_xor_fetch (&v, count, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + __atomic_or_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_CONSUME); + if (v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (&v, 4, __ATOMIC_ACQUIRE); + if (v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (&v, 8, __ATOMIC_RELEASE); + if (v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST); + if (v != 63) + abort (); +} + +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_nand (); + test_fetch_xor (); + test_fetch_or (); + + test_add_fetch (); + test_sub_fetch (); + test_and_fetch (); + test_nand_fetch (); + test_xor_fetch (); + test_or_fetch (); + + test_add (); + test_sub (); + test_and (); + test_nand (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-op-3.c b/gcc/testsuite/gcc.dg/atomic-op-3.c new file mode 100644 index 00000000000..69db4894b63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-3.c @@ -0,0 +1,554 @@ +/* Test __atomic routines for existence and proper execution on 4 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_long } */ + +/* Test the execution of the __atomic_*OP builtin routines for an int. */ + +extern void abort(void); + +int v, count, res; +const int init = ~0; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (__atomic_fetch_add (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub() +{ + v = res = 20; + count = 0; + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (__atomic_fetch_and (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_fetch_and (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand () +{ + v = init; + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (__atomic_fetch_xor (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (__atomic_fetch_or (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch () +{ + v = 0; + count = 1; + + if (__atomic_add_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch () +{ + v = res = 20; + count = 0; + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch () +{ + v = init; + + if (__atomic_and_fetch (&v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + v = init; + if (__atomic_and_fetch (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch () +{ + v = init; + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch () +{ + v = init; + count = 0; + + if (__atomic_xor_fetch (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch () +{ + v = 0; + count = 1; + + if (__atomic_or_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add () +{ + v = 0; + count = 1; + + __atomic_add_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_CONSUME); + if (v != 2) + abort (); + + __atomic_add_fetch (&v, 1 , __ATOMIC_ACQUIRE); + if (v != 3) + abort (); + + __atomic_fetch_add (&v, 1, __ATOMIC_RELEASE); + if (v != 4) + abort (); + + __atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 5) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_SEQ_CST); + if (v != 6) + abort (); +} + + +void +test_sub() +{ + v = res = 20; + count = 0; + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_CONSUME); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, 1, __ATOMIC_ACQUIRE); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + __atomic_and_fetch (&v, 0, __ATOMIC_RELAXED); + if (v != 0) + abort (); + + v = init; + __atomic_fetch_and (&v, init, __ATOMIC_CONSUME); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, init, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_nand () +{ + v = init; + + __atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, init, __ATOMIC_RELEASE); + if (v != 0) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST); + if (v != init) + abort (); +} + + + +void +test_xor () +{ + v = init; + count = 0; + + __atomic_xor_fetch (&v, count, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + __atomic_or_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_CONSUME); + if (v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (&v, 4, __ATOMIC_ACQUIRE); + if (v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (&v, 8, __ATOMIC_RELEASE); + if (v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST); + if (v != 63) + abort (); +} + +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_nand (); + test_fetch_xor (); + test_fetch_or (); + + test_add_fetch (); + test_sub_fetch (); + test_and_fetch (); + test_nand_fetch (); + test_xor_fetch (); + test_or_fetch (); + + test_add (); + test_sub (); + test_and (); + test_nand (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-op-4.c b/gcc/testsuite/gcc.dg/atomic-op-4.c new file mode 100644 index 00000000000..39650213edf --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-4.c @@ -0,0 +1,555 @@ +/* Test __atomic routines for existence and proper execution on 8 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ + +/* Test the execution of the __atomic_*OP builtin routines for long long. */ + +extern void abort(void); + +long long v, count, res; +const long long init = ~0; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (__atomic_fetch_add (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub() +{ + v = res = 20; + count = 0; + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (__atomic_fetch_and (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_fetch_and (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand () +{ + v = init; + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (__atomic_fetch_xor (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (__atomic_fetch_or (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch () +{ + v = 0; + count = 1; + + if (__atomic_add_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch () +{ + v = res = 20; + count = 0; + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch () +{ + v = init; + + if (__atomic_and_fetch (&v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + v = init; + if (__atomic_and_fetch (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch () +{ + v = init; + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch () +{ + v = init; + count = 0; + + if (__atomic_xor_fetch (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch () +{ + v = 0; + count = 1; + + if (__atomic_or_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add () +{ + v = 0; + count = 1; + + __atomic_add_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_CONSUME); + if (v != 2) + abort (); + + __atomic_add_fetch (&v, 1 , __ATOMIC_ACQUIRE); + if (v != 3) + abort (); + + __atomic_fetch_add (&v, 1, __ATOMIC_RELEASE); + if (v != 4) + abort (); + + __atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 5) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_SEQ_CST); + if (v != 6) + abort (); +} + + +void +test_sub() +{ + v = res = 20; + count = 0; + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_CONSUME); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, 1, __ATOMIC_ACQUIRE); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + __atomic_and_fetch (&v, 0, __ATOMIC_RELAXED); + if (v != 0) + abort (); + + v = init; + __atomic_fetch_and (&v, init, __ATOMIC_CONSUME); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, init, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_nand () +{ + v = init; + + __atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, init, __ATOMIC_RELEASE); + if (v != 0) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST); + if (v != init) + abort (); +} + + + +void +test_xor () +{ + v = init; + count = 0; + + __atomic_xor_fetch (&v, count, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + __atomic_or_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_CONSUME); + if (v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (&v, 4, __ATOMIC_ACQUIRE); + if (v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (&v, 8, __ATOMIC_RELEASE); + if (v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST); + if (v != 63) + abort (); +} + +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_nand (); + test_fetch_xor (); + test_fetch_or (); + + test_add_fetch (); + test_sub_fetch (); + test_and_fetch (); + test_nand_fetch (); + test_xor_fetch (); + test_or_fetch (); + + test_add (); + test_sub (); + test_and (); + test_nand (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-op-5.c b/gcc/testsuite/gcc.dg/atomic-op-5.c new file mode 100644 index 00000000000..2ca71adc8f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-5.c @@ -0,0 +1,555 @@ +/* Test __atomic routines for existence and proper execution on 16 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* } } } */ + +/* Test the execution of the __atomic_*OP builtin routines for an int_128. */ + +extern void abort(void); + +__int128_t v, count, res; +const __int128_t init = ~0; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (__atomic_fetch_add (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (&v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (&v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub() +{ + v = res = 20; + count = 0; + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (&v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (&v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (__atomic_fetch_and (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_fetch_and (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand () +{ + v = init; + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (__atomic_fetch_xor (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (&v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (__atomic_fetch_or (&v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch () +{ + v = 0; + count = 1; + + if (__atomic_add_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (&v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (&v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch () +{ + v = res = 20; + count = 0; + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (&v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch () +{ + v = init; + + if (__atomic_and_fetch (&v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + v = init; + if (__atomic_and_fetch (&v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + v = ~v; + if (__atomic_and_fetch (&v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch () +{ + v = init; + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (&v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch () +{ + v = init; + count = 0; + + if (__atomic_xor_fetch (&v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (&v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch () +{ + v = 0; + count = 1; + + if (__atomic_or_fetch (&v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (&v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add () +{ + v = 0; + count = 1; + + __atomic_add_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_CONSUME); + if (v != 2) + abort (); + + __atomic_add_fetch (&v, 1 , __ATOMIC_ACQUIRE); + if (v != 3) + abort (); + + __atomic_fetch_add (&v, 1, __ATOMIC_RELEASE); + if (v != 4) + abort (); + + __atomic_add_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 5) + abort (); + + __atomic_fetch_add (&v, count, __ATOMIC_SEQ_CST); + if (v != 6) + abort (); +} + + +void +test_sub() +{ + v = res = 20; + count = 0; + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_RELAXED); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_CONSUME); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, 1, __ATOMIC_ACQUIRE); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, 1, __ATOMIC_RELEASE); + if (v != --res) + abort (); + + __atomic_sub_fetch (&v, count + 1, __ATOMIC_ACQ_REL); + if (v != --res) + abort (); + + __atomic_fetch_sub (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + __atomic_and_fetch (&v, 0, __ATOMIC_RELAXED); + if (v != 0) + abort (); + + v = init; + __atomic_fetch_and (&v, init, __ATOMIC_CONSUME); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, init, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_and_fetch (&v, 0, __ATOMIC_ACQ_REL); + if (v != 0) + abort (); + + v = ~v; + __atomic_fetch_and (&v, 0, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_nand () +{ + v = init; + + __atomic_fetch_nand (&v, 0, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, init, __ATOMIC_RELEASE); + if (v != 0) + abort (); + + __atomic_fetch_nand (&v, init, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_nand_fetch (&v, 0, __ATOMIC_SEQ_CST); + if (v != init) + abort (); +} + + + +void +test_xor () +{ + v = init; + count = 0; + + __atomic_xor_fetch (&v, count, __ATOMIC_RELAXED); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_CONSUME); + if (v != 0) + abort (); + + __atomic_xor_fetch (&v, 0, __ATOMIC_ACQUIRE); + if (v != 0) + abort (); + + __atomic_fetch_xor (&v, ~count, __ATOMIC_RELEASE); + if (v != init) + abort (); + + __atomic_fetch_xor (&v, 0, __ATOMIC_ACQ_REL); + if (v != init) + abort (); + + __atomic_xor_fetch (&v, ~count, __ATOMIC_SEQ_CST); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + __atomic_or_fetch (&v, count, __ATOMIC_RELAXED); + if (v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_CONSUME); + if (v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (&v, 4, __ATOMIC_ACQUIRE); + if (v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (&v, 8, __ATOMIC_RELEASE); + if (v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (&v, count, __ATOMIC_ACQ_REL); + if (v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (&v, count, __ATOMIC_SEQ_CST); + if (v != 63) + abort (); +} + +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_nand (); + test_fetch_xor (); + test_fetch_or (); + + test_add_fetch (); + test_sub_fetch (); + test_and_fetch (); + test_nand_fetch (); + test_xor_fetch (); + test_or_fetch (); + + test_add (); + test_sub (); + test_and (); + test_nand (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic-param.c b/gcc/testsuite/gcc.dg/atomic-param.c new file mode 100644 index 00000000000..a1bfc6be87c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-param.c @@ -0,0 +1,13 @@ +/* Test __atomic routines for invalid memory model errors. This only needs + to be tested on a single size. */ +/* { dg-do compile } */ +/* { dg-require-effective-target sync_int_long } */ + +int i; + +main () +{ + + __atomic_exchange_n (&i, 1); /* { dg-error "too few arguments" } */ + __atomic_exchange_n (&i, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); /* { dg-error "too many arguments" } */ +} diff --git a/gcc/testsuite/gcc.dg/atomic-store-1.c b/gcc/testsuite/gcc.dg/atomic-store-1.c new file mode 100644 index 00000000000..f99eb9c844f --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-store-1.c @@ -0,0 +1,47 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_store_n builtin for a char. */ + +extern void abort(void); + +char v, count; + +main () +{ + v = 0; + count = 0; + + __atomic_store_n (&v, count + 1, __ATOMIC_RELAXED); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_RELEASE); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != ++count) + abort (); + + /* Now test the generic variant. */ + count++; + + __atomic_store (&v, &count, __ATOMIC_RELAXED); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_RELEASE); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_SEQ_CST); + if (v != count) + abort (); + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-store-2.c b/gcc/testsuite/gcc.dg/atomic-store-2.c new file mode 100644 index 00000000000..da346fd7de4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-store-2.c @@ -0,0 +1,46 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_char_short } */ + +/* Test the execution of the __atomic_store_n builtin for a short. */ + +extern void abort(void); + +short v, count; + +main () +{ + v = 0; + count = 0; + + __atomic_store_n (&v, count + 1, __ATOMIC_RELAXED); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_RELEASE); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != ++count) + abort (); + + /* Now test the generic variant. */ + count++; + + __atomic_store (&v, &count, __ATOMIC_RELAXED); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_RELEASE); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_SEQ_CST); + if (v != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-store-3.c b/gcc/testsuite/gcc.dg/atomic-store-3.c new file mode 100644 index 00000000000..b691da4592f --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-store-3.c @@ -0,0 +1,47 @@ +/* Test __atomic routines for existence and proper execution on 4 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_long } */ + +/* Test the execution of the __atomic_store_n builtin for an int. */ + +extern void abort(void); + +int v, count; + +main () +{ + v = 0; + count = 0; + + __atomic_store_n (&v, count + 1, __ATOMIC_RELAXED); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_RELEASE); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != ++count) + abort (); + + /* Now test the generic variant. */ + count++; + + __atomic_store (&v, &count, __ATOMIC_RELAXED); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_RELEASE); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_SEQ_CST); + if (v != count) + abort (); + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-store-4.c b/gcc/testsuite/gcc.dg/atomic-store-4.c new file mode 100644 index 00000000000..f77e1831ad8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-store-4.c @@ -0,0 +1,48 @@ +/* Test __atomic routines for existence and proper execution on 8 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ + +/* Test the execution of the __atomic_store_n builtin for a long long. */ + +extern void abort(void); + +long long v, count; + +main () +{ + v = 0; + count = 0; + + __atomic_store_n (&v, count + 1, __ATOMIC_RELAXED); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_RELEASE); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != ++count) + abort (); + + /* Now test the generic variant. */ + count++; + + __atomic_store (&v, &count, __ATOMIC_RELAXED); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_RELEASE); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_SEQ_CST); + if (v != count) + abort (); + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic-store-5.c b/gcc/testsuite/gcc.dg/atomic-store-5.c new file mode 100644 index 00000000000..f976a052c7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-store-5.c @@ -0,0 +1,48 @@ +/* Test __atomic routines for existence and proper execution on 16 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* } } } */ + +/* Test the execution of the __atomic_store_n builtin for a 16 byte value. */ + +extern void abort(void); + +__int128_t v, count; + +main () +{ + v = 0; + count = 0; + + __atomic_store_n (&v, count + 1, __ATOMIC_RELAXED); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_RELEASE); + if (v != ++count) + abort (); + + __atomic_store_n (&v, count + 1, __ATOMIC_SEQ_CST); + if (v != ++count) + abort (); + + /* Now test the generic variant. */ + count++; + + __atomic_store (&v, &count, __ATOMIC_RELAXED); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_RELEASE); + if (v != count++) + abort (); + + __atomic_store (&v, &count, __ATOMIC_SEQ_CST); + if (v != count) + abort (); + + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c index 047a1e85449..c5b841a8496 100644 --- a/gcc/testsuite/gcc.dg/builtin-apply2.c +++ b/gcc/testsuite/gcc.dg/builtin-apply2.c @@ -12,7 +12,7 @@ #define INTEGER_ARG 5 -#ifdef __ARM_PCS +#if defined(__ARM_PCS) || defined(__epiphany__) /* For Base AAPCS, NAME is passed in r0. D is passed in r2 and r3. E, F and G are passed on stack. So the size of the stack argument data is 20. */ diff --git a/gcc/testsuite/gcc.dg/c1x-align-1.c b/gcc/testsuite/gcc.dg/c1x-align-1.c new file mode 100644 index 00000000000..9fe5757bed0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c1x-align-1.c @@ -0,0 +1,41 @@ +/* Test C1X alignment support. Test valid code. */ +/* { dg-do compile } */ +/* { dg-options "-std=c1x -pedantic-errors" } */ + +#include <stddef.h> + +_Alignas (_Alignof (max_align_t)) char c; +extern _Alignas (max_align_t) char c; +extern char c; + +extern _Alignas (max_align_t) short s; +_Alignas (max_align_t) short s; + +_Alignas (int) int i; +extern int i; + +_Alignas (max_align_t) long l; + +_Alignas (max_align_t) long long ll; + +_Alignas (max_align_t) float f; + +_Alignas (max_align_t) double d; + +_Alignas (max_align_t) _Complex long double cld; + +_Alignas (0) _Alignas (int) _Alignas (char) char ca[10]; + +_Alignas ((int) _Alignof (max_align_t) + 0) int x; + +enum e { E = _Alignof (max_align_t) }; +_Alignas (E) int y; + +void +func (void) +{ + _Alignas (max_align_t) long long auto_ll; +} + +/* Valid, but useless. */ +_Alignas (0) struct s; /* { dg-warning "useless" } */ diff --git a/gcc/testsuite/gcc.dg/c1x-align-2.c b/gcc/testsuite/gcc.dg/c1x-align-2.c new file mode 100644 index 00000000000..19f7dd67214 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c1x-align-2.c @@ -0,0 +1,92 @@ +/* Test C1X alignment support. Test valid code using stdalign.h. */ +/* { dg-do run } */ +/* { dg-options "-std=c1x -pedantic-errors" } */ + +#include <stdalign.h> +#include <stddef.h> + +extern int strcmp (const char *, const char *); + +extern void exit (int); +extern void abort (void); + +alignas (alignof (max_align_t)) char c; +extern alignas (max_align_t) char c; +extern char c; + +extern alignas (max_align_t) short s; +alignas (max_align_t) short s; + +alignas (int) int i; +extern int i; + +alignas (max_align_t) long l; + +alignas (max_align_t) long long ll; + +alignas (max_align_t) float f; + +alignas (max_align_t) double d; + +alignas (max_align_t) _Complex long double cld; + +alignas (0) alignas (int) alignas (char) char ca[10]; + +alignas ((int) alignof (max_align_t) + 0) int x; + +enum e { E = alignof (max_align_t) }; +alignas (E) int y; + +void +func (void) +{ + alignas (max_align_t) long long auto_ll; +} + +/* Valid, but useless. */ +alignas (0) struct s; /* { dg-warning "useless" } */ + +#ifndef alignas +#error "alignas not defined" +#endif + +#ifndef alignof +#error "alignof not defined" +#endif + +#ifndef __alignas_is_defined +#error "__alignas_is_defined not defined" +#endif + +#if __alignas_is_defined != 1 +#error "__alignas_is_defined not 1" +#endif + +#ifndef __alignof_is_defined +#error "__alignof_is_defined not defined" +#endif + +#if __alignof_is_defined != 1 +#error "__alignof_is_defined not 1" +#endif + +#define str(x) #x +#define xstr(x) str(x) + +const char *s1 = xstr(alignas); +const char *s2 = xstr(alignof); +const char *s3 = xstr(__alignas_is_defined); +const char *s4 = xstr(__alignof_is_defined); + +int +main (void) +{ + if (strcmp (s1, "_Alignas") != 0) + abort (); + if (strcmp (s2, "_Alignof") != 0) + abort (); + if (strcmp (s3, "1") != 0) + abort (); + if (strcmp (s4, "1") != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/c1x-align-3.c b/gcc/testsuite/gcc.dg/c1x-align-3.c new file mode 100644 index 00000000000..0b2a77fa6fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/c1x-align-3.c @@ -0,0 +1,42 @@ +/* Test C1X alignment support. Test invalid code. */ +/* { dg-do compile } */ +/* { dg-options "-std=c1x -pedantic-errors" } */ + +int a = _Alignof (void (void)); /* { dg-error "function" } */ +struct s; +int b = _Alignof (struct s); /* { dg-error "incomplete" } */ +int c = _Alignof (void); /* { dg-error "void" } */ +int d = _Alignof (a); /* { dg-error "expression" } */ + +_Alignas (void (void)) char e; /* { dg-error "function" } */ +_Alignas (struct s) char f; /* { dg-error "incomplete" } */ +_Alignas (void) char g; /* { dg-error "void" } */ + +_Alignas (-__INT_MAX__-1) char h; /* { dg-error "too large|power of 2" } */ +_Alignas (-__INT_MAX__) char h2; /* { dg-error "too large|power of 2" } */ +_Alignas ((-__INT_MAX__-1)/2) char h3; /* { dg-error "too large|power of 2" } */ +_Alignas ((-__INT_MAX__-1)/4) char h4; /* { dg-error "too large|power of 2" } */ +_Alignas ((-__INT_MAX__-1)/8) char h5; /* { dg-error "too large|power of 2" } */ +_Alignas (-__LONG_LONG_MAX__-1) char i; /* { dg-error "too large|power of 2" } */ +_Alignas (-(__LONG_LONG_MAX__-1)/2) char i2; /* { dg-error "too large|power of 2" } */ +_Alignas (-(__LONG_LONG_MAX__-1)/4) char i3; /* { dg-error "too large|power of 2" } */ +_Alignas (-(__LONG_LONG_MAX__-1)/8) char i4; /* { dg-error "too large|power of 2" } */ +_Alignas (-(__LONG_LONG_MAX__-1)/16) char i5; /* { dg-error "too large|power of 2" } */ +_Alignas (-1) char j; /* { dg-error "power of 2" } */ +_Alignas (3) char k; /* { dg-error "power of 2" } */ + +_Alignas ((void *) 1) char k; /* { dg-error "integer constant" } */ +int x; +_Alignas (x) char l; /* { dg-error "integer constant" } */ + +_Alignas (0) struct s; /* { dg-error "does not redeclare tag" } */ + +_Alignas (0) typedef int T; /* { dg-error "alignment specified for typedef" } */ +void func (_Alignas (0) int); /* { dg-error "alignment specified for unnamed parameter" } */ +void f2 (_Alignas (0) int parm2) {} /* { dg-error "alignment specified for parameter" } */ +void +f3 (void) +{ + register _Alignas (0) int reg; /* { dg-error "register" } */ +} +_Alignas (0) void f4 (void); /* { dg-error "alignment specified for function" } */ diff --git a/gcc/testsuite/gcc.dg/c1x-align-4.c b/gcc/testsuite/gcc.dg/c1x-align-4.c new file mode 100644 index 00000000000..432650cf5dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/c1x-align-4.c @@ -0,0 +1,8 @@ +/* Test C1X alignment support. Test reducing alignment (assumes there + are at least some alignment constraints). */ +/* { dg-do compile } */ +/* { dg-options "-std=c1x -pedantic-errors" } */ + +#include <stddef.h> + +_Alignas (_Alignof (char)) max_align_t x; /* { dg-error "reduce alignment" } */ diff --git a/gcc/testsuite/gcc.dg/c90-align-1.c b/gcc/testsuite/gcc.dg/c90-align-1.c new file mode 100644 index 00000000000..77510f4e0d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-align-1.c @@ -0,0 +1,6 @@ +/* Test _Alignof and _Alignas not in C90. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +int a = _Alignof (int); /* { dg-error "ISO C90 does not support '_Alignof'" } */ +_Alignas (int) int b; /* { dg-error "ISO C90 does not support '_Alignas'" } */ diff --git a/gcc/testsuite/gcc.dg/c99-align-1.c b/gcc/testsuite/gcc.dg/c99-align-1.c new file mode 100644 index 00000000000..1fb2cb07110 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-align-1.c @@ -0,0 +1,6 @@ +/* Test _Alignof and _Alignas not in C99. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +int a = _Alignof (int); /* { dg-error "ISO C99 does not support '_Alignof'" } */ +_Alignas (int) int b; /* { dg-error "ISO C99 does not support '_Alignas'" } */ diff --git a/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c b/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c index 4fd6671a4db..0cc14da599a 100644 --- a/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c +++ b/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c @@ -23,7 +23,7 @@ f (void) E5 = __imag__ 0, /* __alignof__ always constant. */ E6 = __alignof__ (int[n]), /* { dg-error "ISO C90 forbids variable length array" } */ - E7 = __alignof__ (a), + E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */ /* __extension__ ignored for constant expression purposes. */ E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */ E9 = __extension__ 0, diff --git a/gcc/testsuite/gcc.dg/gnu90-const-expr-1.c b/gcc/testsuite/gcc.dg/gnu90-const-expr-1.c index 3f7f1af5de0..e052114622c 100644 --- a/gcc/testsuite/gcc.dg/gnu90-const-expr-1.c +++ b/gcc/testsuite/gcc.dg/gnu90-const-expr-1.c @@ -23,7 +23,7 @@ f (void) E5 = __imag__ 0, /* __alignof__ always constant. */ E6 = __alignof__ (int[n]), /* { dg-error "ISO C90 forbids variable length array" } */ - E7 = __alignof__ (a), + E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */ /* __extension__ ignored for constant expression purposes. */ E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */ E9 = __extension__ 0, diff --git a/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c b/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c index 3f5f25e6d2e..da7076ff899 100644 --- a/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c +++ b/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c @@ -23,7 +23,7 @@ f (void) E5 = __imag__ 0, /* __alignof__ always constant. */ E6 = __alignof__ (int[n]), - E7 = __alignof__ (a), + E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */ /* __extension__ ignored for constant expression purposes. */ E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */ E9 = __extension__ 0, diff --git a/gcc/testsuite/gcc.dg/gnu99-static-1.c b/gcc/testsuite/gcc.dg/gnu99-static-1.c index b600a4b1201..3fece615e0e 100644 --- a/gcc/testsuite/gcc.dg/gnu99-static-1.c +++ b/gcc/testsuite/gcc.dg/gnu99-static-1.c @@ -11,7 +11,7 @@ /* __alignof__, OK. */ static int f0(void); -void g0(void) { __alignof__(f0()); } +void g0(void) { __alignof__(f0()); } /* { dg-error "__alignof__ \\(expression\\)" } */ /* __typeof__ not variably modified, OK. */ static int f1(void); diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-11.c b/gcc/testsuite/gcc.dg/gomp/atomic-11.c deleted file mode 100644 index b5647b0bd81..00000000000 --- a/gcc/testsuite/gcc.dg/gomp/atomic-11.c +++ /dev/null @@ -1,17 +0,0 @@ -/* PR middle-end/36877 */ -/* { dg-do compile } */ -/* { dg-options "-fopenmp" } */ -/* { dg-options "-fopenmp -march=i386" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ - -int i; -float f; - -void foo (void) -{ -#pragma omp atomic - i++; -#pragma omp atomic - f += 1.0; -} - -/* { dg-final { scan-assembler-not "__sync_(fetch|add|bool|val)" { target i?86-*-* x86_64-*-* powerpc*-*-* ia64-*-* s390*-*-* sparc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/gomp/gomp.exp b/gcc/testsuite/gcc.dg/gomp/gomp.exp index e4f31cca924..4cb4cafa400 100644 --- a/gcc/testsuite/gcc.dg/gomp/gomp.exp +++ b/gcc/testsuite/gcc.dg/gomp/gomp.exp @@ -29,8 +29,7 @@ if ![check_effective_target_fopenmp] { dg-init # Main loop. -dg-runtest [lsort [find $srcdir/$subdir *.c]] \ - "" "-fopenmp" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/gomp/*.c]] "" "-fopenmp" # All done. dg-finish diff --git a/gcc/testsuite/gcc.dg/pr50763-5.c b/gcc/testsuite/gcc.dg/pr50763-5.c new file mode 100644 index 00000000000..e5952d09c86 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50763-5.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +struct inode +{ + unsigned short i_mode; + unsigned int i_flags; +}; + +static inline int +is_sxid (unsigned int mode) +{ + return (mode & 0004000) || ((mode & 0002000) && (mode & 00010)); +}; + +void +gfs2_set_inode_flags (int ip, struct inode *inode) +{ + unsigned int flags = inode->i_flags; + if ((ip == 0) && !is_sxid (inode->i_mode)) + inode->i_flags |= 4096; + inode->i_flags = flags; +} diff --git a/gcc/testsuite/gcc.dg/pr50908-2.c b/gcc/testsuite/gcc.dg/pr50908-2.c new file mode 100644 index 00000000000..bffea335a70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50908-2.c @@ -0,0 +1,80 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +typedef struct rtx_def *rtx; +enum debug_info_levels +{ + ARM_FLOAT_ABI_SOFT, ARM_FLOAT_ABI_SOFTFP, ARM_FLOAT_ABI_HARD +}; +struct gcc_options +{ + int x_target_flags; +}; +extern struct gcc_options global_options; +extern int arm_arch_thumb2; +enum rtx_code +{ + UNSPEC, UNSPEC_VOLATILE, ADDR_VEC, SET, CLOBBER, CALL, RETURN, + SIMPLE_RETURN, EH_RETURN, TRAP_IF, CONST_INT, CONST_FIXED, CONST_DOUBLE, + CONST_VECTOR, CONST_STRING, CONST, PC, REG, SCRATCH, SUBREG, + STRICT_LOW_PART, CONCAT, CONCATN, MEM, LABEL_REF, SYMBOL_REF, CC0, + IF_THEN_ELSE, COMPARE, PLUS, MINUS, NEG, MULT, SS_MULT, US_MULT, DIV, + SS_DIV, US_DIV, MOD, UDIV, UMOD, AND, IOR, XOR, NOT, ASHIFT, ROTATE, + ASHIFTRT, LSHIFTRT, ROTATERT, PRE_DEC, PRE_INC, POST_DEC, POST_INC, + PRE_MODIFY, POST_MODIFY, NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU, + UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE, UNLT, LTGT, SIGN_EXTEND, + ZERO_EXTEND, TRUNCATE, FLOAT_EXTEND, FLOAT_TRUNCATE, FLOAT, FIX, + UNSIGNED_FLOAT, UNSIGNED_FIX, SIGN_EXTRACT, ZERO_EXTRACT, HIGH, LO_SUM, + VEC_MERGE, VEC_SELECT, VEC_CONCAT, VEC_DUPLICATE, SS_PLUS, US_PLUS, + SS_MINUS, SS_NEG, US_NEG, SS_ABS, SS_ASHIFT, US_ASHIFT, US_MINUS, + SS_TRUNCATE, US_TRUNCATE, FMA, VAR_LOCATION, DEBUG_IMPLICIT_PTR, + ENTRY_VALUE, DEBUG_PARAMETER_REF, LAST_AND_UNUSED_RTX_CODE +}; +union rtunion_def +{ +}; +struct rtx_def +{ + enum rtx_code code:16; +} +builtin_info_type; +enum constraint_num +{ + CONSTRAINT__UNKNOWN = + 0, CONSTRAINT_f, CONSTRAINT_t, CONSTRAINT_v, CONSTRAINT_w, CONSTRAINT_x, + CONSTRAINT_y, CONSTRAINT_z, CONSTRAINT_l, CONSTRAINT_h, CONSTRAINT_j, + CONSTRAINT_Pj, CONSTRAINT_PJ, CONSTRAINT_k, CONSTRAINT_b, CONSTRAINT_c, + CONSTRAINT_I, CONSTRAINT_J, CONSTRAINT_K, CONSTRAINT_L, CONSTRAINT_M, + CONSTRAINT_N, CONSTRAINT_O, CONSTRAINT_Pa, CONSTRAINT_Pb, CONSTRAINT_Pc, + CONSTRAINT_Pd, CONSTRAINT_Ps, CONSTRAINT_Pt, CONSTRAINT_Pu, CONSTRAINT_Pv, + CONSTRAINT_Pw, CONSTRAINT_Px, CONSTRAINT_Py, CONSTRAINT_G, CONSTRAINT_H, + CONSTRAINT_Dz, CONSTRAINT_Da, CONSTRAINT_Db, CONSTRAINT_Dc, CONSTRAINT_Di, + CONSTRAINT_Dn, CONSTRAINT_Dl, CONSTRAINT_DL, CONSTRAINT_Dv, CONSTRAINT_Dy, + CONSTRAINT_Ut, CONSTRAINT_Uv, CONSTRAINT_Uy, CONSTRAINT_Un, CONSTRAINT_Um, + CONSTRAINT_Us, CONSTRAINT_Uq, CONSTRAINT_Q, CONSTRAINT_Uu, CONSTRAINT_Uw, + CONSTRAINT__LIMIT +}; +typedef struct VEC_char_base +{ +} +VEC_int_heap; +static inline int +satisfies_constraint_j (rtx op) +{ + long long ival = 0; + return ((((!((global_options.x_target_flags & (1 << 14)) != 0)) + || arm_arch_thumb2) && arm_arch_thumb2)) + && ((((enum rtx_code) (op)->code) == HIGH) + || ((((enum rtx_code) (op)->code) == CONST_INT) + && (((ival & 0xffff0000) == 0)))); +} + +int +constraint_satisfied_p (rtx op, enum constraint_num c) +{ + switch (c) + { + case CONSTRAINT_j: + return satisfies_constraint_j (op); + } +} diff --git a/gcc/testsuite/gcc.dg/pr50908-3.c b/gcc/testsuite/gcc.dg/pr50908-3.c new file mode 100644 index 00000000000..60db03dae85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50908-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +extern int v1; +extern int v2; + +void +f () +{ + if (v2 || v1) + (!(v1)) ? (void) 0 : (void) g (); +} diff --git a/gcc/testsuite/gcc.dg/pr50908.c b/gcc/testsuite/gcc.dg/pr50908.c new file mode 100644 index 00000000000..75341f8f105 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50908.c @@ -0,0 +1,175 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +enum Lisp_Type +{ + Lisp_Int0 = 0, Lisp_Int1 = 4, Lisp_Symbol = 2, Lisp_Misc = 3, Lisp_String = + 1, Lisp_Vectorlike = 5, Lisp_Cons = 6, Lisp_Float = 7, +}; +typedef long Lisp_Object; +enum pvec_type +{ + PVEC_NORMAL_VECTOR = 0, PVEC_PROCESS = 0x200, PVEC_FRAME = + 0x400, PVEC_COMPILED = 0x800, PVEC_WINDOW = + 0x1000, PVEC_WINDOW_CONFIGURATION = 0x2000, PVEC_SUBR = + 0x4000, PVEC_CHAR_TABLE = 0x8000, PVEC_BOOL_VECTOR = + 0x10000, PVEC_BUFFER = 0x20000, PVEC_HASH_TABLE = 0x40000, PVEC_TERMINAL = + 0x80000, PVEC_SUB_CHAR_TABLE = 0x100000, PVEC_FONT = + 0x200000, PVEC_OTHER = 0x400000, PVEC_TYPE_MASK = 0x7ffe00 +}; +struct Lisp_Vector +{ + unsigned long size; +}; +struct Lisp_Char_Table +{ + Lisp_Object defalt; + Lisp_Object ascii; +}; +struct Lisp_Sub_Char_Table +{ + Lisp_Object contents[1]; +}; +extern Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound; +struct buffer_text +{ + unsigned char *beg; + long gpt_byte; + long gap_size; +}; +struct buffer +{ + struct buffer_text *text; + struct region_cache *width_run_cache; + Lisp_Object tab_width; + Lisp_Object ctl_arrow; +}; +extern struct buffer *current_buffer; +extern Lisp_Object Vchar_width_table; +struct frame +{ + long text_lines, text_cols; +}; +struct window +{ + Lisp_Object frame; +}; +extern Lisp_Object Vtruncate_partial_width_windows; +extern struct Lisp_Char_Table *window_display_table (struct window *); +struct position * +compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, + width, hscroll, tab_offset, win) + long from, fromvpos, fromhpos, to, tovpos, tohpos; + struct window *win; +{ + register long hpos = fromhpos; + register long pos; + long pos_byte; + register int c = 0; + register struct Lisp_Char_Table *dp = window_display_table (win); + long wide_column_end_hpos = 0; + long continuation_glyph_width; + while (1) + { + if (hpos > width) + { + int total_width = width + continuation_glyph_width; + if (!((Vtruncate_partial_width_windows) == (Qnil)) + && (total_width < + (((void) 0, + (struct frame + *) ((long) (((win)->frame) & ~((((long) 1) << 3) - + 1)))))->text_cols)) + { + if (pos <= to) + { + pos = find_before_next_newline (pos, to, 1); + } + if (wide_column_end_hpos > width) + { + hpos -= width; + } + } + } + else + { + Lisp_Object charvec; + c = + *(((((pos_byte)) >= + (current_buffer->text->gpt_byte) ? (current_buffer->text-> + gap_size) : 0) + + ((pos_byte)) + (current_buffer->text->beg) - ((1)))); + if (current_buffer->width_run_cache) + { + if (((((enum Lisp_Type) (((unsigned long) ((charvec))) & + ((((long) 1) << 3) - 1))) == + Lisp_Vectorlike) + && + !(((void) 0, + (struct Lisp_Vector + *) ((long) ((charvec) & ~((((long) 1) << 3) - 1))))-> + size & ((((unsigned long) 1 << (64 - 1)) >> 1))))) + { + unsigned char *ptr; + int bytes, width, wide_column; + do + { + if ((!((*ptr) & 0x80) ? 1 : !((*ptr) & 0x20) ? 2 : + !((*ptr) & 0x10) ? 3 : !((*ptr) & 0x08) ? 4 : 5) != + bytes) + width = bytes * 4; + else + { + if (dp != 0 + && + ((((enum + Lisp_Type) (((unsigned + long) (((((unsigned) (c) < + 0x80) + ? ((((dp)->ascii) == + (Qnil)) ? (dp)-> + defalt + : (((((enum + Lisp_Type) + (((unsigned + long) (((dp)->ascii))) & ((((long) 1) << 3) - 1))) == Lisp_Vectorlike) && (((((void) 0, (struct Lisp_Vector *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->size & (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) == (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) ? ((void) 0, (struct Lisp_Sub_Char_Table *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->contents[c] : (dp)->ascii)) : disp_char_vector ((dp), (c)))))) & ((((long) 1) << 3) - 1))) == Lisp_Vectorlike) && !(((void) 0, (struct Lisp_Vector *) ((long) (((((unsigned) (c) < 0x80) ? ((((dp)->ascii) == (Qnil)) ? (dp)->defalt : (((((enum Lisp_Type) (((unsigned long) (((dp)->ascii))) & ((((long) 1) << 3) - 1))) == Lisp_Vectorlike) && (((((void) 0, (struct Lisp_Vector *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->size & (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) == (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) ? ((void) 0, (struct Lisp_Sub_Char_Table *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->contents[c] : (dp)->ascii)) : disp_char_vector ((dp), (c)))) & ~((((long) 1) << 3) - 1))))->size & ((((unsigned long) 1 << (64 - 1)) >> 1))))) + width = + ((void) 0, + (struct Lisp_Vector + *) ((long) (((((unsigned) (c) < + 0x80) ? ((((dp)->ascii) == + (Qnil)) ? (dp)-> + defalt + : (((((enum + Lisp_Type) (((unsigned long) (((dp)->ascii))) & ((((long) 1) << 3) - 1))) == Lisp_Vectorlike) && (((((void) 0, (struct Lisp_Vector *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->size & (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) == (((((unsigned long) 1 << (64 - 1)) >> 1)) | (PVEC_SUB_CHAR_TABLE)))) ? ((void) 0, (struct Lisp_Sub_Char_Table *) ((long) (((dp)->ascii) & ~((((long) 1) << 3) - 1))))->contents[c] : (dp)->ascii)) : disp_char_vector ((dp), (c)))) & ~((((long) 1) << 3) - 1))))->size; + else + width = + (((unsigned) (c) < 0x80) ? (c < + 0x20 ? (c == + '\t' + ? ((((long) + (current_buffer-> + tab_width)) + >> (3 - + 1))) + : (c == + '\n' ? 0 + : (((current_buffer->ctl_arrow) == (Qnil)) ? 4 : 2))) : (c < 0x7f ? 1 : ((((current_buffer->ctl_arrow) == (Qnil)) ? 4 : 2)))) : (((long) ((((unsigned) (c) < 0x80) ? ( + { + Lisp_Object + _val; + _val;} + ): char_table_ref ((Vchar_width_table), (c))))) >> (3 - 1))); + if (width > 1) + wide_column = width; + } + } + while (0); + if (wide_column) + wide_column_end_hpos = hpos + wide_column; + } + } + } + } +} diff --git a/gcc/testsuite/gcc.dg/pragma-align-2.c b/gcc/testsuite/gcc.dg/pragma-align-2.c index ac5858cab00..5cdaff9586f 100644 --- a/gcc/testsuite/gcc.dg/pragma-align-2.c +++ b/gcc/testsuite/gcc.dg/pragma-align-2.c @@ -1,4 +1,5 @@ /* { dg-do run { target *-*-solaris2.* } } */ +/* { dg-options "-std=gnu99" } */ void abort (void); diff --git a/gcc/testsuite/gcc.dg/pragma-pack-3.c b/gcc/testsuite/gcc.dg/pragma-pack-3.c index e276bd007fe..d3843149134 100644 --- a/gcc/testsuite/gcc.dg/pragma-pack-3.c +++ b/gcc/testsuite/gcc.dg/pragma-pack-3.c @@ -1,6 +1,7 @@ /* PR c++/25294 */ /* { dg-options "-std=gnu99" } */ -/* { dg-do run } */ +/* Epiphany makes struct S 8-byte aligned. */ +/* { dg-do run { target { ! epiphany-*-* } } } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/profile-dir-1.c b/gcc/testsuite/gcc.dg/profile-dir-1.c index 97763721abc..fbe66ad22a8 100644 --- a/gcc/testsuite/gcc.dg/profile-dir-1.c +++ b/gcc/testsuite/gcc.dg/profile-dir-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-O -fprofile-generate=. -fdump-ipa-profile" } */ -/* { dg-final { scan-ipa-dump " ./profile-dir-1.gcda" "profile" } } */ +/* { dg-options "-O -fprofile-generate=. -fdump-ipa-cgraph" } */ +/* { dg-final { scan-ipa-dump " ./profile-dir-1.gcda" "cgraph" } } */ int main(void) @@ -8,4 +8,4 @@ main(void) return 0; } -/* { dg-final { cleanup-ipa-dump "profile" } } */ +/* { dg-final { cleanup-ipa-dump "cgraph" } } */ diff --git a/gcc/testsuite/gcc.dg/profile-dir-2.c b/gcc/testsuite/gcc.dg/profile-dir-2.c index d49dcc37605..1708f7b7275 100644 --- a/gcc/testsuite/gcc.dg/profile-dir-2.c +++ b/gcc/testsuite/gcc.dg/profile-dir-2.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-O -fprofile-generate -fdump-ipa-profile" } */ -/* { dg-final { scan-ipa-dump "/profile-dir-2.gcda" "profile" } } */ +/* { dg-options "-O -fprofile-generate -fdump-ipa-cgraph" } */ +/* { dg-final { scan-ipa-dump "/profile-dir-2.gcda" "cgraph" } } */ int main(void) @@ -8,4 +8,4 @@ main(void) return 0; } -/* { dg-final { cleanup-ipa-dump "profile" } } */ +/* { dg-final { cleanup-ipa-dump "cgraph" } } */ diff --git a/gcc/testsuite/gcc.dg/profile-dir-3.c b/gcc/testsuite/gcc.dg/profile-dir-3.c index 0ae329d4698..ccedf0e7447 100644 --- a/gcc/testsuite/gcc.dg/profile-dir-3.c +++ b/gcc/testsuite/gcc.dg/profile-dir-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-O -fprofile-generate -fprofile-dir=. -fdump-ipa-profile" } */ -/* { dg-final { scan-ipa-dump " ./profile-dir-3.gcda" "profile" } } */ +/* { dg-options "-O -fprofile-generate -fprofile-dir=. -fdump-ipa-cgraph" } */ +/* { dg-final { scan-ipa-dump " ./profile-dir-3.gcda" "cgraph" } } */ int main(void) @@ -8,4 +8,4 @@ main(void) return 0; } -/* { dg-final { cleanup-ipa-dump "profile" } } */ +/* { dg-final { cleanup-ipa-dump "cgraph" } } */ diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int.c new file mode 100644 index 00000000000..d03e8318108 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int.c @@ -0,0 +1,116 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_int_long } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + + +/* Testing load for atomicity is a little trickier. + + Set up the atomic value so that it changes value after every instruction + is executed. + + Simply alternating between 2 values wouldn't be sufficient since a load of + one part, followed by the load of the second part 2 instructions later would + appear to be valid. + + set up a table of 16 values which change a bit in every byte of the value + each time, this will give us a 16 instruction cycle before repetition + kicks in, which should be sufficient to detect any issues. Just to be sure, + we also change the table cycle size during execution. + + The end result is that all loads should always get one of the values from + the table. Any other pattern means the load failed. */ + +unsigned int ret; +unsigned int value = 0; +unsigned int result = 0; +unsigned int table[16] = { +0x00000000, +0x11111111, +0x22222222, +0x33333333, +0x44444444, +0x55555555, +0x66666666, +0x77777777, +0x88888888, +0x99999999, +0xAAAAAAAA, +0xBBBBBBBB, +0xCCCCCCCC, +0xDDDDDDDD, +0xEEEEEEEE, +0xFFFFFFFF +}; + +int table_cycle_size = 16; + +/* Return 0 if 'result' is a valid value to have loaded. */ +int verify_result () +{ + int x; + int found = 0; + + /* Check entire table for valid values. */ + for (x = 0; x < 16 ; x++) + if (result == table[x]) + { + found = 1; + break; + } + + if (!found) + printf("FAIL: Invalid result returned from fetch\n"); + + return !found; +} + +/* Iterate VALUE through the different valid values. */ +void simulate_thread_other_threads () +{ + static int current = 0; + + if (++current >= table_cycle_size) + current = 0; + value = table[current]; +} + +int simulate_thread_step_verify () +{ + return verify_result (); +} + +int simulate_thread_final_verify () +{ + return verify_result (); +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + int x; + + /* Execute loads with value changing at various cyclic values. */ + for (table_cycle_size = 16; table_cycle_size > 4 ; table_cycle_size--) + { + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + /* In order to verify the returned value (which is not atomic), it needs + to be atomically stored into another variable and check that. */ + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + + /* Execute the fetch/store a couple of times just to ensure the cycles + have a chance to be interesting. */ + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + } +} + +main() +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int128.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int128.c new file mode 100644 index 00000000000..3ade0d6fad3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-int128.c @@ -0,0 +1,132 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* i?86-*-* } } } */ +/* { dg-final { simulate-thread } } */ + +#include <stdio.h> +#include "simulate-thread.h" + + +/* Testing load for atomicity is a little trickier. + + Set up the atomic value so that it changes value after every instruction + is executed. + + Simply alternating between 2 values wouldn't be sufficient since a load of + one part, followed by the load of the second part 2 instructions later would + appear to be valid. + + set up a table of 16 values which change a bit in every byte of the value + each time, this will give us a 16 instruction cycle before repetition + kicks in, which should be sufficient to detect any issues. Just to be sure, + we also change the table cycle size during execution. + + The end result is that all loads should always get one of the values from + the table. Any other pattern means the load failed. */ + +__int128_t ret; +__int128_t value = 0; +__int128_t result = 0; +__int128_t table[16] = { +0x0000000000000000, +0x1111111111111111, +0x2222222222222222, +0x3333333333333333, +0x4444444444444444, +0x5555555555555555, +0x6666666666666666, +0x7777777777777777, +0x8888888888888888, +0x9999999999999999, +0xAAAAAAAAAAAAAAAA, +0xBBBBBBBBBBBBBBBB, +0xCCCCCCCCCCCCCCCC, +0xDDDDDDDDDDDDDDDD, +0xEEEEEEEEEEEEEEEE, +0xFFFFFFFFFFFFFFFF +}; + +int table_cycle_size = 16; + +/* Since we don't have 128 bit constants, we have to properly pad the table. */ +void fill_table() +{ + int x; + for (x = 0; x < 16; x++) + { + ret = table[x]; + ret = (ret << 64) | ret; + table[x] = ret; + } +} + +/* Return 0 if 'result' is a valid value to have loaded. */ +int verify_result () +{ + int x; + int found = 0; + + /* Check entire table for valid values. */ + for (x = 0; x < 16; x++) + if (result == table[x]) + { + found = 1; + break; + } + + if (!found) + printf("FAIL: Invalid result returned from fetch\n"); + + return !found; +} + +/* Iterate VALUE through the different valid values. */ +void simulate_thread_other_threads () +{ + static int current = 0; + + if (++current >= table_cycle_size) + current = 0; + value = table[current]; +} + +int simulate_thread_step_verify () +{ + return verify_result (); +} + +int simulate_thread_final_verify () +{ + return verify_result (); +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + int x; + + /* Make sure value starts with an atomic value now. */ + __atomic_store_n (&value, ret, __ATOMIC_SEQ_CST); + + /* Execute loads with value changing at various cyclic values. */ + for (table_cycle_size = 16; table_cycle_size > 4 ; table_cycle_size--) + { + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + /* In order to verify the returned value (which is not atomic), it needs + to be atomically stored into another variable and check that. */ + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + + /* Execute the fetch/store a couple of times just to ensure the cycles + have a chance to be interesting. */ + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + } +} + +main() +{ + fill_table (); + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-longlong.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-longlong.c new file mode 100644 index 00000000000..8bc2eaace65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-longlong.c @@ -0,0 +1,117 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + + +/* Testing load for atomicity is a little trickier. + + Set up the atomic value so that it changes value after every instruction + is executed. + + Simply alternating between 2 values wouldn't be sufficient since a load of + one part, followed by the load of the second part 2 instructions later would + appear to be valid. + + set up a table of 16 values which change a bit in every byte of the value + each time, this will give us a 16 instruction cycle before repetition + kicks in, which should be sufficient to detect any issues. Just to be sure, + we also change the table cycle size during execution. + + The end result is that all loads should always get one of the values from + the table. Any other pattern means the load failed. */ + +unsigned long long ret; +unsigned long long value = 0; +unsigned long long result = 0; +unsigned long long table[16] = { +0x0000000000000000, +0x1111111111111111, +0x2222222222222222, +0x3333333333333333, +0x4444444444444444, +0x5555555555555555, +0x6666666666666666, +0x7777777777777777, +0x8888888888888888, +0x9999999999999999, +0xAAAAAAAAAAAAAAAA, +0xBBBBBBBBBBBBBBBB, +0xCCCCCCCCCCCCCCCC, +0xDDDDDDDDDDDDDDDD, +0xEEEEEEEEEEEEEEEE, +0xFFFFFFFFFFFFFFFF +}; + +int table_cycle_size = 16; + +/* Return 0 if 'result' is a valid value to have loaded. */ +int verify_result () +{ + int x; + int found = 0; + + /* Check entire table for valid values. */ + for (x = 0; x < 16 ; x++) + if (result == table[x]) + { + found = 1; + break; + } + + if (!found) + printf("FAIL: Invalid result returned from fetch\n"); + + return !found; +} + +/* Iterate VALUE through the different valid values. */ +void simulate_thread_other_threads () +{ + static int current = 0; + + if (++current >= table_cycle_size) + current = 0; + value = table[current]; +} + +int simulate_thread_step_verify () +{ + return verify_result (); +} + +int simulate_thread_final_verify () +{ + return verify_result (); +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + int x; + + /* Execute loads with value changing at various cyclic values. */ + for (table_cycle_size = 16; table_cycle_size > 4 ; table_cycle_size--) + { + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + /* In order to verify the returned value (which is not atomic), it needs + to be atomically stored into another variable and check that. */ + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + + /* Execute the fetch/store a couple of times just to ensure the cycles + have a chance to be interesting. */ + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + } +} + +main() +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-short.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-short.c new file mode 100644 index 00000000000..e7b54c46bef --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-load-short.c @@ -0,0 +1,116 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_char_short } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + + +/* Testing load for atomicity is a little trickier. + + Set up the atomic value so that it changes value after every instruction + is executed. + + Simply alternating between 2 values wouldn't be sufficient since a load of + one part, followed by the load of the second part 2 instructions later would + appear to be valid. + + set up a table of 16 values which change a bit in every byte of the value + each time, this will give us a 16 instruction cycle before repetition + kicks in, which should be sufficient to detect any issues. Just to be sure, + we also change the table cycle size during execution. + + The end result is that all loads should always get one of the values from + the table. Any other pattern means the load failed. */ + +unsigned short ret; +unsigned short value = 0; +unsigned short result = 0; +unsigned short table[16] = { +0x0000, +0x1111, +0x2222, +0x3333, +0x4444, +0x5555, +0x6666, +0x7777, +0x8888, +0x9999, +0xAAAA, +0xBBBB, +0xCCCC, +0xDDDD, +0xEEEE, +0xFFFF +}; + +int table_cycle_size = 16; + +/* Return 0 if 'result' is a valid value to have loaded. */ +int verify_result () +{ + int x; + int found = 0; + + /* Check entire table for valid values. */ + for (x = 0; x < 16 ; x++) + if (result == table[x]) + { + found = 1; + break; + } + + if (!found) + printf("FAIL: Invalid result returned from fetch\n"); + + return !found; +} + +/* Iterate VALUE through the different valid values. */ +void simulate_thread_other_threads () +{ + static int current = 0; + + if (++current >= table_cycle_size) + current = 0; + value = table[current]; +} + +int simulate_thread_step_verify () +{ + return verify_result (); +} + +int simulate_thread_final_verify () +{ + return verify_result (); +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + int x; + + /* Execute loads with value changing at various cyclic values. */ + for (table_cycle_size = 16; table_cycle_size > 4 ; table_cycle_size--) + { + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + /* In order to verify the returned value (which is not atomic), it needs + to be atomically stored into another variable and check that. */ + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + + /* Execute the fetch/store a couple of times just to ensure the cycles + have a chance to be interesting. */ + ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST); + __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST); + } +} + +main() +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int.c new file mode 100644 index 00000000000..990310c0f0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int.c @@ -0,0 +1,118 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_int_long } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + +/* Test all the __sync routines for proper atomicity on 4 byte values. */ + +unsigned int zero = 0; +unsigned int max = ~0; + +unsigned int changing_value = 0; +unsigned int value = 0; +unsigned int ret; + +void test_abort() +{ + static int reported = 0; + if (!reported) + { + printf ("FAIL: improper execution of __sync builtin.\n"); + reported = 1; + } +} + +void simulate_thread_other_threads () +{ +} + +int simulate_thread_step_verify () +{ + if (value != zero && value != max) + { + printf ("FAIL: invalid intermediate result for value.\n"); + return 1; + } + return 0; +} + +int simulate_thread_final_verify () +{ + if (value != 0) + { + printf ("FAIL: invalid final result for value.\n"); + return 1; + } + return 0; +} + +/* All values written to 'value' alternate between 'zero' and + 'max'. Any other value detected by simulate_thread_step_verify() + between instructions would indicate that the value was only + partially written, and would thus fail this atomicity test. + + This function tests each different __atomic routine once, with + the exception of the load instruction which requires special + testing. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + + ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); + if (ret != zero || value != max) + test_abort(); + + __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); + if (value != zero) + test_abort(); + + ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); + + ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); +} + +main () +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int128.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int128.c new file mode 100644 index 00000000000..67f84a14a00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-int128.c @@ -0,0 +1,116 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_int_128 } */ +/* { dg-options "-mcx16" { target { x86_64-*-* i?86-*-*] } } } */ +/* { dg-final { simulate-thread } } */ + +#include <stdio.h> +#include "simulate-thread.h" + +/* Test all the __sync routines for proper atomicity on 16 byte values. */ + +__int128_t zero = 0; +__int128_t max = ~0; +__int128_t changing_value = 0; +__int128_t value = 0; +__int128_t ret; + +void test_abort() +{ + static int reported = 0; + if (!reported) + { + printf ("FAIL: improper execution of __sync builtin.\n"); + reported = 1; + } +} + +void simulate_thread_other_threads () +{ +} + +int simulate_thread_step_verify () +{ + if (value != zero && value != max) + { + printf ("FAIL: invalid intermediate result for value.\n"); + return 1; + } + return 0; +} + +int simulate_thread_final_verify () +{ + if (value != 0) + { + printf ("FAIL: invalid final result for value.\n"); + return 1; + } + return 0; +} + +/* All values written to 'value' alternate between 'zero' and 'max'. Any other + value detected by simulate_thread_step_verify() between instructions would indicate + that the value was only partially written, and would thus fail this + atomicity test. + + This function tests each different __atomic routine once, with the + exception of the load instruction which requires special testing. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + + ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); + if (ret != zero || value != max) + test_abort(); + + __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); + if (value != zero) + test_abort(); + + ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); + + ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); +} + +int main() +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c new file mode 100644 index 00000000000..ac4330bd8a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c @@ -0,0 +1,117 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_long_long } */ +/* { dg-options "" } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + +/* Test all the __sync routines for proper atomicity on 8 byte values. */ + +unsigned long long zero = 0; +unsigned long long max = ~0; + +unsigned long long changing_value = 0; +unsigned long long value = 0; +unsigned long long ret; + +void test_abort() +{ + static int reported = 0; + if (!reported) + { + printf ("FAIL: improper execution of __sync builtin.\n"); + reported = 1; + } +} + +void simulate_thread_other_threads () +{ +} + +int simulate_thread_step_verify () +{ + if (value != zero && value != max) + { + printf ("FAIL: invalid intermediate result for value.\n"); + return 1; + } + return 0; +} + +int simulate_thread_final_verify () +{ + if (value != 0) + { + printf ("FAIL: invalid final result for value.\n"); + return 1; + } + return 0; +} + +/* All values written to 'value' alternate between 'zero' and 'max'. Any other + value detected by simulate_thread_step_verify() between instructions would indicate + that the value was only partially written, and would thus fail this + atomicity test. + + This function tests each different __atomic routine once, with the + exception of the load instruction which requires special testing. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); + if (ret != zero || value != max) + test_abort(); + + __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); + if (value != zero) + test_abort(); + + ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); + + ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); +} + +int main () +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c new file mode 100644 index 00000000000..d823e02fb47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c @@ -0,0 +1,117 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_char_short } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#include "simulate-thread.h" + +/* Test all the __sync routines for proper atomicity on 2 byte values. */ + +unsigned short zero = 0; +unsigned short max = ~0; + +unsigned short changing_value = 0; +unsigned short value = 0; +unsigned short ret; + +void test_abort() +{ + static int reported = 0; + if (!reported) + { + printf ("FAIL: improper execution of __sync builtin.\n"); + reported = 1; + } +} + +void simulate_thread_other_threads () +{ +} + +int simulate_thread_step_verify () +{ + if (value != zero && value != max) + { + printf ("FAIL: invalid intermediate result for value.\n"); + return 1; + } + return 0; +} + +int simulate_thread_final_verify () +{ + if (value != 0) + { + printf ("FAIL: invalid final result for value.\n"); + return 1; + } + return 0; +} + +/* All values written to 'value' alternate between 'zero' and + 'max'. Any other value detected by simulate_thread_step_verify() + between instructions would indicate that the value was only + partially written, and would thus fail this atomicity test. + + This function tests each different __atomic routine once, with + the exception of the load instruction which requires special + testing. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); + if (ret != zero || value != max) + test_abort(); + + __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); + if (value != zero) + test_abort(); + + ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != zero) + test_abort (); + + ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != max) + test_abort (); + + ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); + + ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != max || ret != max) + test_abort (); + + ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); + if (value != zero || ret != zero) + test_abort (); +} + +int main () +{ + simulate_thread_main (); + simulate_thread_done (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c new file mode 100644 index 00000000000..71d1cca9dda --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c @@ -0,0 +1,57 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +#include <stdio.h> +#include "simulate-thread.h" + +/* This file tests that speculative store movement out of a loop doesn't + happen. This is disallowed when --param allow-store-data-races is 0. */ + +int global = 100; + +/* Other thread makes sure global is 100 before the next instruction is + * exceuted. */ +void simulate_thread_other_threads() +{ + global = 100; +} + +int simulate_thread_step_verify() +{ + if (global != 100) + { + printf("FAIL: global variable was assigned to. \n"); + return 1; + } +} + +int simulate_thread_final_verify() +{ + return 0; +} + +/* The variable global should never be assigned if func(0) is called. + This tests store movement out of loop thats never executed. */ +void test (int y) +{ + int x; + for (x=0; x< y; x++) + { + global = y; /* This should never speculatively execute. */ + } +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + test(0); + simulate_thread_done(); +} + +__attribute__((noinline)) +int main() +{ + simulate_thread_main(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/strict-align-global.c b/gcc/testsuite/gcc.dg/simulate-thread/strict-align-global.c new file mode 100644 index 00000000000..fdcd7f46af7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/strict-align-global.c @@ -0,0 +1,52 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-packed-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +#include <stdio.h> +#include "simulate-thread.h" + +/* This test verifies writes to globals do not write to adjacent + globals. This mostly happens on strict-align targets that are not + byte addressable (old Alphas, etc). */ + +char a = 0; +char b = 77; + +void simulate_thread_other_threads() +{ +} + +int simulate_thread_step_verify() +{ + if (b != 77) + { + printf("FAIL: Unexpected value. <b> is %d, should be 77\n", b); + return 1; + } + return 0; +} + +/* Verify that every variable has the correct value. */ +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify (); + if (a != 66) + { + printf("FAIL: Unexpected value. <a> is %d, should be 66\n", a); + return 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + a = 66; +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/simulate-thread/subfields.c b/gcc/testsuite/gcc.dg/simulate-thread/subfields.c new file mode 100644 index 00000000000..2d931176e7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/subfields.c @@ -0,0 +1,93 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-packed-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +#include <stdio.h> +#include "simulate-thread.h" + +/* This test verifies that data races aren't introduced by structure subfield + stores. */ + +struct test_struct { + char a; + char b; + char c; + char d; +} var = {0,0,0,0}; + + +/* This routine sets field a to 'x'. If executed properly, it will + not affect any of the other fields in the structure. An improper + implementation may load an entire word, change the 8 bits for field + 'a' and write the entire word back out. */ +__attribute__((noinline)) +void set_a(char x) +{ + var.a = x; +} + +static int global = 0; + +/* The other thread increments the value of each of the other fields + in the structure every cycle. If the store to the 'a' field does + an incorrect full or partial word load, mask and store, it will + write back an incorrect value to one or more of the other + fields. */ +void simulate_thread_other_threads() +{ + global++; + var.b = global; + var.c = global; + var.d = global; +} + + +/* Make sure that none of the other fields have been changed. */ +int simulate_thread_step_verify() +{ + int ret = 0; + if (var.b != global) + { + printf("FAIL: Unexpected value. var.b is %d, should be %d\n", + var.b, global); + ret = 1; + } + if (var.c != global) + { + printf("FAIL: Unexpected value. var.c is %d, should be %d\n", + var.c, global); + ret = 1; + } + if (var.d != global) + { + printf("FAIL: Unexpected value. var.d is %d, should be %d\n", + var.d, global); + ret = 1; + } + return ret; +} + +/* Verify that every variable has the correct value. */ +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify(); + if (var.a != 1) + { + printf("FAIL: Unexpected value. var.a is %d, should be %d\n", var.a, 1); + ret = 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + set_a(1); +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c index f55168e9e44..77dd03852fb 100644 --- a/gcc/testsuite/gcc.dg/stack-usage-1.c +++ b/gcc/testsuite/gcc.dg/stack-usage-1.c @@ -52,6 +52,8 @@ # define SIZE 160 /* 256 - 96 bytes for register save area */ #elif defined (__SPU__) # define SIZE 224 +#elif defined (__epiphany__) +# define SIZE (256 - __EPIPHANY_STACK_OFFSET__) #else # define SIZE 256 #endif diff --git a/gcc/testsuite/gcc.dg/strlenopt-22.c b/gcc/testsuite/gcc.dg/strlenopt-22.c index 541bfdce467..d6fd4dfbd88 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-22.c +++ b/gcc/testsuite/gcc.dg/strlenopt-22.c @@ -1,7 +1,6 @@ /* { dg-do run } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ -#define USE_GNU #include "strlenopt.h" __attribute__((noinline, noclone)) size_t @@ -32,10 +31,10 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } * /* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-22g.c b/gcc/testsuite/gcc.dg/strlenopt-22g.c new file mode 100644 index 00000000000..45c6345fc8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-22g.c @@ -0,0 +1,14 @@ +/* This test needs runtime that provides stpcpy function. */ +/* { dg-do run { target *-*-linux* } } */ +/* { dg-options "-O2 -fdump-tree-strlen" } */ + +#define USE_GNU +#include "strlenopt-22.c" + +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c index 7542350d8da..87fdc64688d 100644 --- a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c +++ b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c @@ -1,5 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ +/* Using -mshort-calls avoids loading the function addresses in + registers and thus getting the counts wrong. */ +/* { dg-additional-options "-mshort-calls" { target epiphany-*-* } } */ /* { dg-require-effective-target tls_emulated } */ /* Test that we only get one call to emutls_get_address when CSE is diff --git a/gcc/testsuite/gcc.dg/torture/pr50890.c b/gcc/testsuite/gcc.dg/torture/pr50890.c new file mode 100644 index 00000000000..17240d4fb82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr50890.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +static float make_insn_raw (void) +{ + return 0; +} + +static int emit_pattern_after_noloc (int (make_raw) ()) +{ + return make_raw (); +} + +void emit_insn_after_noloc (void) +{ + emit_pattern_after_noloc ((void *) make_insn_raw); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr50902.c b/gcc/testsuite/gcc.dg/torture/pr50902.c new file mode 100644 index 00000000000..5b7275b839d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr50902.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ + +_Bool data[128]; +void foo (_Bool *init) +{ + int i; + for (i = 0; i < 128; i++) + data[i] = *init; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c index a1ba20fce53..89c71a99d5b 100644 --- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c @@ -9,6 +9,15 @@ #define INTEGER_ARG 5 +#if defined(__ARM_PCS) || defined(__epiphany__) +/* For Base AAPCS, NAME is passed in r0. D is passed in r2 and r3. + E, F and G are passed on stack. So the size of the stack argument + data is 20. */ +#define STACK_ARGUMENTS_SIZE 20 +#else +#define STACK_ARGUMENTS_SIZE 64 +#endif + extern void abort(void); void foo(char *name, double d, double e, double f, int g) @@ -19,7 +28,7 @@ void foo(char *name, double d, double e, double f, int g) void bar(char *name, ...) { - __builtin_apply(foo, __builtin_apply_args(), 64); + __builtin_apply(foo, __builtin_apply_args(), STACK_ARGUMENTS_SIZE); } int main(void) diff --git a/gcc/testsuite/gcc.dg/torture/vec-cvt-1.c b/gcc/testsuite/gcc.dg/torture/vec-cvt-1.c new file mode 100644 index 00000000000..601f098889c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/vec-cvt-1.c @@ -0,0 +1,211 @@ +/* { dg-do run } */ + +#include <stdlib.h> + +#define N 1024 +signed char sc[N]; +short ss[N]; +int si[N]; +long long sl[N]; +unsigned char uc[N]; +unsigned short us[N]; +unsigned int ui[N]; +unsigned long long ul[N]; +float f[N]; +double d[N]; + +#define FN1(from, to) \ +__attribute__((noinline, noclone)) void \ +from##2##to (void) \ +{ \ + int i; \ + for (i = 0; i < N; i++) \ + to[i] = from[i]; \ +} +#define FN(intt, fltt) FN1 (intt, fltt) FN1 (fltt, intt) + +FN (sc, f) +FN (ss, f) +FN (si, f) +FN (sl, f) +FN (uc, f) +FN (us, f) +FN (ui, f) +FN (ul, f) +FN (sc, d) +FN (ss, d) +FN (si, d) +FN (sl, d) +FN (uc, d) +FN (us, d) +FN (ui, d) +FN (ul, d) + +#define FLTTEST(min, max, intt) \ +__attribute__((noinline, noclone)) void \ +flttointtest##intt (void) \ +{ \ + int i; \ + volatile float fltmin, fltmax, vf, vf2; \ + volatile double dblmin, dblmax, vd, vd2; \ + if (min == 0) \ + fltmin = 0.0f; \ + else \ + { \ + vf2 = fltmin = min - 1.0f; \ + for (vf = 1.0f; (fltmin = vf2 + vf) == vf2; vf = vf * 2.0f) \ + ; \ + } \ + vf2 = fltmax = max + 1.0f; \ + for (vf = 1.0f; (fltmax = vf2 - vf) == vf2; vf = vf * 2.0f) \ + ; \ + if (min == 0) \ + dblmin = 0.0; \ + else \ + { \ + vd2 = dblmin = min - 1.0; \ + for (vd = 1.0; (dblmin = vd2 + vd) == vd2; vd = vd * 2.0) \ + ; \ + } \ + vd2 = dblmax = max + 1.0; \ + for (vd = 1.0; (dblmax = vd2 - vd) == vd2; vd = vd * 2.0) \ + ; \ + for (i = 0; i < N; i++) \ + { \ + asm (""); \ + if (i == 0) \ + f[i] = fltmin; \ + else if (i < N / 4) \ + f[i] = fltmin + i + 0.25f; \ + else if (i < 3 * N / 4) \ + f[i] = (fltmax + fltmin) / 2.0 - N * 8 + 16.0f * i; \ + else \ + f[i] = fltmax - N + 1 + i; \ + if (f[i] < fltmin) f[i] = fltmin; \ + if (f[i] > fltmax) f[i] = fltmax; \ + if (i == 0) \ + d[i] = dblmin; \ + else if (i < N / 4) \ + d[i] = dblmin + i + 0.25f; \ + else if (i < 3 * N / 4) \ + d[i] = (dblmax + dblmin) / 2.0 - N * 8 + 16.0f * i; \ + else \ + d[i] = dblmax - N + 1 + i; \ + if (d[i] < dblmin) d[i] = dblmin; \ + if (d[i] > dblmax) d[i] = dblmax; \ + } \ + f2##intt (); \ + for (i = 0; i < N; i++) \ + if (intt[i] != (__typeof (intt[0])) f[i]) \ + abort (); \ + d2##intt (); \ + for (i = 0; i < N; i++) \ + if (intt[i] != (__typeof (intt[0])) d[i]) \ + abort (); \ + for (i = 0; i < N; i++) \ + { \ + unsigned long long r = random (); \ + r = (r << 21) ^ (unsigned) random (); \ + r = (r << 21) ^ (unsigned) random (); \ + asm (""); \ + f[i] = (r >> 59) / 32.0f + (__typeof (intt[0])) r; \ + if (f[i] < fltmin) f[i] = fltmin; \ + if (f[i] > fltmax) f[i] = fltmax; \ + d[i] = (r >> 59) / 32.0 + (__typeof (intt[0])) r; \ + if (d[i] < dblmin) f[i] = dblmin; \ + if (d[i] > dblmax) f[i] = dblmax; \ + } \ + f2##intt (); \ + for (i = 0; i < N; i++) \ + if (intt[i] != (__typeof (intt[0])) f[i]) \ + abort (); \ + d2##intt (); \ + for (i = 0; i < N; i++) \ + if (intt[i] != (__typeof (intt[0])) d[i]) \ + abort (); \ +} \ + \ +__attribute__((noinline, noclone)) void \ +inttoflttest##intt (void) \ +{ \ + int i; \ + volatile float vf; \ + volatile double vd; \ + for (i = 0; i < N; i++) \ + { \ + asm (""); \ + if (i < N / 4) \ + intt[i] = min + i; \ + else if (i < 3 * N / 4) \ + intt[i] = (max + min) / 2 - N * 8 + 16 * i; \ + else \ + intt[i] = max - N + 1 + i; \ + } \ + intt##2f (); \ + for (i = 0; i < N; i++) \ + { \ + vf = intt[i]; \ + if (f[i] != vf) \ + abort (); \ + } \ + intt##2d (); \ + for (i = 0; i < N; i++) \ + { \ + vd = intt[i]; \ + if (d[i] != vd) \ + abort (); \ + } \ + for (i = 0; i < N; i++) \ + { \ + unsigned long long r = random (); \ + r = (r << 21) ^ (unsigned) random (); \ + r = (r << 21) ^ (unsigned) random (); \ + asm (""); \ + intt[i] = r; \ + } \ + intt##2f (); \ + for (i = 0; i < N; i++) \ + { \ + vf = intt[i]; \ + if (f[i] != vf) \ + abort (); \ + } \ + intt##2d (); \ + for (i = 0; i < N; i++) \ + { \ + vd = intt[i]; \ + if (d[i] != vd) \ + abort (); \ + } \ +} + +FLTTEST (- __SCHAR_MAX__ - 1, __SCHAR_MAX__, sc) +FLTTEST (- __SHRT_MAX__ - 1, __SHRT_MAX__, ss) +FLTTEST (- __INT_MAX__ - 1, __INT_MAX__, si) +FLTTEST (- __LONG_LONG_MAX__ - 1LL, __LONG_LONG_MAX__, sl) +FLTTEST (0, 2U * __SCHAR_MAX__ + 1, uc) +FLTTEST (0, 2U * __SHRT_MAX__ + 1, us) +FLTTEST (0, 2U * __INT_MAX__ + 1, ui) +FLTTEST (0, 2ULL * __LONG_LONG_MAX__ + 1, ul) + +int +main () +{ + flttointtestsc (); + flttointtestss (); + flttointtestsi (); + flttointtestsl (); + flttointtestuc (); + flttointtestus (); + flttointtestui (); + flttointtestul (); + inttoflttestsc (); + inttoflttestss (); + inttoflttestsi (); + inttoflttestsl (); + inttoflttestuc (); + inttoflttestus (); + inttoflttestui (); + inttoflttestul (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c new file mode 100644 index 00000000000..ae833e53dc0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_condition } */ + +#include "tree-vect.h" + +#define N 128 + +__attribute__((noinline, noclone)) void +foo (int *a, int stride) +{ + int i; + + for (i = 0; i < N/stride; i++, a += stride) + { + a[0] = a[0] ? 1 : 5; + a[1] = a[1] ? 2 : 6; + a[2] = a[2] ? 3 : 7; + a[3] = a[3] ? 4 : 8; + } +} + + +int a[N]; +int main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + a[i] = i; + + foo (a, 4); + + for (i = 1; i < N; i++) + if (a[i] != i%4 + 1) + abort (); + + if (a[0] != 5) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-cond-1.c b/gcc/testsuite/gcc.dg/vect/slp-cond-1.c new file mode 100644 index 00000000000..4b8e3d3b6a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-cond-1.c @@ -0,0 +1,126 @@ +/* { dg-require-effective-target vect_condition } */ +#include "tree-vect.h" + +#define N 32 +int a[N], b[N]; +int d[N], e[N]; +int k[N]; + +__attribute__((noinline, noclone)) void +f1 (void) +{ + int i; + for (i = 0; i < N/4; i++) + { + k[4*i] = a[4*i] < b[4*i] ? 17 : 0; + k[4*i+1] = a[4*i+1] < b[4*i+1] ? 17 : 0; + k[4*i+2] = a[4*i+2] < b[4*i+2] ? 17 : 0; + k[4*i+3] = a[4*i+3] < b[4*i+3] ? 17 : 0; + } +} + +__attribute__((noinline, noclone)) void +f2 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + k[2*i] = a[2*i] < b[2*i] ? 0 : 24; + k[2*i+1] = a[2*i+1] < b[2*i+1] ? 7 : 4; + } +} + +__attribute__((noinline, noclone)) void +f3 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + k[2*i] = a[2*i] < b[2*i] ? 51 : 12; + k[2*i+1] = a[2*i+1] > b[2*i+1] ? 51 : 12; + } +} + +__attribute__((noinline, noclone)) void +f4 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + int d0 = d[2*i], e0 = e[2*i]; + int d1 = d[2*i+1], e1 = e[2*i+1]; + k[2*i] = a[2*i] >= b[2*i] ? d0 : e0; + k[2*i+1] = a[2*i+1] >= b[2*i+1] ? d1 : e1; + } +} + +int +main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break; + case 1: a[i] = 0; b[i] = 0; break; + case 2: a[i] = i + 1; b[i] = - i - 1; break; + case 3: a[i] = i; b[i] = i + 7; break; + case 4: a[i] = i; b[i] = i; break; + case 5: a[i] = i + 16; b[i] = i + 3; break; + case 6: a[i] = - i - 5; b[i] = - i; break; + case 7: a[i] = - i; b[i] = - i; break; + case 8: a[i] = - i; b[i] = - i - 7; break; + } + d[i] = i; + e[i] = 2 * i; + } + f1 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? 17 : 0)) + abort (); + + f2 (); + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: + case 6: + if (k[i] != ((i/9 % 2) == 0 ? 0 : 7)) + abort (); + break; + case 1: + case 5: + case 7: + if (k[i] != ((i/9 % 2) == 0 ? 4 : 24)) + abort (); + break; + case 2: + case 4: + case 8: + if (k[i] != ((i/9 % 2) == 0 ? 24 : 4)) + abort (); + break; + case 3: + if (k[i] != ((i/9 % 2) == 0 ? 7 : 0)) + abort (); + break; + } + } + + f3 (); + + f4 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? e[i] : d[i])) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-cond-2.c b/gcc/testsuite/gcc.dg/vect/slp-cond-2.c new file mode 100644 index 00000000000..c73933fce0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-cond-2.c @@ -0,0 +1,127 @@ +/* { dg-require-effective-target vect_cond_mixed } */ +#include "tree-vect.h" + +#define N 32 +int d[N], e[N], f[N]; +unsigned char k[N]; +float a[N], b[N]; + +__attribute__((noinline, noclone)) void +f1 (void) +{ + int i; + for (i = 0; i < N/4; i++) + { + k[4*i] = a[4*i] < b[4*i] ? 17 : 0; + k[4*i+1] = a[4*i+1] < b[4*i+1] ? 17 : 0; + k[4*i+2] = a[4*i+2] < b[4*i+2] ? 17 : 0; + k[4*i+3] = a[4*i+3] < b[4*i+3] ? 17 : 0; + } +} + +__attribute__((noinline, noclone)) void +f2 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + k[2*i] = a[2*i] < b[2*i] ? 0 : 24; + k[2*i+1] = a[2*i+1] < b[2*i+1] ? 7 : 4; + } +} + +__attribute__((noinline, noclone)) void +f3 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + k[2*i] = a[2*i] < b[2*i] ? 51 : 12; + k[2*i+1] = a[2*i+1] > b[2*i+1] ? 51 : 12; + } +} + +__attribute__((noinline, noclone)) void +f4 (void) +{ + int i; + for (i = 0; i < N/2; ++i) + { + int d0 = d[2*i], e0 = e[2*i]; + int d1 = d[2*i+1], e1 = e[2*i+1]; + f[2*i] = a[2*i] >= b[2*i] ? d0 : e0; + f[2*i+1] = a[2*i+1] >= b[2*i+1] ? d1 : e1; + } +} + +int +main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break; + case 1: a[i] = 0; b[i] = 0; break; + case 2: a[i] = i + 1; b[i] = - i - 1; break; + case 3: a[i] = i; b[i] = i + 7; break; + case 4: a[i] = i; b[i] = i; break; + case 5: a[i] = i + 16; b[i] = i + 3; break; + case 6: a[i] = - i - 5; b[i] = - i; break; + case 7: a[i] = - i; b[i] = - i; break; + case 8: a[i] = - i; b[i] = - i - 7; break; + } + d[i] = i; + e[i] = 2 * i; + } + + f1 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? 17 : 0)) + abort (); + + f2 (); + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: + case 6: + if (k[i] != ((i/9 % 2) == 0 ? 0 : 7)) + abort (); + break; + case 1: + case 5: + case 7: + if (k[i] != ((i/9 % 2) == 0 ? 4 : 24)) + abort (); + break; + case 2: + case 4: + case 8: + if (k[i] != ((i/9 % 2) == 0 ? 24 : 4)) + abort (); + break; + case 3: + if (k[i] != ((i/9 % 2) == 0 ? 7 : 0)) + abort (); + break; + } + } + + f3 (); + + f4 (); + for (i = 0; i < N; i++) + if (f[i] != ((i % 3) == 0 ? e[i] : d[i])) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/weak/typeof-2.c b/gcc/testsuite/gcc.dg/weak/typeof-2.c index 63f427fc8c9..d13235fd972 100644 --- a/gcc/testsuite/gcc.dg/weak/typeof-2.c +++ b/gcc/testsuite/gcc.dg/weak/typeof-2.c @@ -5,6 +5,9 @@ /* { dg-require-weak "" } */ /* { dg-require-alias "" } */ /* { dg-options "-O2" } */ +/* Using -mshort-calls avoids loading the function addresses in + registers and thus getting the counts wrong. */ +/* { dg-additional-options "-mshort-calls" { target epiphany-*-* } } */ extern int foo1 (int x) __asm ("baz1"); int bar1 (int x) { return x; } diff --git a/gcc/testsuite/gcc.misc-tests/gcov-12.c b/gcc/testsuite/gcc.misc-tests/gcov-12.c new file mode 100644 index 00000000000..1898aadb4ce --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-12.c @@ -0,0 +1,17 @@ +/* Test gcov weak ellision. */ + +/* { dg-options "-fprofile-arcs -ftest-coverage" } */ +/* { dg-require-weak "" } */ +/* { dg-do run { target native } } */ + +int __attribute__ ((weak)) weak () +{ + return 0; /* count(1) */ +} + +int main () +{ + return weak (); /* count(1) */ +} + +/* { dg-final { run-gcov { -a gcov-12.c } } } */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov-13.c b/gcc/testsuite/gcc.misc-tests/gcov-13.c new file mode 100644 index 00000000000..605d4d4b382 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-13.c @@ -0,0 +1,18 @@ +/* Test gcov weak ellision. */ + +/* { dg-options "-fprofile-arcs -ftest-coverage" } */ +/* { dg-require-weak "" } */ +/* { dg-do run { target native } } */ +/* { dg-additional-sources "gcovpart-13b.c" } */ + +int __attribute__ ((weak)) weak () +{ + return 1; /* count(-) */ +} + +int main () +{ + return weak (); /* count(1) */ +} + +/* { dg-final { run-gcov { -a gcov-13.c } } } */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov-14.c b/gcc/testsuite/gcc.misc-tests/gcov-14.c new file mode 100644 index 00000000000..0eaf284a9c4 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-14.c @@ -0,0 +1,24 @@ +/* Test gcov extern inline. */ + +/* { dg-options "-O2 -fprofile-arcs -ftest-coverage" } */ +/* { dg-require-weak "" } */ +/* { dg-do run { target native } } */ + +extern int __attribute__ ((weak)) Foo (); + +extern __inline int Foo () +{ + return 0; /* count(-) */ +} + +int (* __attribute__ ((noinline)) Bar ()) () +{ + return Foo; /* count(1) */ +} + +int main () +{ + return Bar () != 0; /* count(1) */ +} + +/* { dg-final { run-gcov { -a gcov-14.c } } } */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov.exp b/gcc/testsuite/gcc.misc-tests/gcov.exp index d433b996392..85a1c34abd9 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov.exp +++ b/gcc/testsuite/gcc.misc-tests/gcov.exp @@ -33,7 +33,7 @@ if { ![is_remote host] && [string match "*/*" [lindex $GCC_UNDER_TEST 0]] } { dg-init # Delete old .gcda files. -set files [glob -nocomplain gcov-*.gcda] +set files [glob -nocomplain gcov*.gcda] if { $files != "" } { eval "remote_file build delete $files" } diff --git a/gcc/testsuite/gcc.misc-tests/gcovpart-13b.c b/gcc/testsuite/gcc.misc-tests/gcovpart-13b.c new file mode 100644 index 00000000000..0900ab48021 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcovpart-13b.c @@ -0,0 +1,4 @@ +int weak () +{ + return 0; /* count(1) */ +} diff --git a/gcc/testsuite/gcc.target/arm/stack-red-zone.c b/gcc/testsuite/gcc.target/arm/stack-red-zone.c new file mode 100644 index 00000000000..b9f0f99371e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/stack-red-zone.c @@ -0,0 +1,12 @@ +/* No stack red zone. PR38644. */ +/* { dg-options "-mthumb -O2" } */ +/* { dg-final { scan-assembler "ldrb\[^\n\]*\\n\[\t \]*add\[\t \]*sp" } } */ + +extern int doStreamReadBlock (int *, char *, int size, int); + +char readStream (int *s) +{ + char c = 0; + doStreamReadBlock (s, &c, 1, *s); + return c; +} diff --git a/gcc/testsuite/gcc.target/arm/wmul-1.c b/gcc/testsuite/gcc.target/arm/wmul-1.c index 426c9393f20..ddddd509fe6 100644 --- a/gcc/testsuite/gcc.target/arm/wmul-1.c +++ b/gcc/testsuite/gcc.target/arm/wmul-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_dsp } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O1 -fexpensive-optimizations" } */ int mac(const short *a, const short *b, int sqr, int *sum) { diff --git a/gcc/testsuite/gcc.target/arm/wmul-2.c b/gcc/testsuite/gcc.target/arm/wmul-2.c index 898b5f065cb..2ea55f9fbe1 100644 --- a/gcc/testsuite/gcc.target/arm/wmul-2.c +++ b/gcc/testsuite/gcc.target/arm/wmul-2.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_dsp } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O1 -fexpensive-optimizations" } */ void vec_mpy(int y[], const short x[], short scaler) { diff --git a/gcc/testsuite/gcc.target/arm/wmul-3.c b/gcc/testsuite/gcc.target/arm/wmul-3.c index 83f73fba727..144b553082e 100644 --- a/gcc/testsuite/gcc.target/arm/wmul-3.c +++ b/gcc/testsuite/gcc.target/arm/wmul-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_dsp } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O1 -fexpensive-optimizations" } */ int mac(const short *a, const short *b, int sqr, int *sum) { diff --git a/gcc/testsuite/gcc.target/arm/wmul-4.c b/gcc/testsuite/gcc.target/arm/wmul-4.c index a297bda2182..68f9866746d 100644 --- a/gcc/testsuite/gcc.target/arm/wmul-4.c +++ b/gcc/testsuite/gcc.target/arm/wmul-4.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_dsp } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O1 -fexpensive-optimizations" } */ int mac(const int *a, const int *b, long long sqr, long long *sum) { diff --git a/gcc/testsuite/gcc.target/epiphany/epiphany.exp b/gcc/testsuite/gcc.target/epiphany/epiphany.exp new file mode 100644 index 00000000000..dc9fecc728e --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/epiphany.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2007, 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an epiphany target. +if ![istarget epiphany*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/epiphany/fmadd-1.c b/gcc/testsuite/gcc.target/epiphany/fmadd-1.c new file mode 100644 index 00000000000..868d5bd0226 --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/fmadd-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "fmadd\[ \ta-zA-Z0-9\]*," 2 } } */ + +#include <epiphany_intrinsics.h> + +float +f1 (float a, float b, float c) +{ + return __builtin_epiphany_fmadd (a, b, c); +} + +float +f2 (float a, float b, float c) +{ + return a + b * c; +} diff --git a/gcc/testsuite/gcc.target/epiphany/fmsub-1.c b/gcc/testsuite/gcc.target/epiphany/fmsub-1.c new file mode 100644 index 00000000000..ff7fefa7f20 --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/fmsub-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "fmsub\[ \ta-zA-Z0-9\]*," 2 } } */ + +#include <epiphany_intrinsics.h> + +float +f1 (float a, float b, float c) +{ + return __builtin_epiphany_fmsub (a, b, c); +} + +float +f2 (float a, float b, float c) +{ + return a - b * c; +} diff --git a/gcc/testsuite/gcc.target/epiphany/interrupt.c b/gcc/testsuite/gcc.target/epiphany/interrupt.c new file mode 100644 index 00000000000..a44c79e432e --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/interrupt.c @@ -0,0 +1,14 @@ +void __attribute__((interrupt("dma0"))) +f (void) +{ +} + +void __attribute__((interrupt("Vss"))) +g (void) +{ /* { dg-warning "is not \"reset\"" } */ +} + +void __attribute__((interrupt(42))) +h (void) +{ /* { dg-warning "is not a string constant" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/47698.c b/gcc/testsuite/gcc.target/i386/47698.c new file mode 100644 index 00000000000..2c751093ae3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/47698.c @@ -0,0 +1,10 @@ +/* { dg-options "-Os" } */ +/* { dg-final { scan-assembler-not "cmov" } } */ + +extern volatile unsigned long mmio; +unsigned long foo(int cond) +{ + if (cond) + return mmio; + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/avx-cvt-2.c b/gcc/testsuite/gcc.target/i386/avx-cvt-2.c index 78c6398f341..68206f5a0e7 100644 --- a/gcc/testsuite/gcc.target/i386/avx-cvt-2.c +++ b/gcc/testsuite/gcc.target/i386/avx-cvt-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -mavx -mno-avx2 -fdump-tree-vect-details" } */ +/* { dg-options "-O3 -mavx -mno-avx2 -mtune=generic -fdump-tree-vect-details" } */ #include "avx-cvt-1.c" diff --git a/gcc/testsuite/gcc.target/i386/avx2-cvt-2.c b/gcc/testsuite/gcc.target/i386/avx2-cvt-2.c index 288e5601a46..4826e9b6d05 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-cvt-2.c +++ b/gcc/testsuite/gcc.target/i386/avx2-cvt-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -mavx2 -fdump-tree-vect-details" } */ +/* { dg-options "-O3 -mavx2 -mtune=generic -fdump-tree-vect-details" } */ #include "avx2-cvt-1.c" diff --git a/gcc/testsuite/gcc.target/i386/avx2-gather-1.c b/gcc/testsuite/gcc.target/i386/avx2-gather-1.c new file mode 100644 index 00000000000..7ed567dc491 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-gather-1.c @@ -0,0 +1,215 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx2 } */ +/* { dg-options "-O3 -mavx2" } */ + +#include "avx2-check.h" + +#define N 1024 +float vf1[N+16], vf2[N]; +double vd1[N+16], vd2[N]; +int k[N]; +long l[N]; +short n[N]; + +__attribute__((noinline, noclone)) void +f1 (void) +{ + int i; + for (i = 0; i < N; i++) + vf2[i] = vf1[k[i]]; +} + +__attribute__((noinline, noclone)) void +f2 (void) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vf1[k[i]]; +} + +__attribute__((noinline, noclone)) void +f3 (int x) +{ + int i; + for (i = 0; i < N; i++) + vf2[i] = vf1[k[i] + x]; +} + +__attribute__((noinline, noclone)) void +f4 (int x) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vf1[k[i] + x]; +} + +__attribute__((noinline, noclone)) void +f5 (void) +{ + int i; + for (i = 0; i < N; i++) + vd2[i] = vd1[k[i]]; +} + +__attribute__((noinline, noclone)) void +f6 (void) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vd1[k[i]]; +} + +__attribute__((noinline, noclone)) void +f7 (int x) +{ + int i; + for (i = 0; i < N; i++) + vd2[i] = vd1[k[i] + x]; +} + +__attribute__((noinline, noclone)) void +f8 (int x) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vd1[k[i] + x]; +} + +__attribute__((noinline, noclone)) void +f9 (void) +{ + int i; + for (i = 0; i < N; i++) + vf2[i] = vf1[l[i]]; +} + +__attribute__((noinline, noclone)) void +f10 (void) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vf1[l[i]]; +} + +__attribute__((noinline, noclone)) void +f11 (long x) +{ + int i; + for (i = 0; i < N; i++) + vf2[i] = vf1[l[i] + x]; +} + +__attribute__((noinline, noclone)) void +f12 (long x) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vf1[l[i] + x]; +} + +__attribute__((noinline, noclone)) void +f13 (void) +{ + int i; + for (i = 0; i < N; i++) + vd2[i] = vd1[l[i]]; +} + +__attribute__((noinline, noclone)) void +f14 (void) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vd1[l[i]]; +} + +__attribute__((noinline, noclone)) void +f15 (long x) +{ + int i; + for (i = 0; i < N; i++) + vd2[i] = vd1[l[i] + x]; +} + +__attribute__((noinline, noclone)) void +f16 (long x) +{ + int i; + for (i = 0; i < N; i++) + n[i] = (int) vd1[l[i] + x]; +} + +static void +avx2_test (void) +{ + int i; + + for (i = 0; i < N + 16; i++) + { + asm (""); + vf1[i] = 17.0f + i; + vd1[i] = 19.0 + i; + } + for (i = 0; i < N; i++) + { + asm (""); + k[i] = (i * 731) & (N - 1); + l[i] = (i * 657) & (N - 1); + } + + f1 (); + f2 (); + for (i = 0; i < N; i++) + if (vf2[i] != ((i * 731) & (N - 1)) + 17 + || n[i] != ((i * 731) & (N - 1)) + 17) + abort (); + + f3 (12); + f4 (14); + for (i = 0; i < N; i++) + if (vf2[i] != ((i * 731) & (N - 1)) + 17 + 12 + || n[i] != ((i * 731) & (N - 1)) + 17 + 14) + abort (); + + f5 (); + f6 (); + for (i = 0; i < N; i++) + if (vd2[i] != ((i * 731) & (N - 1)) + 19 + || n[i] != ((i * 731) & (N - 1)) + 19) + abort (); + + f7 (7); + f8 (9); + for (i = 0; i < N; i++) + if (vd2[i] != ((i * 731) & (N - 1)) + 19 + 7 + || n[i] != ((i * 731) & (N - 1)) + 19 + 9) + abort (); + + f9 (); + f10 (); + for (i = 0; i < N; i++) + if (vf2[i] != ((i * 657) & (N - 1)) + 17 + || n[i] != ((i * 657) & (N - 1)) + 17) + abort (); + + f11 (2); + f12 (4); + for (i = 0; i < N; i++) + if (vf2[i] != ((i * 657) & (N - 1)) + 17 + 2 + || n[i] != ((i * 657) & (N - 1)) + 17 + 4) + abort (); + + f13 (); + f14 (); + for (i = 0; i < N; i++) + if (vd2[i] != ((i * 657) & (N - 1)) + 19 + || n[i] != ((i * 657) & (N - 1)) + 19) + abort (); + + f15 (13); + f16 (15); + for (i = 0; i < N; i++) + if (vd2[i] != ((i * 657) & (N - 1)) + 19 + 13 + || n[i] != ((i * 657) & (N - 1)) + 19 + 15) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avx2-gather-2.c b/gcc/testsuite/gcc.target/i386/avx2-gather-2.c new file mode 100644 index 00000000000..8a7fe95a238 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-gather-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx2 -fdump-tree-vect-details" } */ + +#include "avx2-gather-1.c" + +/* { dg-final { scan-tree-dump-times "note: vectorized 1 loops in function" 16 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx2-gather-3.c b/gcc/testsuite/gcc.target/i386/avx2-gather-3.c new file mode 100644 index 00000000000..fb6289c0e7e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-gather-3.c @@ -0,0 +1,167 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx2 } */ +/* { dg-options "-O3 -mavx2 -ffast-math" } */ + +#include "avx2-check.h" + +#define N 1024 +float f[N]; +double d[N]; +int k[N]; +float *l[N]; +double *n[N]; +int **m[N]; +long **o[N]; +long q[N]; +long *r[N]; +int *s[N]; + +__attribute__((noinline, noclone)) float +f1 (void) +{ + int i; + float g = 0.0; + for (i = 0; i < N / 2; i++) + g += f[k[i]]; + return g; +} + +__attribute__((noinline, noclone)) float +f2 (float *p) +{ + int i; + float g = 0.0; + for (i = 0; i < N / 2; i++) + g += p[k[i]]; + return g; +} + +__attribute__((noinline, noclone)) float +f3 (void) +{ + int i; + float g = 0.0; + for (i = 0; i < N / 2; i++) + g += *l[i]; + return g; +} + +__attribute__((noinline, noclone)) int +f4 (void) +{ + int i; + int g = 0; + for (i = 0; i < N / 2; i++) + g += **m[i]; + return g; +} + +__attribute__((noinline, noclone)) double +f5 (void) +{ + int i; + double g = 0.0; + for (i = 0; i < N / 2; i++) + g += d[k[i]]; + return g; +} + +__attribute__((noinline, noclone)) double +f6 (double *p) +{ + int i; + double g = 0.0; + for (i = 0; i < N / 2; i++) + g += p[k[i]]; + return g; +} + +__attribute__((noinline, noclone)) double +f7 (void) +{ + int i; + double g = 0.0; + for (i = 0; i < N / 2; i++) + g += *n[i]; + return g; +} + +__attribute__((noinline, noclone)) int +f8 (void) +{ + int i; + int g = 0; + for (i = 0; i < N / 2; i++) + g += **o[i]; + return g; +} + +__attribute__((noinline, noclone)) float +f9 (void) +{ + int i; + float g = 0.0; + for (i = 0; i < N / 2; i++) + g += f[q[i]]; + return g; +} + +__attribute__((noinline, noclone)) float +f10 (float *p) +{ + int i; + float g = 0.0; + for (i = 0; i < N / 2; i++) + g += p[q[i]]; + return g; +} + +__attribute__((noinline, noclone)) double +f11 (void) +{ + int i; + double g = 0.0; + for (i = 0; i < N / 2; i++) + g += d[q[i]]; + return g; +} + +__attribute__((noinline, noclone)) double +f12 (double *p) +{ + int i; + double g = 0.0; + for (i = 0; i < N / 2; i++) + g += p[q[i]]; + return g; +} + +static void +avx2_test (void) +{ + int i; + + for (i = 0; i < N; i++) + { + asm (""); + f[i] = -256.0f + i; + d[i] = -258.0 + i; + k[i] = (i * 731) & (N - 1); + q[i] = (i * 657) & (N - 1); + l[i] = &f[(i * 239) & (N - 1)]; + n[i] = &d[(i * 271) & (N - 1)]; + r[i] = &q[(i * 323) & (N - 1)]; + s[i] = &k[(i * 565) & (N - 1)]; + m[i] = &s[(i * 13) & (N - 1)]; + o[i] = &r[(i * 19) & (N - 1)]; + } + + if (f1 () != 136448.0f || f2 (f) != 136448.0f || f3 () != 130304.0) + abort (); + if (f4 () != 261376 || f5 () != 135424.0 || f6 (d) != 135424.0) + abort (); + if (f7 () != 129280.0 || f8 () != 259840L || f9 () != 130816.0f) + abort (); + if (f10 (f) != 130816.0f || f11 () != 129792.0 || f12 (d) != 129792.0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avx2-gather-4.c b/gcc/testsuite/gcc.target/i386/avx2-gather-4.c new file mode 100644 index 00000000000..440a9c9b164 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-gather-4.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx2 } */ +/* { dg-options "-O3 -mavx2" } */ + +#include "avx2-check.h" + +#define N 1024 +int a[N], b[N], c[N], d[N]; + +__attribute__((noinline, noclone)) void +foo (float *__restrict p, float *__restrict q, float *__restrict r, + long s1, long s2, long s3) +{ + int i; + for (i = 0; i < N; i++) + p[i] = q[a[i] * s1 + b[i] * s2 + s3] * r[c[i] * s1 + d[i] * s2 + s3]; +} + +static void +avx2_test (void) +{ + int i; + float e[N], f[N], g[N]; + for (i = 0; i < N; i++) + { + a[i] = (i * 7) & (N / 8 - 1); + b[i] = (i * 13) & (N / 8 - 1); + c[i] = (i * 23) & (N / 8 - 1); + d[i] = (i * 5) & (N / 8 - 1); + e[i] = 16.5 + i; + f[i] = 127.5 - i; + } + foo (g, e, f, 3, 2, 4); + for (i = 0; i < N; i++) + if (g[i] != (float) ((20.5 + a[i] * 3 + b[i] * 2) + * (123.5 - c[i] * 3 - d[i] * 2))) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr49781-1.c b/gcc/testsuite/gcc.target/i386/pr49781-1.c index 80db03416e5..60f9d50d866 100644 --- a/gcc/testsuite/gcc.target/i386/pr49781-1.c +++ b/gcc/testsuite/gcc.target/i386/pr49781-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fpic" } */ +/* { dg-options "-O2 -fpic -mtune=generic" } */ /* { dg-require-effective-target fpic } */ static int heap[2*(256 +1+29)+1]; diff --git a/gcc/testsuite/gcc.target/i386/sse2-cvt-2.c b/gcc/testsuite/gcc.target/i386/sse2-cvt-2.c index 9c4519544ca..00f13254c22 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-cvt-2.c +++ b/gcc/testsuite/gcc.target/i386/sse2-cvt-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -msse2 -mno-sse3 -fdump-tree-vect-details" } */ +/* { dg-options "-O3 -msse2 -mno-sse3 -mtune=generic -fdump-tree-vect-details" } */ #include "sse2-cvt-1.c" diff --git a/gcc/testsuite/gcc.target/i386/vectorize4-avx.c b/gcc/testsuite/gcc.target/i386/vectorize4-avx.c index 8e4a747a64b..33e99189373 100644 --- a/gcc/testsuite/gcc.target/i386/vectorize4-avx.c +++ b/gcc/testsuite/gcc.target/i386/vectorize4-avx.c @@ -11,4 +11,4 @@ calc_freq (int *dest) dest[i] = sqrt (tmp_out[i]); } -/* { dg-final { scan-assembler "vsqrtpd\[ \\t\]+\[^\n\]*%ymm" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler "vsqrtpd\[ \\t\]+\[^\n\]*%ymm" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/20111102-1.c b/gcc/testsuite/gcc.target/sparc/20111102-1.c new file mode 100644 index 00000000000..d33f103e377 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/20111102-1.c @@ -0,0 +1,17 @@ +/* PR target/50945 */ +/* { dg-do compile } */ +/* { dg-options "-O -msoft-float" } */ + +double +__powidf2 (double x, int m) +{ + unsigned int n = m < 0 ? -m : m; + double y = n % 2 ? x : 1; + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + return m < 0 ? 1/y : y; +} diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-1-vis1.c b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis1.c new file mode 100644 index 00000000000..4202bfa6e72 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis1.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_hw } */ +/* { dg-options "-mcpu=ultrasparc -mvis -O2" } */ + +#include "vec-init-1.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-1-vis2.c b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis2.c new file mode 100644 index 00000000000..a5c21323936 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis2.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis2_hw } */ +/* { dg-options "-mcpu=ultrasparc3 -O2" } */ + +#include "vec-init-1.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-1-vis3.c b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis3.c new file mode 100644 index 00000000000..ab916e052cc --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-1-vis3.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis3_hw } */ +/* { dg-options "-mcpu=niagara3 -O2" } */ + +#include "vec-init-1.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-1.inc b/gcc/testsuite/gcc.target/sparc/vec-init-1.inc new file mode 100644 index 00000000000..e27bb6e293b --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-1.inc @@ -0,0 +1,85 @@ +typedef int __v1si __attribute__ ((__vector_size__ (4))); +typedef int __v2si __attribute__ ((__vector_size__ (8))); +typedef short __v2hi __attribute__ ((__vector_size__ (4))); +typedef short __v4hi __attribute__ ((__vector_size__ (8))); +typedef unsigned char __v4qi __attribute__ ((__vector_size__ (4))); +typedef unsigned char __v8qi __attribute__ ((__vector_size__ (8))); + +extern void abort (void); + +static void +compare64 (void *p, unsigned long long val) +{ + if (*(unsigned long long *)p != val) + abort(); +} + +static void +compare32 (void *p, unsigned int val) +{ + if (*(unsigned int *)p != val) + abort(); +} + +static void +test_v8qi (unsigned char x) +{ + __v8qi v = { x, x, x, x, x, x, x, x }; + + compare64(&v, 0x4444444444444444ULL); +} + +static void +test_v4qi (unsigned char x) +{ + __v4qi v = { x, x, x, x }; + + compare32(&v, 0x44444444); +} + +static void +test_v4hi (unsigned short x) +{ + __v4hi v = { x, x, x, x, }; + + compare64(&v, 0x3344334433443344ULL); +} + +static void +test_v2hi (unsigned short x) +{ + __v2hi v = { x, x, }; + + compare32(&v, 0x33443344); +} + +static void +test_v2si (unsigned int x) +{ + __v2si v = { x, x, }; + + compare64(&v, 0x1122334411223344ULL); +} + +static void +test_v1si (unsigned int x) +{ + __v1si v = { x }; + + compare32(&v, 0x11223344); +} + +unsigned char x8 = 0x44; +unsigned short x16 = 0x3344; +unsigned int x32 = 0x11223344; + +int main(void) +{ + test_v8qi (x8); + test_v4qi (x8); + test_v4hi (x16); + test_v2hi (x16); + test_v2si (x32); + test_v1si (x32); + return 0; +} diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-2-vis1.c b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis1.c new file mode 100644 index 00000000000..efa08fa248c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis1.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_hw } */ +/* { dg-options "-mcpu=ultrasparc -mvis -O2" } */ + +#include "vec-init-2.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-2-vis2.c b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis2.c new file mode 100644 index 00000000000..3aa0f51595f --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis2.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis2_hw } */ +/* { dg-options "-mcpu=ultrasparc3 -O2" } */ + +#include "vec-init-2.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-2-vis3.c b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis3.c new file mode 100644 index 00000000000..5f0c65860bc --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-2-vis3.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis3_hw } */ +/* { dg-options "-mcpu=niagara3 -O2" } */ + +#include "vec-init-2.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-2.inc b/gcc/testsuite/gcc.target/sparc/vec-init-2.inc new file mode 100644 index 00000000000..13685a1006e --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-2.inc @@ -0,0 +1,94 @@ +typedef short __v2hi __attribute__ ((__vector_size__ (4))); +typedef short __v4hi __attribute__ ((__vector_size__ (8))); + +extern void abort (void); + +static void +compare64 (int n, void *p, unsigned long long val) +{ + unsigned long long *x = (unsigned long long *) p; + + if (*x != val) + abort(); +} + +static void +compare32 (int n, void *p, unsigned int val) +{ + unsigned int *x = (unsigned int *) p; + if (*x != val) + abort(); +} + +#define V2HI_TEST(N, elt0, elt1) \ +static void \ +test_v2hi_##N (unsigned short x, unsigned short y) \ +{ \ + __v2hi v = { (elt0), (elt1) }; \ + compare32(N, &v, ((int)(elt0) << 16) | (elt1)); \ +} + +V2HI_TEST(1, x, y) +V2HI_TEST(2, y, x) +V2HI_TEST(3, x, x) +V2HI_TEST(4, x, 0) +V2HI_TEST(5, 0, x) +V2HI_TEST(6, y, 1) +V2HI_TEST(7, 1, y) +V2HI_TEST(8, 2, 3) +V2HI_TEST(9, 0x400, x) +V2HI_TEST(10, y, 0x8000) + +#define V4HI_TEST(N, elt0, elt1, elt2, elt3) \ +static void \ +test_v4hi_##N (unsigned short a, unsigned short b, unsigned short c, unsigned short d) \ +{ \ + __v4hi v = { (elt0), (elt1), (elt2), (elt3) }; \ + compare64(N, &v, \ + ((long long)(elt0) << 48) | \ + ((long long)(elt1) << 32) | \ + ((long long)(elt2) << 16) | \ + ((long long)(elt3))); \ +} + +V4HI_TEST(1, a, a, a, a) +V4HI_TEST(2, a, b, c, d) +V4HI_TEST(3, a, a, b, b) +V4HI_TEST(4, d, c, b, a) +V4HI_TEST(5, a, 0, 0, 0) +V4HI_TEST(6, a, 0, b, 0) +V4HI_TEST(7, c, 5, 5, 5) +V4HI_TEST(8, d, 6, a, 6) +V4HI_TEST(9, 0x200, 0x300, 0x500, 0x8800) +V4HI_TEST(10, 0x600, a, a, a) + +unsigned short a16 = 0x3344; +unsigned short b16 = 0x5566; +unsigned short c16 = 0x7788; +unsigned short d16 = 0x9911; + +int main(void) +{ + test_v2hi_1 (a16, b16); + test_v2hi_2 (a16, b16); + test_v2hi_3 (a16, b16); + test_v2hi_4 (a16, b16); + test_v2hi_5 (a16, b16); + test_v2hi_6 (a16, b16); + test_v2hi_7 (a16, b16); + test_v2hi_8 (a16, b16); + test_v2hi_9 (a16, b16); + test_v2hi_10 (a16, b16); + + test_v4hi_1 (a16, b16, c16, d16); + test_v4hi_2 (a16, b16, c16, d16); + test_v4hi_3 (a16, b16, c16, d16); + test_v4hi_4 (a16, b16, c16, d16); + test_v4hi_5 (a16, b16, c16, d16); + test_v4hi_6 (a16, b16, c16, d16); + test_v4hi_7 (a16, b16, c16, d16); + test_v4hi_8 (a16, b16, c16, d16); + test_v4hi_9 (a16, b16, c16, d16); + test_v4hi_10 (a16, b16, c16, d16); + return 0; +} diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-3-vis1.c b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis1.c new file mode 100644 index 00000000000..6c826108c29 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis1.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_hw } */ +/* { dg-options "-mcpu=ultrasparc -mvis -O2" } */ + +#include "vec-init-3.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-3-vis2.c b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis2.c new file mode 100644 index 00000000000..6424e2f1592 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis2.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis2_hw } */ +/* { dg-options "-mcpu=ultrasparc3 -O2" } */ + +#include "vec-init-3.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-3-vis3.c b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis3.c new file mode 100644 index 00000000000..226c108c5e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-3-vis3.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ultrasparc_vis3_hw } */ +/* { dg-options "-mcpu=niagara3 -O2" } */ + +#include "vec-init-3.inc" diff --git a/gcc/testsuite/gcc.target/sparc/vec-init-3.inc b/gcc/testsuite/gcc.target/sparc/vec-init-3.inc new file mode 100644 index 00000000000..8a3db2600a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/vec-init-3.inc @@ -0,0 +1,105 @@ +typedef unsigned char __v4qi __attribute__ ((__vector_size__ (4))); +typedef unsigned char __v8qi __attribute__ ((__vector_size__ (8))); + +extern void abort (void); + +static void +compare64 (int n, void *p, unsigned long long val) +{ + unsigned long long *x = (unsigned long long *) p; + + if (*x != val) + abort(); +} + +static void +compare32 (int n, void *p, unsigned int val) +{ + unsigned int *x = (unsigned int *) p; + if (*x != val) + abort(); +} + +#define V4QI_TEST(N, elt0, elt1, elt2, elt3) \ +static void \ +test_v4qi_##N (unsigned char a, unsigned char b, unsigned char c, unsigned char d) \ +{ \ + __v4qi v = { (elt0), (elt1), (elt2), (elt3) }; \ + compare32(N, &v, ((int)(elt0) << 24) | \ + ((int)(elt1) << 16) | \ + ((int)(elt2) << 8) | ((int)(elt3))); \ +} + +V4QI_TEST(1, a, a, a, a) +V4QI_TEST(2, b, b, b, b) +V4QI_TEST(3, a, b, c, d) +V4QI_TEST(4, d, c, b, a) +V4QI_TEST(5, a, 0, 0, 0) +V4QI_TEST(6, b, 1, 1, b) +V4QI_TEST(7, c, 5, d, 5) +V4QI_TEST(8, 0x20, 0x30, b, a) +V4QI_TEST(9, 0x40, 0x50, 0x60, 0x70) +V4QI_TEST(10, 0x40, 0x50, 0x60, c) + +#define V8QI_TEST(N, elt0, elt1, elt2, elt3, elt4, elt5, elt6, elt7) \ +static void \ +test_v8qi_##N (unsigned char a, unsigned char b, unsigned char c, unsigned char d, \ + unsigned char e, unsigned char f, unsigned char g, unsigned char h) \ +{ \ + __v8qi v = { (elt0), (elt1), (elt2), (elt3), \ + (elt4), (elt5), (elt6), (elt7) }; \ + compare64(N, &v, ((long long)(elt0) << 56) | \ + ((long long)(elt1) << 48) | \ + ((long long)(elt2) << 40) | \ + ((long long)(elt3) << 32) | \ + ((long long)(elt4) << 24) | \ + ((long long)(elt5) << 16) | \ + ((long long)(elt6) << 8) | \ + ((long long)(elt7) << 0)); \ +} + +V8QI_TEST(1, a, a, a, a, a, a, a, a) +V8QI_TEST(2, a, b, c, d, e, f, g, h) +V8QI_TEST(3, h, g, f, e, d, c, b, a) +V8QI_TEST(4, a, b, a, b, a, b, a, b) +V8QI_TEST(5, c, b, c, b, c, b, c, a) +V8QI_TEST(6, a, 0, 0, 0, 0, 0, 0, 0) +V8QI_TEST(7, b, 1, b, 1, b, 1, b, 1) +V8QI_TEST(8, c, d, 0x20, a, 0x21, b, 0x23, c) +V8QI_TEST(9, 1, 2, 3, 4, 5, 6, 7, 8) +V8QI_TEST(10, a, a, b, b, c, c, d, d) + +unsigned char a8 = 0x33; +unsigned char b8 = 0x55; +unsigned char c8 = 0x77; +unsigned char d8 = 0x99; +unsigned char e8 = 0x11; +unsigned char f8 = 0x22; +unsigned char g8 = 0x44; +unsigned char h8 = 0x66; + +int main(void) +{ + test_v4qi_1 (a8, b8, c8, d8); + test_v4qi_2 (a8, b8, c8, d8); + test_v4qi_3 (a8, b8, c8, d8); + test_v4qi_4 (a8, b8, c8, d8); + test_v4qi_5 (a8, b8, c8, d8); + test_v4qi_6 (a8, b8, c8, d8); + test_v4qi_7 (a8, b8, c8, d8); + test_v4qi_8 (a8, b8, c8, d8); + test_v4qi_9 (a8, b8, c8, d8); + test_v4qi_10 (a8, b8, c8, d8); + + test_v8qi_1 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_2 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_3 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_4 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_5 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_6 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_7 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_8 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_9 (a8, b8, c8, d8, e8, f8, g8, h8); + test_v8qi_10 (a8, b8, c8, d8, e8, f8, g8, h8); + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_5.f90 b/gcc/testsuite/gfortran.dg/bind_c_dts_5.f90 new file mode 100644 index 00000000000..497c0501b11 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_5.f90 @@ -0,0 +1,54 @@ +! { dg-do compile } +! +! PR fortran/50933 +! +! Check whether type-compatibility checks for BIND(C) work. +! +! Contributed by Richard Maine +! + +MODULE liter_cb_mod +USE ISO_C_BINDING +CONTAINS + FUNCTION liter_cb(link_info) bind(C) + USE ISO_C_BINDING + IMPLICIT NONE + + INTEGER(c_int) liter_cb + + TYPE, bind(C) :: info_t + INTEGER(c_int) :: type + END TYPE info_t + + TYPE(info_t) :: link_info + + liter_cb = 0 + + END FUNCTION liter_cb + +END MODULE liter_cb_mod + +PROGRAM main + USE ISO_C_BINDING + interface + FUNCTION liter_cb(link_info) bind(C) + USE ISO_C_BINDING + IMPLICIT NONE + INTEGER(c_int) liter_cb + TYPE, bind(C) :: info_t + INTEGER(c_int) :: type + END TYPE info_t + TYPE(info_t) :: link_info + END FUNCTION liter_cb + end interface + + TYPE, bind(C) :: info_t + INTEGER(c_int) :: type + END TYPE info_t + type(info_t) :: link_info + + write (*,*) liter_cb(link_info) + +END PROGRAM main + +! { dg-final { cleanup-modules "liter_cb_mod" } } diff --git a/gcc/testsuite/gfortran.dg/function_optimize_7.f90 b/gcc/testsuite/gfortran.dg/function_optimize_7.f90 index 212c8fbd491..e0c404b6a2a 100644 --- a/gcc/testsuite/gfortran.dg/function_optimize_7.f90 +++ b/gcc/testsuite/gfortran.dg/function_optimize_7.f90 @@ -12,6 +12,7 @@ subroutine xx(n, m, a, b, c, d, x, z, i, s_in, s_out) real, intent(out) :: z character(60) :: line real, external :: ext_func + integer :: one = 1 interface elemental function element(x) real, intent(in) :: x @@ -33,7 +34,7 @@ subroutine xx(n, m, a, b, c, d, x, z, i, s_in, s_out) z = element(x) + element(x) i = mypure(x) - mypure(x) z = elem_impure(x) - elem_impure(x) - s_out = sum(s_in,1) + 3.14 / sum(s_in,1) ! { dg-warning "Creating array temporary" } + s_out = sum(s_in,one) + 3.14 / sum(s_in,one) ! { dg-warning "Creating array temporary" } end subroutine xx ! { dg-final { scan-tree-dump-times "matmul_r4" 1 "original" } } ! { dg-final { scan-tree-dump-times "__builtin_sinf" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/inline_product_1.f90 b/gcc/testsuite/gfortran.dg/inline_product_1.f90 new file mode 100644 index 00000000000..72c096bff4a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_product_1.f90 @@ -0,0 +1,32 @@ +! { dg-do compile } +! { dg-options "-Warray-temporaries -O -fdump-tree-original" } +! +! PR fortran/43829 +! Scalarization of reductions. +! Test that product is properly inlined. + +! For more extended tests, see inline_sum_1.f90 + + implicit none + + + integer :: i + + integer, parameter :: q = 2 + integer, parameter :: nx=3, ny=2*q, nz=5 + integer, parameter, dimension(nx,ny,nz) :: p = & + & reshape ((/ (i, i=1,size(p)) /), shape(p)) + + + integer, dimension(nx,ny,nz) :: a + integer, dimension(nx, nz) :: ay + + a = p + + ay = product(a,2) + +end +! { dg-final { scan-tree-dump-times "struct array._integer\\(kind=4\\) atmp" 0 "original" } } +! { dg-final { scan-tree-dump-times "struct array\[^\\n\]*atmp" 0 "original" } } +! { dg-final { scan-tree-dump-times "_gfortran_product_" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/inline_sum_1.f90 b/gcc/testsuite/gfortran.dg/inline_sum_1.f90 new file mode 100644 index 00000000000..4538e5e117f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_sum_1.f90 @@ -0,0 +1,194 @@ +! { dg-do compile } +! { dg-options "-Warray-temporaries -O -fdump-tree-original" } +! +! PR fortran/43829 +! Scalarization of reductions. +! Test that sum is properly inlined. + +! This is the compile time test only; for the runtime test see inline_sum_2.f90 +! We can't test for temporaries on the run time test directly, as it tries +! several optimization options among which -Os, and sum inlining is disabled +! at -Os. + + + implicit none + + + integer :: i, j, k + + integer, parameter :: q = 2 + integer, parameter :: nx=3, ny=2*q, nz=5 + integer, parameter, dimension(nx,ny,nz) :: p = & + & reshape ((/ (i**2, i=1,size(p)) /), shape(p)) + + integer, parameter, dimension( ny,nz) :: px = & + & reshape ((/ (( & + & nx*( nx*j+nx*ny*k+1)*( nx*j+nx*ny*k+1+ (nx-1)) & + & + nx*(nx-1)*(2*nx-1)/6, & + & j=0,ny-1), k=0,nz-1) /), shape(px)) + + integer, parameter, dimension(nx, nz) :: py = & + & reshape ((/ (( & + & ny*(i +nx*ny*k+1)*(i +nx*ny*k+1+nx *(ny-1)) & + & +(nx )**2*ny*(ny-1)*(2*ny-1)/6, & + & i=0,nx-1), k=0,nz-1) /), shape(py)) + + integer, parameter, dimension(nx,ny ) :: pz = & + & reshape ((/ (( & + & nz*(i+nx*j +1)*(i+nx*j +1+nx*ny*(nz-1)) & + & +(nx*ny)**2*nz*(nz-1)*(2*nz-1)/6, & + & i=0,nx-1), j=0,ny-1) /), shape(pz)) + + + integer, dimension(nx,ny,nz) :: a + integer, dimension( ny,nz) :: ax + integer, dimension(nx, nz) :: ay + integer, dimension(nx,ny ) :: az + + logical, dimension(nx,ny,nz) :: m, true + + + integer, dimension(nx,ny) :: b + + integer, dimension(nx,nx) :: onesx + integer, dimension(ny,ny) :: onesy + integer, dimension(nz,nz) :: onesz + + + a = p + m = reshape((/ ((/ .true., .false. /), i=1,size(m)/2) /), shape(m)) + true = reshape((/ (.true., i=1,size(true)) /), shape(true)) + + onesx = reshape((/ ((1, j=1,i),(0,j=1,nx-i),i=1,size(onesx,2)) /), shape(onesx)) + onesy = reshape((/ ((1, j=1,i),(0,j=1,ny-i),i=1,size(onesy,2)) /), shape(onesy)) + onesz = reshape((/ ((1, j=1,i),(0,j=1,nz-i),i=1,size(onesz,2)) /), shape(onesz)) + + ! Correct results in simple cases + ax = sum(a,1) + if (any(ax /= px)) call abort + + ay = sum(a,2) + if (any(ay /= py)) call abort + + az = sum(a,3) + if (any(az /= pz)) call abort + + + ! Masks work + if (any(sum(a,1,.false.) /= 0)) call abort + if (any(sum(a,2,.true.) /= py)) call abort + if (any(sum(a,3,m) /= merge(pz,0,m(:,:,1)))) call abort + if (any(sum(a,2,m) /= merge(sum(a(:, ::2,:),2),& + sum(a(:,2::2,:),2),& + m(:,1,:)))) call abort + + + ! It works too with array constructors ... + if (any(sum( & + reshape((/ (i*i,i=1,size(a)) /), shape(a)), & + 1, & + true) /= ax)) call abort + + ! ... and with vector subscripts + if (any(sum( & + a((/ (i,i=1,nx) /), & + (/ (i,i=1,ny) /), & + (/ (i,i=1,nz) /)), & + 1) /= ax)) call abort + + if (any(sum( & + a(sum(onesx(:,:),1), & ! unnecessary { dg-warning "Creating array temporary" } + sum(onesy(:,:),1), & ! unnecessary { dg-warning "Creating array temporary" } + sum(onesz(:,:),1)), & ! unnecessary { dg-warning "Creating array temporary" } + 1) /= ax)) call abort + + + ! Nested sums work + if (sum(sum(sum(a,1),1),1) /= sum(a)) call abort + if (sum(sum(sum(a,1),2),1) /= sum(a)) call abort + if (sum(sum(sum(a,3),1),1) /= sum(a)) call abort + if (sum(sum(sum(a,3),2),1) /= sum(a)) call abort + + if (any(sum(sum(a,1),1) /= sum(sum(a,2),1))) call abort + if (any(sum(sum(a,1),2) /= sum(sum(a,3),1))) call abort + if (any(sum(sum(a,2),2) /= sum(sum(a,3),2))) call abort + + + ! Temps are unavoidable here (function call's argument or result) + ax = sum(neid3(a),1) ! { dg-warning "Creating array temporary" } + ! Sums as part of a bigger expr work + if (any(1+sum(eid(a),1)+ax+sum( & + neid3(a), & ! { dg-warning "Creating array temporary" } + 1)+1 /= 3*ax+2)) call abort + if (any(1+eid(sum(a,2))+ay+ & + neid2( & ! { dg-warning "Creating array temporary" } + sum(a,2) & ! { dg-warning "Creating array temporary" } + )+1 /= 3*ay+2)) call abort + if (any(sum(eid(sum(a,3))+az+2* & + neid2(az) & ! { dg-warning "Creating array temporary" } + ,1)+1 /= 4*sum(az,1)+1)) call abort + + if (any(sum(transpose(sum(a,1)),1)+sum(az,1) /= sum(ax,2)+sum(sum(a,3),1))) call abort + + + ! Creates a temp when needed. + a(1,:,:) = sum(a,1) ! unnecessary { dg-warning "Creating array temporary" } + if (any(a(1,:,:) /= ax)) call abort + + b = p(:,:,1) + call set(b(2:,1), sum(b(:nx-1,:),2)) ! { dg-warning "Creating array temporary" } + if (any(b(2:,1) /= ay(1:nx-1,1))) call abort + + b = p(:,:,1) + call set(b(:,1), sum(b,2)) ! unnecessary { dg-warning "Creating array temporary" } + if (any(b(:,1) /= ay(:,1))) call abort + + b = p(:,:,1) + call tes(sum(eid(b(:nx-1,:)),2), b(2:,1)) ! { dg-warning "Creating array temporary" } + if (any(b(2:,1) /= ay(1:nx-1,1))) call abort + + b = p(:,:,1) + call tes(eid(sum(b,2)), b(:,1)) ! unnecessary { dg-warning "Creating array temporary" } + if (any(b(:,1) /= ay(:,1))) call abort + +contains + + elemental function eid (x) + integer, intent(in) :: x + integer :: eid + + eid = x + end function eid + + function neid2 (x) + integer, intent(in) :: x(:,:) + integer :: neid2(size(x,1),size(x,2)) + + neid2 = x + end function neid2 + + function neid3 (x) + integer, intent(in) :: x(:,:,:) + integer :: neid3(size(x,1),size(x,2),size(x,3)) + + neid3 = x + end function neid3 + + elemental subroutine set (o, i) + integer, intent(in) :: i + integer, intent(out) :: o + + o = i + end subroutine set + + elemental subroutine tes (i, o) + integer, intent(in) :: i + integer, intent(out) :: o + + o = i + end subroutine tes +end +! { dg-final { scan-tree-dump-times "struct array._integer\\(kind=4\\) atmp" 13 "original" } } +! { dg-final { scan-tree-dump-times "struct array\[^\\n\]*atmp" 13 "original" } } +! { dg-final { scan-tree-dump-times "_gfortran_sum_" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/inline_sum_2.f90 b/gcc/testsuite/gfortran.dg/inline_sum_2.f90 new file mode 100644 index 00000000000..0b7c60ad9e9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_sum_2.f90 @@ -0,0 +1,12 @@ +! { dg-do run } + +! PR fortran/43829 +! Scalarization of reductions. +! Test that inlined sum is correct. + +! We can't check for the absence of temporary arrays generated on the run-time +! testcase, as inlining is disabled at -Os, so it will fail in that case. +! Thus, the test is splitted into two independant files, one checking for +! the absence of temporaries, and one (this one) checking that the code +! generated remains valid at all optimization levels. +include 'inline_sum_1.f90' diff --git a/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_1.f90 b/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_1.f90 new file mode 100644 index 00000000000..39984683d4b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_1.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } + + integer, parameter :: nx = 3, ny = 4 + + integer :: i, j, too_big + + integer, parameter, dimension(nx,ny) :: p = & + reshape((/ (i*i, i=1,size(p)) /), shape(p)) + + integer, dimension(nx,ny) :: a + + integer, dimension(:), allocatable :: b + + allocate(b(nx)) + + a = p + too_big = ny + 1 + + b = sum(a(:,1:too_big),2) + end +! { dg-shouldfail "outside of expected range" } diff --git a/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_2.f90 b/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_2.f90 new file mode 100644 index 00000000000..8de80fdc9f6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_sum_bounds_check_2.f90 @@ -0,0 +1,23 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } + + integer, parameter :: nx = 3, ny = 4 + + integer :: i, j, too_big + + integer, parameter, dimension(nx,ny) :: p = & + reshape((/ (i*i, i=1,size(p)) /), shape(p)) + + integer, dimension(nx,ny) :: a + + integer, dimension(:), allocatable :: c + + + allocate(c(ny)) + + a = p + too_big = nx + 1 + + c = sum(a(1:too_big,:),2) + end +! { dg-shouldfail "outside of expected range" } diff --git a/gcc/testsuite/gfortran.dg/module_parameter_array_refs_2.f90 b/gcc/testsuite/gfortran.dg/module_parameter_array_refs_2.f90 new file mode 100644 index 00000000000..385761d1d17 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_parameter_array_refs_2.f90 @@ -0,0 +1,23 @@ +! { dg-do compile } +! { dg-options "-O" } +! { dg-final { scan-assembler-not "i_am_optimized_away" } } +! +! PR fortran/50960 +! +! PARAMETER arrays and derived types exists as static variables. +! Check that the their read-only nature is taken into account +! when optimizations are done. +! + +module m + integer, parameter :: PARA(*) = [1,2,3,4,5,6,7,8,9,10] +end module m + +subroutine test() +use m +integer :: i +i = 1 +if (para(i) /= 1) call i_am_optimized_away() +end + +! { dg-final { cleanup-modules "m" } } diff --git a/gcc/testsuite/gfortran.dg/open_dev_null.f90 b/gcc/testsuite/gfortran.dg/open_dev_null.f90 deleted file mode 100644 index 00394cb55a6..00000000000 --- a/gcc/testsuite/gfortran.dg/open_dev_null.f90 +++ /dev/null @@ -1,9 +0,0 @@ -! { dg-do run } -! PR45723 opening /dev/null for appending writes fails -logical :: thefile -inquire(file="/dev/null",exist=thefile) -if (thefile) then - open(unit=7,file="/dev/null",position="append") - close(7) -endif -end diff --git a/gcc/testsuite/gfortran.dg/pr50769.f90 b/gcc/testsuite/gfortran.dg/pr50769.f90 new file mode 100644 index 00000000000..3a98543e3a6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr50769.f90 @@ -0,0 +1,30 @@ +! { dg-do compile } +! { dg-options "-O2 -ftree-tail-merge -fno-delete-null-pointer-checks -fno-guess-branch-probability" } +! +! based on testsuite/gfortran.dg/alloc_comp_optional_1.f90, +! which was contributed by David Kinniburgh <davidkinniburgh@yahoo.co.uk> +! +program test_iso + type ivs + character(LEN=1), dimension(:), allocatable :: chars + end type ivs + type(ivs) :: v_str + integer :: i + call foo(v_str, i) + if (v_str%chars(1) .ne. "a") call abort + if (i .ne. 0) call abort + call foo(flag = i) + if (i .ne. 1) call abort +contains + subroutine foo (arg, flag) + type(ivs), optional, intent(out) :: arg + integer :: flag + if (present(arg)) then + arg = ivs([(char(i+96), i = 1,10)]) + flag = 0 + else + flag = 1 + end if + end subroutine +end + diff --git a/gcc/testsuite/gfortran.dg/quad_2.f90 b/gcc/testsuite/gfortran.dg/quad_2.f90 new file mode 100644 index 00000000000..c1334db9cd4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/quad_2.f90 @@ -0,0 +1,63 @@ +! { dg-do run } +! +! This test checks whether the largest possible +! floating-point number works. +! +! This is a run-time check. Depending on the architecture, +! this tests REAL(8), REAL(10) or REAL(16) and REAL(16) +! might be a hardware or libquadmath 128bit number. +! +program test_qp + use iso_fortran_env, only: real_kinds + implicit none + integer, parameter :: QP = real_kinds(ubound(real_kinds,dim=1)) + real(qp) :: fp1, fp2, fp3, fp4 + character(len=80) :: str1, str2, str3, str4 + fp1 = 1 + fp2 = sqrt (2.0_qp) + write (str1,*) fp1 + write (str2,'(g0)') fp1 + write (str3,*) fp2 + write (str4,'(g0)') fp2 + +! print '(3a)', '>',trim(str1),'<' +! print '(3a)', '>',trim(str2),'<' +! print '(3a)', '>',trim(str3),'<' +! print '(3a)', '>',trim(str4),'<' + + read (str1, *) fp3 + if (fp1 /= fp3) call abort() + read (str2, *) fp3 + if (fp1 /= fp3) call abort() + read (str3, *) fp4 + if (fp2 /= fp4) call abort() + read (str4, *) fp4 + if (fp2 /= fp4) call abort() + + select case (qp) + case (8) + if (str1 /= " 1.0000000000000000") call abort() + if (str2 /= "1.0000000000000000") call abort() + if (str3 /= " 1.4142135623730951") call abort() + if (str4 /= "1.4142135623730951") call abort() + case (10) + if (str1 /= " 1.00000000000000000000") call abort() + if (str2 /= "1.00000000000000000000") call abort() + if (str3 /= " 1.41421356237309504876") call abort() + if (str4 /= "1.41421356237309504876") call abort() + case (16) + if (str1 /= " 1.00000000000000000000000000000000000") call abort() + if (str2 /= "1.00000000000000000000000000000000000") call abort() + if (str3 /= " 1.41421356237309504880168872420969798") call abort() + if (str4 /= "1.41421356237309504880168872420969798") call abort() + block + real(qp), volatile :: fp2a + fp2a = 2.0_qp + fp2a = sqrt (fp2a) + if (abs (fp2a - fp2) > sqrt(2.0_qp)-nearest(sqrt(2.0_qp),-1.0_qp)) call abort() + end block + case default + call abort() + end select + +end program test_qp diff --git a/gcc/testsuite/gfortran.dg/typebound_call_21.f03 b/gcc/testsuite/gfortran.dg/typebound_call_21.f03 new file mode 100644 index 00000000000..5f7d67283c4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/typebound_call_21.f03 @@ -0,0 +1,39 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! PR 50919: [OOP] Don't use vtable for NON_OVERRIDABLE TBP +! +! Contributed by Tobias Burnus <burnus@gcc.gnu.org> + +module m + +type t +contains + procedure, nopass, NON_OVERRIDABLE :: testsub + procedure, nopass, NON_OVERRIDABLE :: testfun +end type t + +contains + + subroutine testsub() + print *, "t's test" + end subroutine + + integer function testfun() + testfun = 1 + end function + +end module m + + + use m + class(t), allocatable :: x + allocate(x) + call x%testsub() + print *,x%testfun() +end + +! { dg-final { scan-tree-dump-times "_vptr->" 0 "original" } } + +! { dg-final { cleanup-modules "m" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gnat.dg/loop_optimization10.adb b/gcc/testsuite/gnat.dg/loop_optimization10.adb new file mode 100644 index 00000000000..3b8e8949e1a --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization10.adb @@ -0,0 +1,18 @@ +-- { dg-do compile } +-- { dg-options "-O3" } +-- { dg-options "-O3 -msse2" { target i?86-*-* x86_64-*-* } } + +package body Loop_Optimization10 is + + function F (Low, High : in Array_Real_Type) return Array_Limit_Type is + Result : Array_Limit_Type; + begin + for I in Result'Range + loop + Result (I) := F (Low (I), High (I)); + end loop; + return Result; + end; + +end Loop_Optimization10; + diff --git a/gcc/testsuite/gnat.dg/loop_optimization10.ads b/gcc/testsuite/gnat.dg/loop_optimization10.ads new file mode 100644 index 00000000000..2f4872d1b5a --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization10.ads @@ -0,0 +1,11 @@ +with Loop_Optimization10_Pkg; use Loop_Optimization10_Pkg; +package Loop_Optimization10 is + + type Dual_Axis_Type is (One, Two); + + type Array_Real_Type is array (Dual_Axis_Type) of Float; + type Array_Limit_Type is array (Dual_Axis_Type) of Limit_Type; + + function F (Low, High : in Array_Real_Type) return Array_Limit_Type; + +end Loop_Optimization10; diff --git a/gcc/testsuite/gnat.dg/loop_optimization10_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization10_pkg.ads new file mode 100644 index 00000000000..6fce4df8a3e --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization10_pkg.ads @@ -0,0 +1,12 @@ +package Loop_Optimization10_Pkg is + + pragma Pure (Loop_Optimization10_Pkg); + + type Limit_Type is record + Low : Float; + High : Float; + end record; + + function F (Low, High : in Float) return Limit_Type; + +end Loop_Optimization10_Pkg; diff --git a/gcc/testsuite/gnat.dg/specs/private1-sub.ads b/gcc/testsuite/gnat.dg/specs/private1-sub.ads new file mode 100644 index 00000000000..0dcbbd0569c --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/private1-sub.ads @@ -0,0 +1,13 @@ +-- { dg-do compile } +-- { dg-options "-gnatct" } + +package Private1.Sub is + + package Nested is + type T is limited private; + function "=" (X, Y : T) return Boolean; + private + type T is new Private1.T; + end Nested; + +end Private1.Sub; diff --git a/gcc/testsuite/gnat.dg/specs/private1.ads b/gcc/testsuite/gnat.dg/specs/private1.ads new file mode 100644 index 00000000000..4ef06004352 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/private1.ads @@ -0,0 +1,5 @@ +package Private1 is + type T is private; +private + type T is new Boolean; +end Private1; diff --git a/gcc/testsuite/go.test/test/closedchan.go b/gcc/testsuite/go.test/test/closedchan.go index 95314b3345e..c2bbec59d95 100644 --- a/gcc/testsuite/go.test/test/closedchan.go +++ b/gcc/testsuite/go.test/test/closedchan.go @@ -11,6 +11,10 @@ package main +import "os" + +var failed bool + type Chan interface { Send(int) Nbsend(int) bool @@ -225,19 +229,23 @@ func test1(c Chan) { // recv a close signal (a zero value) if x := c.Recv(); x != 0 { println("test1: recv on closed:", x, c.Impl()) + failed = true } if x, ok := c.Recv2(); x != 0 || ok { println("test1: recv2 on closed:", x, ok, c.Impl()) + failed = true } // should work with select: received a value without blocking, so selected == true. x, selected := c.Nbrecv() if x != 0 || !selected { println("test1: recv on closed nb:", x, selected, c.Impl()) + failed = true } x, ok, selected := c.Nbrecv2() if x != 0 || ok || !selected { println("test1: recv2 on closed nb:", x, ok, selected, c.Impl()) + failed = true } } @@ -247,12 +255,14 @@ func test1(c Chan) { // the value should have been discarded. if x := c.Recv(); x != 0 { println("test1: recv on closed got non-zero after send on closed:", x, c.Impl()) + failed = true } // similarly Send. shouldPanic(func() { c.Send(2) }) if x := c.Recv(); x != 0 { println("test1: recv on closed got non-zero after send on closed:", x, c.Impl()) + failed = true } } @@ -260,6 +270,7 @@ func testasync1(c Chan) { // should be able to get the last value via Recv if x := c.Recv(); x != 1 { println("testasync1: Recv did not get 1:", x, c.Impl()) + failed = true } test1(c) @@ -269,6 +280,7 @@ func testasync2(c Chan) { // should be able to get the last value via Recv2 if x, ok := c.Recv2(); x != 1 || !ok { println("testasync1: Recv did not get 1, true:", x, ok, c.Impl()) + failed = true } test1(c) @@ -278,6 +290,7 @@ func testasync3(c Chan) { // should be able to get the last value via Nbrecv if x, selected := c.Nbrecv(); x != 1 || !selected { println("testasync2: Nbrecv did not get 1, true:", x, selected, c.Impl()) + failed = true } test1(c) @@ -287,6 +300,7 @@ func testasync4(c Chan) { // should be able to get the last value via Nbrecv2 if x, ok, selected := c.Nbrecv2(); x != 1 || !ok || !selected { println("testasync2: Nbrecv did not get 1, true, true:", x, ok, selected, c.Impl()) + failed = true } test1(c) } @@ -327,4 +341,19 @@ func main() { testclosed(mk(closedasync())) } } + + var ch chan int + shouldPanic(func() { + close(ch) + }) + + ch = make(chan int) + close(ch) + shouldPanic(func() { + close(ch) + }) + + if failed { + os.Exit(1) + } } diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index caa057f0746..d0b679d7ad6 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -73,6 +73,13 @@ if [info exists ADDITIONAL_TORTURE_OPTIONS] { } set LTO_TORTURE_OPTIONS "" + +# Some torture-options cause intermediate code output, unusable for +# testing using e.g. scan-assembler. In this variable are the options +# how to force it, when needed. +global gcc_force_conventional_output +set gcc_force_conventional_output "" + if [check_effective_target_lto] { # When having plugin test both slim and fat LTO and plugin/nonplugin # path. @@ -81,6 +88,7 @@ if [check_effective_target_lto] { { -O2 -flto -fno-use-linker-plugin -flto-partition=none } \ { -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects } ] + set gcc_force_conventional_output "-ffat-lto-objects" } else { set LTO_TORTURE_OPTIONS [list \ { -O2 -flto -flto-partition=none } \ @@ -156,6 +164,19 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { } } + # Let { dg-final { action } } force options as returned by an + # optional proc ${action}_required_options. + upvar 2 dg-final-code finalcode + foreach x [split $finalcode "\n"] { + set finalcmd [lindex $x 0] + if { [info procs ${finalcmd}_required_options] != "" } { + set req [${finalcmd}_required_options] + if { $req != "" } { + lappend extra_tool_flags $req + } + } + } + if { $extra_tool_flags != "" } { lappend options "additional_flags=$extra_tool_flags" } diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp index 6574ab13a35..3ba22f9dad7 100644 --- a/gcc/testsuite/lib/scanasm.exp +++ b/gcc/testsuite/lib/scanasm.exp @@ -85,6 +85,11 @@ proc scan-assembler { args } { dg-scan "scan-assembler" 1 $testcase $output_file $args } +proc scan-assembler_required_options { args } { + global gcc_force_conventional_output + return $gcc_force_conventional_output +} + # Check that a pattern is not present in the .s file produced by the # compiler. See dg-scan for details. @@ -96,6 +101,11 @@ proc scan-assembler-not { args } { dg-scan "scan-assembler-not" 0 $testcase $output_file $args } +proc scan-assembler-not_required_options { args } { + global gcc_force_conventional_output + return $gcc_force_conventional_output +} + # Return the scan for the assembly for hidden visibility. proc hidden-scan-for { symbol } { diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index f19c3c566c6..fd6b2691a97 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -655,6 +655,28 @@ proc check_effective_target_tls_runtime {} { } [add_options_for_tls ""]] } +# Return 1 if atomic compare-and-swap is supported on 'int' + +proc check_effective_target_cas_char {} { + return [check_no_compiler_messages cas_char assembly { + #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 + #error unsupported + #endif + } ""] +} + +proc check_effective_target_cas_int {} { + return [check_no_compiler_messages cas_int assembly { + #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + /* ok */ + #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + /* ok */ + #else + #error unsupported + #endif + } ""] +} + # Return 1 if -ffunction-sections is supported, 0 otherwise. proc check_effective_target_function_sections {} { @@ -2449,6 +2471,24 @@ proc check_effective_target_ultrasparc_hw { } { } "-mcpu=ultrasparc"] } +# Return 1 if the test environment supports executing UltraSPARC VIS2 +# instructions. We check this by attempting: "bmask %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis2_hw { } { + return [check_runtime ultrasparc_hw { + int main() { __asm__(".word 0x81b00320"); return 0; } + } "-mcpu=ultrasparc3"] +} + +# Return 1 if the test environment supports executing UltraSPARC VIS3 +# instructions. We check this by attempting: "addxc %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis3_hw { } { + return [check_runtime ultrasparc_hw { + int main() { __asm__(".word 0x81b00220"); return 0; } + } "-mcpu=niagara3"] +} + # Return 1 if the target supports hardware vector shift operation. proc check_effective_target_vect_shift { } { @@ -3499,6 +3539,28 @@ proc check_effective_target_section_anchors { } { return $et_section_anchors_saved } +# Return 1 if the target supports atomic operations on "int_128" values. + +proc check_effective_target_sync_int_128 { } { + if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) + && ![is-effective-target ia32] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if the target supports atomic operations on "long long". + +proc check_effective_target_sync_long_long { } { + if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) + && ![is-effective-target ia32] } { + return 1 + } else { + return 0 + } +} + # Return 1 if the target supports atomic operations on "int" and "long". proc check_effective_target_sync_int_long { } { |