diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-20 13:32:32 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-20 13:32:32 +0000 |
commit | fe5ad9266cba2cbb611a831aaac450d3f6decd0c (patch) | |
tree | a1dce161550e71aa81d0af00e118e4f68d907995 /gcc/testsuite | |
parent | 6715fbd40b05c43941c4d4e093cceb5345a695e7 (diff) | |
parent | 8c53c46cebf42cb4f4ac125ca6428c5e9b519f66 (diff) | |
download | gcc-fe5ad9266cba2cbb611a831aaac450d3f6decd0c.tar.gz |
Merge from trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@205111 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite')
45 files changed, 2597 insertions, 118 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e5e9ecbe46a..606e4de6979 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,125 @@ +2013-11-20 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * gcc.target/s390/htm-1.c: Rename to ... + * gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c: ... this + one. + * gcc.target/s390/htm-xl-intrin-1.c: Rename to ... + * gcc.target/s390/htm-builtins-compile-3.c: ... this one. + * gcc.target/s390/htm-builtins-compile-2.c: New testcase. + * gcc.target/s390/htm-builtins-1.c: New testcase. + * gcc.target/s390/htm-builtins-2.c: New testcase. + * gcc.target/s390/s390.exp: Add check for htm machine. + +2013-11-19 Joshua J Cogliati <jrincayc@yahoo.com> + + PR c/53001 + * c-c++-common/Wfloat-conversion.c: Copies relevant + tests from c-c++-common/Wconversion-real.c, + gcc.dg/Wconversion-real-integer.c and gcc.dg/pr35635.c into + new testcase for conversions that are warned about by + -Wfloat-conversion. + +2013-11-19 Martin Jambor <mjambor@suse.cz> + + PR rtl-optimization/59099 + * gcc.target/i386/pr59099.c: New test. + +2013-11-19 Sriraman Tallam <tmsriram@google.com> + + * gcc.dg/tree-prof/cold_partition_label.c: New testcase. + +2013-11-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * gcc.target/powerpc/ppc64-abi-2.c (MAKE_SLOT): New macro to + construct parameter slot value in endian-independent way. + (fcevv, fciievv, fcvevv): Use it. + +2013-11-19 Jan Hubicka <jh@suse.cz> + + * ipa/devirt9.C: Fix prevoius change. + +2013-11-19 Cesar Philippidis <cesar@codesourcery.com> + + * gcc.c-torture/execute/20101011-1.c (__aarch64__): + Remove defined(__linux__). + +2013-11-19 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59164 + * gcc.dg/torture/pr59164.c: New testcase. + +2013-11-19 Richard Biener <rguenther@suse.de> + + PR middle-end/58956 + * gcc.dg/torture/pr58956.c: New testcase. + +2013-11-19 Marek Polacek <polacek@redhat.com> + + * c-c++-common/ubsan/null-1.c: New test. + * c-c++-common/ubsan/null-2.c: New test. + * c-c++-common/ubsan/null-3.c: New test. + * c-c++-common/ubsan/null-4.c: New test. + * c-c++-common/ubsan/null-5.c: New test. + * c-c++-common/ubsan/null-6.c: New test. + * c-c++-common/ubsan/null-7.c: New test. + * c-c++-common/ubsan/null-8.c: New test. + * c-c++-common/ubsan/null-9.c: New test. + * c-c++-common/ubsan/null-10.c: New test. + * c-c++-common/ubsan/null-11.c: New test. + * gcc.dg/ubsan/c99-shift-2.c: Adjust dg-output. + * c-c++-common/ubsan/shift-1.c: Likewise. + * c-c++-common/ubsan/div-by-zero-3.c: Likewise. + +2013-11-19 Uros Bizjak <ubizjak@gmail.com> + + * gcc.dg/c11-complex-1.c: Use dg-add-options ieee. + +2013-11-19 Jan Hubicka <jh@suse.cz> + + * ipa/devirt9.C: Verify that the optimization happens already before. + whole-program. + +2013-11-19 Richard Biener <rguenther@suse.de> + + PR tree-optimization/57517 + * gfortran.fortran-torture/compile/pr57517.f90: New testcase. + * gcc.dg/torture/pr57517.c: Likewise. + +2013-11-19 Jan Hubicka <jh@suse.cz> + + * gcc.target/i386/memcpy-3.c: New testcase. + +2013-11-18 Jan Hubicka <jh@suse.cz> + Uros Bizjak <ubizjak@gmail.com> + + PR middle-end/59175 + * gcc.target/i386/memcpy-2.c: Fix template; + add +1 so the testcase passes at 32bit. + +2013-11-18 Dominique d'Humieres <dominiq@lps.ens.fr> + + * c-c++-common/cilk-plus/PS/reduction-3.c: Use stdlib.h. + Remove spurious FIXME. + +2013-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * c-c++-common/cilk-plus/PS/body.c: Add fopenmp effective target check. + +2013-11-18 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53473 + * g++.dg/cpp0x/constexpr-noexcept7.C: New. + +2013-11-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59125 + PR tree-optimization/54570 + * gcc.dg/builtin-object-size-8.c: Un-xfail. + * gcc.dg/builtin-object-size-14.c: New testcase. + * gcc.dg/strlenopt-14gf.c: Adjust. + * gcc.dg/strlenopt-1f.c: Likewise. + * gcc.dg/strlenopt-4gf.c: Likewise. + 2013-11-18 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/volatile11.adb: New test. @@ -108,6 +230,11 @@ * g++.dg/cpp0x/nsdmi-template3.C: New. * g++.dg/cpp0x/nsdmi-template4.C: Likewise. +2013-11-14 Diego Novillo <dnovillo@google.com> + + * gcc.dg/plugin/selfassign.c: Include stringpool.h. + * gcc.dg/plugin/start_unit_plugin.c: Likewise. + 2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> * gcc.target/powerpc/ppc64-abi-1.c (stack_frame_t): Remove @@ -1083,8 +1210,8 @@ * gcc.dg/vmx/gcc-bug-i.c: Add little endian variant. * gcc.dg/vmx/eg-5.c: Likewise. -2013-10-28 Claudiu Zissulescu <claziss@synopsys.com> - Joern Rennecke <joern.rennecke@embecosm.com> +2013-10-28 Claudiu Zissulescu <claziss@synopsys.com> + Joern Rennecke <joern.rennecke@embecosm.com> * gcc.target/arc/jump-around-jump.c: New test. diff --git a/gcc/testsuite/c-c++-common/Wfloat-conversion.c b/gcc/testsuite/c-c++-common/Wfloat-conversion.c new file mode 100644 index 00000000000..e872755902d --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wfloat-conversion.c @@ -0,0 +1,58 @@ +/* Test for diagnostics for Wconversion for floating-point. */ + +/* { dg-do compile } */ +/* { dg-options "-std=c99 -Wfloat-conversion" { target c } } */ +/* { dg-options "-Wfloat-conversion" { target c++ } } */ +/* { dg-require-effective-target large_double } */ +/* { dg-require-effective-target int32plus } */ +/* { dg-require-effective-target double64plus } */ +#include <limits.h> + +float vfloat; +double vdouble; +long double vlongdouble; +int bar; + +void fsi (signed int x); +void fui (unsigned int x); +void ffloat (float f); +void fdouble (double d); +void flongdouble (long double ld); + +void h (void) +{ + unsigned int ui = 3; + int si = 3; + unsigned char uc = 3; + signed char sc = 3; + float f = 0; + double d = 0; + long double ld = 0; + + ffloat (3.1); /* { dg-warning "conversion to 'float' alters 'double' constant value" } */ + vfloat = 3.1; /* { dg-warning "conversion to 'float' alters 'double' constant value" } */ + ffloat (3.1L); /* { dg-warning "conversion to 'float' alters 'long double' constant value" } */ + vfloat = 3.1L; /* { dg-warning "conversion to 'float' alters 'long double' constant value" } */ + fdouble (3.1L); /* { dg-warning "conversion to 'double' alters 'long double' constant value" "" { target large_long_double } } */ + vdouble = 3.1L; /* { dg-warning "conversion to 'double' alters 'long double' constant value" "" { target large_long_double } } */ + ffloat (vdouble); /* { dg-warning "conversion to 'float' from 'double' may alter its value" } */ + vfloat = vdouble; /* { dg-warning "conversion to 'float' from 'double' may alter its value" } */ + ffloat (vlongdouble); /* { dg-warning "conversion to 'float' from 'long double' may alter its value" } */ + vfloat = vlongdouble; /* { dg-warning "conversion to 'float' from 'long double' may alter its value" } */ + fdouble (vlongdouble); /* { dg-warning "conversion to 'double' from 'long double' may alter its value" "" { target large_long_double } } */ + vdouble = vlongdouble; /* { dg-warning "conversion to 'double' from 'long double' may alter its value" "" { target large_long_double } } */ + + fsi (3.1f); /* { dg-warning "conversion to 'int' alters 'float' constant value" } */ + si = 3.1f; /* { dg-warning "conversion to 'int' alters 'float' constant value" } */ + fsi (3.1); /* { dg-warning "conversion to 'int' alters 'double' constant value" } */ + si = 3.1; /* { dg-warning "conversion to 'int' alters 'double' constant value" } */ + fsi (d); /* { dg-warning "conversion to 'int' from 'double' may alter its value" } */ + si = d; /* { dg-warning "conversion to 'int' from 'double' may alter its value" } */ + ffloat (INT_MAX); /* { dg-warning "conversion to 'float' alters 'int' constant value" } */ + vfloat = INT_MAX; /* { dg-warning "conversion to 'float' alters 'int' constant value" } */ + ffloat (16777217); /* { dg-warning "conversion to 'float' alters 'int' constant value" } */ + vfloat = 16777217; /* { dg-warning "conversion to 'float' alters 'int' constant value" } */ + + sc = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion to 'signed char' alters 'double' constant value" } */ + uc = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion to 'unsigned char' alters 'double' constant value" } */ +} diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c index 9b10041d669..82c0a0c20bf 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fcilkplus -fopenmp" } */ +/* { dg-require-effective-target fopenmp } */ int *a, *b, c; void *jmpbuf[10]; diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c index 26822d633ff..35cb904a540 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c @@ -1,13 +1,11 @@ /* { dg-do run } */ /* { dg-options "-O3 -fcilkplus" } */ -/* FIXME: This test has been xfailed until reductions are fixed. */ - #define N 256 #if HAVE_IO #include <stdio.h> #endif -#include <malloc.h> +#include <stdlib.h> int reduction_simd (int *a) diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c index 719e6c98634..f3ee23bd021 100644 --- a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c +++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c @@ -16,6 +16,6 @@ main (void) return 0; } -/* { dg-output "division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */ +/* { dg-output "division of -2147483648 by -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-1.c b/gcc/testsuite/c-c++-common/ubsan/null-1.c new file mode 100644 index 00000000000..887dfdcdb9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +main (void) +{ + int *p = 0; + return *p; +} + +/* { dg-output "load of null pointer of type 'int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-10.c b/gcc/testsuite/c-c++-common/ubsan/null-10.c new file mode 100644 index 00000000000..267ab1f321c --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-10.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +main (void) +{ + short *p = 0, *u; + *(u + *p) = 23; + return 0; +} + +/* { dg-output "load of null pointer of type 'short int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-11.c b/gcc/testsuite/c-c++-common/ubsan/null-11.c new file mode 100644 index 00000000000..83e65af7e86 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-11.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +struct S { + int i; +}; + +int +main (void) +{ + struct S **s = 0; + return (*s)->i; +} + +/* { dg-output "load of null pointer of type 'struct S \\*'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-2.c b/gcc/testsuite/c-c++-common/ubsan/null-2.c new file mode 100644 index 00000000000..c5303ea97a7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-2.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +main (void) +{ + int ***ppp = 0; + return ***ppp; +} + +/* { dg-output "load of null pointer of type 'int \\*\\*'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-3.c b/gcc/testsuite/c-c++-common/ubsan/null-3.c new file mode 100644 index 00000000000..0beb20cfbd0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-3.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +foo (int *p) +{ + return *p; +} + +int +main (void) +{ + int **p = 0; + return foo (*p); +} + +/* { dg-output "load of null pointer of type 'int \\*'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-4.c b/gcc/testsuite/c-c++-common/ubsan/null-4.c new file mode 100644 index 00000000000..b5f03ed0b60 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-4.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +main (void) +{ + _Complex double *p = 0; + if (p[0]) + return 42; + return 0; +} + +/* { dg-output "load of null pointer of type 'complex double'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-5.c b/gcc/testsuite/c-c++-common/ubsan/null-5.c new file mode 100644 index 00000000000..f6db4744446 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-5.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +typedef volatile const _Complex float *T; + +int +main (void) +{ + T t = 0; + if (*t) + return 42; + return 0; +} + +/* { dg-output "load of null pointer of type 'volatile const complex float'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-6.c b/gcc/testsuite/c-c++-common/ubsan/null-6.c new file mode 100644 index 00000000000..705635c0d84 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-6.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int +main (void) +{ + unsigned long int *p = 0; + *p = 42; + return 0; +} + +/* { dg-output "store to null pointer of type 'long unsigned int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-7.c b/gcc/testsuite/c-c++-common/ubsan/null-7.c new file mode 100644 index 00000000000..1d8216a3d2f --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-7.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +int * +gao (void) +{ + return 0; +} + +int +main (void) +{ + return *gao (); +} + +/* { dg-output "load of null pointer of type 'int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-8.c b/gcc/testsuite/c-c++-common/ubsan/null-8.c new file mode 100644 index 00000000000..2cf3939ca5e --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-8.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +struct S { + int i; +}; + +int +main (void) +{ + struct S *s = 0; + return s->i; +} + +/* { dg-output "member access within null pointer of type 'struct S'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-9.c b/gcc/testsuite/c-c++-common/ubsan/null-9.c new file mode 100644 index 00000000000..7fabbeca4c7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/null-9.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=null -w" } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +union U { + int i; +}; + +int +main (void) +{ + union U *u = 0; + return u->i; +} + +/* { dg-output "member access within null pointer of type 'union U'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-1.c b/gcc/testsuite/c-c++-common/ubsan/shift-1.c index 48cf3cd7bff..0928ff7a102 100644 --- a/gcc/testsuite/c-c++-common/ubsan/shift-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/shift-1.c @@ -23,9 +23,9 @@ main (void) return 0; } -/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 154 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 524 is too large for \[^\n\r]*-bit type long long unsigned int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 370 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 402 is too large for \[^\n\r]*-bit type long int(\n|\r\n|\r)" } */ +/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 154 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 524 is too large for \[^\n\r]*-bit type 'long long unsigned int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 370 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 402 is too large for \[^\n\r]*-bit type 'long int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-noexcept7.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-noexcept7.C new file mode 100644 index 00000000000..2a70d7bb529 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-noexcept7.C @@ -0,0 +1,9 @@ +// PR c++/53473 +// { dg-do compile { target c++11 } } + +template<typename T> struct A +{ + static constexpr T foo() noexcept { return 0; } +}; + +template<> constexpr int A<int>::foo() noexcept { return 0; } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-9.C b/gcc/testsuite/g++.dg/ipa/devirt-9.C index 5be458cbb41..7fd0bf5f5cd 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-9.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-9.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-ipa-inline" } */ +/* { dg-options "-O2 -fdump-ipa-whole-program" } */ double foo (); struct B { @@ -27,5 +27,7 @@ bar () static C c; c.c1 (60, (int) foo ()); } -/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target" "inline" } } */ -/* { dg-final { cleanup-ipa-dump "inline" } } */ +/* We optimize out this call just after early passes. Unfortunately + this unreachable removal is not logged in dump file. */ +/* { dg-final { scan-ipa-dump-not "OBJ_TYPE_REF" "whole-program" } } */ +/* { dg-final { cleanup-ipa-dump "whole-program" } } */ diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c index bd54318a263..56b48ca72bf 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c @@ -12,10 +12,9 @@ #elif defined (__sh__) /* On SH division by zero does not trap. */ # define DO_TEST 0 -#elif defined (__aarch64__) && !defined(__linux__) - /* AArch64 divisions do trap by default, but libgloss targets do not - intercept the trap and raise a SIGFPE. So restrict the test to - AArch64 systems that use the Linux kernel. */ +#elif defined (__aarch64__) + /* On AArch64 integer division by zero does not trap. */ +# define DO_TEST 0 #elif defined (__TMS320C6X__) /* On TI C6X division by zero does not trap. */ # define DO_TEST 0 diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-14.c b/gcc/testsuite/gcc.dg/builtin-object-size-14.c new file mode 100644 index 00000000000..085011eda52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-object-size-14.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); +extern char *strncpy(char *, const char *, __SIZE_TYPE__); + +union u { + struct { + char vi[8]; + char pi[16]; + }; + char all[8+16+4]; +}; + +void __attribute__((noinline,noclone)) +f(union u *u) +{ + char vi[8+1]; + __builtin_strncpy(vi, u->vi, sizeof(u->vi)); + if (__builtin_object_size (u->all, 1) != -1) + abort (); +} +int main() +{ + union u u; + f (&u); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-8.c b/gcc/testsuite/gcc.dg/builtin-object-size-8.c index 7af64d3ab7a..f2d88f9d591 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-8.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-8.c @@ -1,4 +1,4 @@ -/* { dg-do run { xfail *-*-* } } */ +/* { dg-do run } */ /* { dg-options "-O2" } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/c11-complex-1.c b/gcc/testsuite/gcc.dg/c11-complex-1.c index e2d3c460f40..4acb2bcc221 100644 --- a/gcc/testsuite/gcc.dg/c11-complex-1.c +++ b/gcc/testsuite/gcc.dg/c11-complex-1.c @@ -1,6 +1,7 @@ /* Test complex divide does not have the bug identified in N1496. */ /* { dg-do run } */ /* { dg-options "-std=c11 -pedantic-errors" } */ +/* { dg-add-options ieee } */ extern void abort (void); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c index 2498153a273..cdab74a19ae 100644 --- a/gcc/testsuite/gcc.dg/plugin/selfassign.c +++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c @@ -8,6 +8,7 @@ #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "stringpool.h" #include "toplev.h" #include "basic-block.h" #include "gimple.h" diff --git a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c index 257aad85a8a..39f44626a55 100644 --- a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c @@ -11,6 +11,7 @@ #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "stringpool.h" #include "toplev.h" #include "basic-block.h" #include "gimple.h" diff --git a/gcc/testsuite/gcc.dg/strlenopt-14gf.c b/gcc/testsuite/gcc.dg/strlenopt-14gf.c index 6e5c9b08e16..8b78538d41d 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14gf.c @@ -11,14 +11,14 @@ memcpy. */ /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "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 "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c index e0a2c926ca2..50c5f91306a 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-1f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c @@ -6,12 +6,12 @@ #include "strlenopt-1.c" /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "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 "stpcpy \\(" 0 "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-4gf.c b/gcc/testsuite/gcc.dg/strlenopt-4gf.c index 743066f2eb0..e1762366e45 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4gf.c @@ -7,13 +7,13 @@ #include "strlenopt-4.c" /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 5 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "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 "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr57517.c b/gcc/testsuite/gcc.dg/torture/pr57517.c new file mode 100644 index 00000000000..2422d8ee64a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57517.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +int x[1024], y[1024], z[1024], w[1024]; +void foo (void) +{ + int i; + for (i = 1; i < 1024; ++i) + { + int a = x[i]; + int b = y[i]; + int c = x[i-1]; + int d = y[i-1]; + if (w[i]) + z[i] = (a + b) + (c + d); + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr58956.c b/gcc/testsuite/gcc.dg/torture/pr58956.c new file mode 100644 index 00000000000..7576ba7fb5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58956.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct S +{ + int f0; +} a = {1}, b, g, *c = &b, **f = &c; + +int *d, **e = &d, h; + +struct S +foo () +{ + *e = &h; + if (!d) + __builtin_unreachable (); + *f = &g; + return a; +} + +int +main () +{ + struct S *i = c; + *i = foo (); + if (b.f0 != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr59164.c b/gcc/testsuite/gcc.dg/torture/pr59164.c new file mode 100644 index 00000000000..1ec69610c21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59164.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int a, d, e; +long b[10]; +int c[10][8]; + +int fn1(p1) +{ + return 1 >> p1; +} + +void fn2(void) +{ + int f; + for (a=1; a <= 4; a++) + { + f = fn1(0 < c[a][0]); + if (f || d) + e = b[a] = 1; + } +} diff --git a/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c new file mode 100644 index 00000000000..9dc75668e8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c @@ -0,0 +1,36 @@ +/* Test case to check if function foo gets split and the cold function + gets a label. */ +/* { dg-require-effective-target freorder } */ +/* { dg-options "-O2 -freorder-blocks-and-partition --save-temps" } */ + +#define SIZE 10000 + +const char *sarr[SIZE]; +const char *buf_hot; +const char *buf_cold; + +__attribute__((noinline)) +void +foo (int path) +{ + int i; + if (path) + { + for (i = 0; i < SIZE; i++) + sarr[i] = buf_hot; + } + else + { + for (i = 0; i < SIZE; i++) + sarr[i] = buf_cold; + } +} + +int +main (int argc, char *argv[]) +{ + buf_hot = "hello"; + buf_cold = "world"; + foo (argc); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c b/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c index 7dceb585739..c6662dc43bc 100644 --- a/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c +++ b/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c @@ -7,4 +7,4 @@ main (void) int a = 1; a <<= 31; } -/* { dg-output "left shift of 1 by 31 places cannot be represented in type int" } */ +/* { dg-output "left shift of 1 by 31 places cannot be represented in type 'int'" } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-2.c index fe53f2653a0..56cdd56fae4 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-2.c @@ -1,11 +1,11 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ -/* Memcpy should be inlined because block size is known. */ -/* { dg-final { scan-assembler-not "memcpy" } } */ void *a; void *b; t(unsigned int c) { if (c<10) - memcpy (a,b,c); + __builtin_memcpy (a,b,c+1); } +/* Memcpy should be inlined because block size is known. */ +/* { dg-final { scan-assembler-not "(jmp|call)\[\\t \]*memcpy" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-3.c b/gcc/testsuite/gcc.target/i386/memcpy-3.c new file mode 100644 index 00000000000..b9ea9c28e23 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +void *a; +void *b; +t(int c) +{ + if (c<10) + __builtin_memcpy (a,b,c); +} +/* Memcpy should be inlined because block size is known. */ +/* { dg-final { scan-assembler-not "(jmp|call)\[\\t \]*memcpy" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr59099.c b/gcc/testsuite/gcc.target/i386/pr59099.c new file mode 100644 index 00000000000..7dc12ff3f7c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59099.c @@ -0,0 +1,76 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fPIC -m32" } */ + +void (*pfn)(void); + +struct s +{ + void** q; + int h; + int t; + int s; +}; + + +void* f (struct s *, struct s *) __attribute__ ((noinline, regparm(1))); + +void* +__attribute__ ((regparm(1))) +f (struct s *p, struct s *p2) +{ + void *gp, *gp1; + int t, h, s, t2, h2, c, i; + + if (p2->h == p2->t) + return 0; + + (*pfn) (); + + h = p->h; + t = p->t; + s = p->s; + + h2 = p2->h; + t2 = p2->t; + + gp = p2->q[h2++]; + + c = (t2 - h2) / 2; + for (i = 0; i != c; i++) + { + if (t == h || (h == 0 && t == s - 1)) + break; + gp1 = p2->q[h2++]; + p->q[t++] = gp1; + if (t == s) + t = 0; + } + + p2->h = h2; + return gp; +} + +static void gn () { } + +int +main() +{ + struct s s1, s2; + void *q[10]; + + pfn = gn; + + s1.q = q; + s1.h = 0; + s1.t = 2; + s1.s = 4; + + s2.q = q; + s2.h = 0; + s2.t = 4; + s2.s = 2; + + f (&s1, &s2); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c index fdb781554c6..e4825973b11 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c @@ -121,6 +121,12 @@ typedef union vector int v; } vector_int_t; +#ifdef __LITTLE_ENDIAN__ +#define MAKE_SLOT(x, y) ((long)x | ((long)y << 32)) +#else +#define MAKE_SLOT(x, y) ((long)y | ((long)x << 32)) +#endif + /* Paramter passing. s : gpr 3 v : vpr 2 @@ -228,8 +234,8 @@ fcevv (char *s, ...) sp = __builtin_frame_address(0); sp = sp->backchain; - if (sp->slot[2].l != 0x100000002ULL - || sp->slot[4].l != 0x500000006ULL) + if (sp->slot[2].l != MAKE_SLOT (1, 2) + || sp->slot[4].l != MAKE_SLOT (5, 6)) abort(); } @@ -270,8 +276,8 @@ fciievv (char *s, int i, int j, ...) sp = __builtin_frame_address(0); sp = sp->backchain; - if (sp->slot[4].l != 0x100000002ULL - || sp->slot[6].l != 0x500000006ULL) + if (sp->slot[4].l != MAKE_SLOT (1, 2) + || sp->slot[6].l != MAKE_SLOT (5, 6)) abort(); } @@ -298,8 +304,8 @@ fcvevv (char *s, vector int x, ...) sp = __builtin_frame_address(0); sp = sp->backchain; - if (sp->slot[4].l != 0x100000002ULL - || sp->slot[6].l != 0x500000006ULL) + if (sp->slot[4].l != MAKE_SLOT (1, 2) + || sp->slot[6].l != MAKE_SLOT (5, 6)) abort(); } diff --git a/gcc/testsuite/gcc.target/s390/htm-1.c b/gcc/testsuite/gcc.target/s390/htm-1.c deleted file mode 100644 index 245ba2c7ef9..00000000000 --- a/gcc/testsuite/gcc.target/s390/htm-1.c +++ /dev/null @@ -1,73 +0,0 @@ -/* This checks the availability of the low-level builtins introduced - for transactional execution. */ - -/* { dg-do compile } */ -/* { dg-options "-O3 -march=zEC12 -mzarch" } */ - -#include <stdint.h> -#include <htmintrin.h> - -int global = 0; -uint64_t g; -struct __htm_tdb global_tdb; - -int -foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) -{ - - int cc; - int n; - - cc = __builtin_tbegin (0); - cc = __builtin_tbegin (tdb); - cc = __builtin_tbegin (&global_tdb); - - cc = __builtin_tbegin_nofloat (0); - cc = __builtin_tbegin_nofloat (&global_tdb); - - cc = __builtin_tbegin_retry (0, 42); - cc = __builtin_tbegin_retry (0, reg); - cc = __builtin_tbegin_retry (0, *mem); - cc = __builtin_tbegin_retry (0, global); - cc = __builtin_tbegin_retry (tdb, 42); - cc = __builtin_tbegin_retry (&global_tdb, 42); - - cc = __builtin_tbegin_retry_nofloat (0, 42); - cc = __builtin_tbegin_retry_nofloat (0, reg); - cc = __builtin_tbegin_retry_nofloat (0, *mem); - cc = __builtin_tbegin_retry_nofloat (0, global); - cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42); - - __builtin_tbeginc (); - - n = __builtin_tx_nesting_depth(); - - __builtin_non_tx_store(&g, 23); - __builtin_non_tx_store(mem64, 23); - __builtin_non_tx_store(&g, reg); - __builtin_non_tx_store(&g, *mem); - __builtin_non_tx_store(&g, global); - - __builtin_tabort (42 + 255); - __builtin_tabort (reg); - /* { dg-final { scan-assembler-times "tabort\t255" 1 } } */ - __builtin_tabort (reg + 255); - __builtin_tabort (*mem); - __builtin_tabort (global); - /* Here global + 255 gets reloaded into a reg. Better would be to - just reload global or *mem and get the +255 for free as address - arithmetic. */ - __builtin_tabort (*mem + 255); - __builtin_tabort (global + 255); - - __builtin_tend(); - - __builtin_tx_assist (23); - __builtin_tx_assist (reg); - __builtin_tx_assist (*mem); - __builtin_tx_assist (global); -} - -/* Make sure the tdb NULL argument ends up as immediate value in the - instruction. */ -/* { dg-final { scan-assembler-times "tbegin\t0," 10 } } */ diff --git a/gcc/testsuite/gcc.target/s390/htm-builtins-1.c b/gcc/testsuite/gcc.target/s390/htm-builtins-1.c new file mode 100644 index 00000000000..c90490faa59 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-1.c @@ -0,0 +1,1073 @@ +/* Functional tests of the htm __builtin_... macros. */ + +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +/* ---------------------------- included header files ---------------------- */ + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <htmintrin.h> + +/* ---------------------------- local definitions -------------------------- */ + +#define DEFAULT_MAX_REPETITIONS 5 +#define DEFAULT_REQUIRED_QUORUM ((DEFAULT_MAX_REPETITIONS) - 1) +#define NUM_WARMUP_RUNS 10 + +/* ---------------------------- local macros ------------------------------- */ + +#define TEST_DF_REP(name) \ + { #name, name, DEFAULT_MAX_REPETITIONS, DEFAULT_REQUIRED_QUORUM } +#define TEST_NO_REP(name) { #name, name, 1, 1 } + +/* ---------------------------- local types -------------------------------- */ + +typedef int (*test_func_t)(void); + +typedef struct +{ + const char *name; + test_func_t test_func; + int max_repetitions; + int required_quorum; +} test_table_entry_t; + +/* ---------------------------- local variables ---------------------------- */ + +__attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256; +static struct __htm_tdb local_tdb; +static int do_dump_tdb = 0; + +/* ---------------------------- exported variables (globals) --------------- */ + +__attribute__ ((aligned(256))) struct +{ + float float_1; + float float_2; + float float_3; +} global = { 1.0, 2.5, 0.0 }; + +__attribute__ ((aligned(256))) struct +{ + volatile uint64_t c1; + volatile uint64_t c2; + volatile uint64_t c3; +} counters = { 0, 0, 0 }; + +/* ---------------------------- local helper functions --------------------- */ + +static void dump_tdb (struct __htm_tdb *tdb) +{ + unsigned char *p; + int i; + int j; + + if (do_dump_tdb == 0) + { + return; + } + p = (unsigned char *)tdb; + for (i = 0; i < 16; i++) + { + fprintf (stderr, "0x%02x ", i * 16); + for (j = 0; j < 16; j++) + { + fprintf (stderr, "%02x", (int)p[i * 16 + j]); + if (j < 15) + { + fprintf (stderr, " "); + } + if (j == 7) + { + fprintf (stderr, " "); + } + } + fprintf (stderr, "\n"); + } + + return; +} + +/* ---------------------------- local test functions ----------------------- */ + +/* Check values of the constants defined in htmintrin.h. */ +static int test_constants (void) +{ + if (_HTM_TBEGIN_STARTED != 0) + { + return 100 * _HTM_TBEGIN_STARTED + 1; + } + if (_HTM_TBEGIN_INDETERMINATE != 1) + { + return 100 * _HTM_TBEGIN_INDETERMINATE + 2; + } + if (_HTM_TBEGIN_TRANSIENT != 2) + { + return 100 * _HTM_TBEGIN_TRANSIENT + 3; + } + if (_HTM_TBEGIN_PERSISTENT != 3) + { + return 100 * _HTM_TBEGIN_PERSISTENT + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tend (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tabort (void) +{ + float f; + + counters.c1 = 0; + counters.c2 = 0; + f = 0; + if (__builtin_tbegin ((void *)0) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + f = 1; + __builtin_tabort (256); + return 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 0) + { + return 100 * counters.c2 + 3; + } + if (f != 0) + { + return 100 * f + 4; + } + + return 0; +} + +static int test_tbegin_nofloat (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_retry (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0) + { + int do_abort; + + do_abort = (counters.c1 == 0) ? 1 : 0; + __builtin_non_tx_store ( + (uint64_t *)&counters.c1, counters.c1 + 1); + if (do_abort == 1) + { + __builtin_tabort (256); + } + counters.c2 = counters.c2 + 10; + __builtin_non_tx_store ((uint64_t *)&counters.c3, 3); + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 2) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 10) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 6; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_retry_nofloat (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, 5)) == 0) + { + int do_abort; + + do_abort = (counters.c1 == 0) ? 1 : 0; + __builtin_non_tx_store ( + (uint64_t *)&counters.c1, counters.c1 + 1); + if (do_abort == 1) + { + __builtin_tabort (256); + } + counters.c2 = counters.c2 + 10; + __builtin_non_tx_store ((uint64_t *)&counters.c3, 3); + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 2) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 10) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 6; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_aborts (void) +{ + float f; + int rc; + + f = 77; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 88; + __builtin_tabort (256); + return 2; + } + else if (rc != 2) + { + return 3; + } + if (f != 77) + { + return 4; + } + f = 66; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 99; + __builtin_tabort (257); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + global.float_3 = global.float_1 + global.float_2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 8; + } + } + else + { + return 100 * rc + 9; + } + if (global.float_3 != global.float_1 + global.float_2) + { + return 100 * rc + 10; + } + + return 0; +} + +static __attribute__((noinline)) void indirect_abort(int abort_code) +{ + __builtin_tabort (abort_code); + + return; +} + +static int test_tbegin_indirect_aborts (void) +{ + float f; + int rc; + + f = 77; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 88; + indirect_abort(256); + return 2; + } + else if (rc != 2) + { + return 100 * rc + 3; + } + if (f != 77) + { + return 100 * rc + 4; + } + f = 66; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 99; + indirect_abort(257); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + + return 0; +} + +static int test_tbegin_nofloat_aborts (void) +{ + int rc; + + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_tabort (256); + return 2; + } + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_tabort (257); + return 1005; + } + else if (rc != 3) + { + return 1000 * rc + 6; + } + + return 0; +} + +static int test_tbegin_nofloat_indirect_aborts (void) +{ + int rc; + + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + indirect_abort (256); + return 2; + } + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + indirect_abort (257); + return 1005; + } + else if (rc != 3) + { + return 1000 * rc + 6; + } + + return 0; +} + +static +int _test_tbegin_retry_aborts (int retries, uint64_t abort_code) +{ + int rc; + + counters.c1 = 0; + if ((rc = __builtin_tbegin_retry ((void *)0, retries)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1); + __builtin_tabort (abort_code); + return 2; + } + else + { + if ((abort_code & 1) == 0) + { + if (rc != 2) + { + return 100 * rc + 2003; + } + else if (counters.c1 != (uint64_t)retries + 1) + { + return 1000 * counters.c1 + 100 * retries + 4; + } + } + else + { + if (rc != 3) + { + return 100 * rc + 3005; + } + else if (counters.c1 != 1) + { + return 1000 * counters.c1 + 100 * retries + 6; + } + } + } + + return 0; +} + +static int test_tbegin_retry_aborts (void) +{ + int rc; + int retries; + + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_aborts (retries, 256); + if (rc != 0) + { + return 10000 + rc; + } + } + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_aborts (retries, 257); + if (rc != 0) + { + return 20000 + rc; + } + } + if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0) + { + global.float_3 = global.float_1 + global.float_2; + rc = __builtin_tend (); + if (rc != 0) + { + return 30000 + 100 * rc + 6; + } + } + else + { + return 30000 + 100 * rc + 7; + } + + return 0; +} + +static int _test_tbegin_retry_nofloat_aborts (int retries, uint64_t abort_code) +{ + int rc; + + counters.c1 = 0; + if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, retries)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1); + __builtin_tabort (abort_code); + return 2; + } + else + { + if ((abort_code & 1) == 0) + { + if (rc != 2) + { + return 100 * rc + 2003; + } + else if (counters.c1 != (uint64_t)retries + 1) + { + return 1000 * counters.c1 + 100 * retries + 4; + } + } + else + { + if (rc != 3) + { + return 100 * rc + 3005; + } + else if (counters.c1 != 1) + { + return 1000 * counters.c1 + 100 * retries + 6; + } + } + } + + return 0; +} + +static int test_tbegin_retry_nofloat_aborts (void) +{ + int rc; + int retries; + + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_nofloat_aborts (retries, 256); + if (rc != 0) + { + return 10 * retries + rc; + } + } + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_nofloat_aborts (retries, 257); + if (rc != 0) + { + return 10000 + 10 * retries + rc; + } + } + + return 0; +} + +static int test_tbegin_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin (&local_tdb)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin (&local_tdb)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin (&local_tdb256)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin (&local_tdb256)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_nofloat_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1003; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_retry_tdb (void) +{ + int rc; + + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1003; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_retry_nofloat_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_etnd (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + counters.c1 = __builtin_tx_nesting_depth (); + if (__builtin_tbegin ((void *)0) == 0) + { + counters.c2 = __builtin_tx_nesting_depth (); + if (__builtin_tbegin ((void *)0) == 0) + { + counters.c3 = __builtin_tx_nesting_depth (); + __builtin_tend (); + } + __builtin_tend (); + } + __builtin_tend (); + } + else + { + return 100 * rc + 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 4; + } + + return 0; +} + +static int test_tbeginc (void) +{ + int rc; + + counters.c1 = 0; + __builtin_tbeginc (); + counters.c1 = 1; + rc = __builtin_tend (); + if (rc != 0) + { + return 10000 * rc + 1; + } + if (counters.c1 != 1) + { + return 100000 * counters.c1 + 3; + } + + return 0; +} + +/* ---------------------------- local testing framework functions ---------- */ + +static int run_one_test (const test_table_entry_t *test_entry) +{ + int do_print_passes; + int succeeded; + int rc; + int i; + + /* Warmup run to get all necessary data and instruction pages into the page + * tables. */ + { + int run; + + do_dump_tdb = 0; + for (run = 0; run < NUM_WARMUP_RUNS; run++) + { + test_entry->test_func (); + } + do_dump_tdb = 1; + } + do_print_passes = ( + test_entry->required_quorum != 1 || + test_entry->max_repetitions != 1); + printf ("RRR RUN %s\n", test_entry->name); + if (do_print_passes == 1) + { + printf ( + " (requires %d successful out of %d runs)\n", + test_entry->required_quorum, + test_entry->max_repetitions); + } + succeeded = 0; + rc = 0; + for (rc = 0, i = 0; i < test_entry->max_repetitions; i++) + { + if (do_print_passes == 1) + { + if (i == 0) + { + printf (" "); + } + else + { + printf (","); + } + } + rc = test_entry->test_func (); + if (rc == 0) + { + if (do_print_passes == 1) + { + printf (" success"); + } + succeeded++; + if (succeeded >= test_entry->required_quorum) + { + break; + } + } + else + { + printf (" failed (rc = %d)", rc); + } + } + if (do_print_passes == 1 || rc != 0) + { + printf ("\n"); + } + if (succeeded >= test_entry->required_quorum) + { + printf ("+++ OK %s\n", test_entry->name); + + return 0; + } + else + { + printf ("--- FAIL %s\n", test_entry->name); + + return (rc != 0) ? rc : -1; + } +} + +static int run_all_tests (const test_table_entry_t *test_table) +{ + const test_table_entry_t *test; + int rc; + + for ( + rc = 0, test = &test_table[0]; + test->test_func != NULL && rc == 0; test++) + { + rc = run_one_test (test); + } + + return rc; +} + +/* ---------------------------- interface functions ------------------------ */ + +int main (void) +{ + const test_table_entry_t test_table[] = { + TEST_NO_REP (test_constants), + TEST_DF_REP (test_tbegin_ntstg_tend), + TEST_DF_REP (test_tbegin_ntstg_tabort), + TEST_DF_REP (test_tbegin_nofloat), + TEST_NO_REP (test_tbegin_retry), + TEST_NO_REP (test_tbegin_retry_nofloat), + TEST_DF_REP (test_tbegin_aborts), + TEST_DF_REP (test_tbegin_indirect_aborts), + TEST_DF_REP (test_tbegin_nofloat_aborts), + TEST_DF_REP (test_tbegin_nofloat_indirect_aborts), + TEST_NO_REP (test_tbegin_retry_aborts), + TEST_NO_REP (test_tbegin_retry_nofloat_aborts), + TEST_DF_REP (test_tbegin_tdb), + TEST_DF_REP (test_tbegin_nofloat_tdb), + TEST_NO_REP (test_tbegin_retry_tdb), + TEST_NO_REP (test_tbegin_retry_nofloat_tdb), + TEST_DF_REP (test_etnd), + TEST_DF_REP (test_tbeginc), + { (void *)0, 0, 0 } + }; + + { + int rc; + + rc = run_all_tests (test_table); + + return rc; + } +} diff --git a/gcc/testsuite/gcc.target/s390/htm-builtins-2.c b/gcc/testsuite/gcc.target/s390/htm-builtins-2.c new file mode 100644 index 00000000000..15b0d12ae92 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-2.c @@ -0,0 +1,682 @@ +/* Functional tests of the htm __TM_... macros. */ + +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +/* ---------------------------- included header files ---------------------- */ + +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <htmxlintrin.h> + +/* ---------------------------- local definitions -------------------------- */ + +#define DEFAULT_MAX_REPETITIONS 5 +#define DEFAULT_REQUIRED_QUORUM ((DEFAULT_MAX_REPETITIONS) - 1) +#define DEFAULT_ABORT_ADDRESS (0x12345678u) + +/* ---------------------------- local macros ------------------------------- */ + +#define TEST_DF_REP(name) \ + { #name, name, DEFAULT_MAX_REPETITIONS, DEFAULT_REQUIRED_QUORUM } +#define TEST_NO_REP(name) { #name, name, 1, 1 } + +/* ---------------------------- local types -------------------------------- */ + +typedef int (*test_func_t)(void); + +typedef struct +{ + const char *name; + test_func_t test_func; + int max_repetitions; + int required_quorum; +} test_table_entry_t; + +typedef enum +{ + ABORT_T_SYSTEM = 0, + ABORT_T_USER = 1, +} abort_user_t; + +typedef enum +{ + ABORT_T_NONE = 0, + ABORT_T_ILLEGAL, + ABORT_T_FOOTPRINT_EXCEEDED, + ABORT_T_NESTED_TOO_DEEP, + ABORT_T_CONFLICT, + + ABORT_T_INVALID_ABORT_CODE +} abort_t; + +/* ---------------------------- local variables ---------------------------- */ + +__attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256; +static struct __htm_tdb local_tdb; + +static abort_t const abort_classes[] = +{ + ABORT_T_INVALID_ABORT_CODE, + ABORT_T_NONE, + ABORT_T_NONE, + ABORT_T_NONE, + + ABORT_T_ILLEGAL, + ABORT_T_NONE, + ABORT_T_NONE, + ABORT_T_FOOTPRINT_EXCEEDED, + + ABORT_T_FOOTPRINT_EXCEEDED, + ABORT_T_CONFLICT, + ABORT_T_CONFLICT, + ABORT_T_ILLEGAL, + + ABORT_T_NONE, + ABORT_T_NESTED_TOO_DEEP, + ABORT_T_NONE, + ABORT_T_NONE, + + ABORT_T_NONE +}; + +static size_t num_abort_classes = sizeof(abort_classes) / sizeof(abort_t); + +/* ---------------------------- exported variables (globals) --------------- */ + +int global_int = 0; +uint64_t global_u64 = 0; +float global_float_1 = 1.0; +float global_float_2 = 2.5; +float global_float_3 = 0.0; +__attribute__ ((aligned(256))) struct +{ + volatile uint64_t c1; + volatile uint64_t c2; + volatile uint64_t c3; +} counters = { 0, 0, 0 }; + +/* ---------------------------- local helper functions --------------------- */ + +static void dump_tdb(struct __htm_tdb *tdb) +{ + unsigned char *p; + int i; + int j; + + p = (unsigned char *)tdb; + for (i = 0; i < 16; i++) + { + fprintf(stderr, "0x%02x ", i * 16); + for (j = 0; j < 16; j++) + { + fprintf(stderr, "%02x", (int)p[i * 16 + j]); + if (j < 15) + { + fprintf(stderr, " "); + } + if (j == 7) + { + fprintf(stderr, " "); + } + } + fprintf(stderr, "\n"); + } + + return; +} + +static void make_fake_tdb(struct __htm_tdb *tdb) +{ + memset(tdb, 0, sizeof(*tdb)); + tdb->format = 1; + tdb->nesting_depth = 1; + tdb->atia = DEFAULT_ABORT_ADDRESS; + tdb->abort_code = 11; + + return; +} + +static int check_abort_code_in_tdb(struct __htm_tdb *tdb, uint64_t abort_code) +{ + long expect_rc; + long rc; + + if (abort_code != 0) + { + long addr; + + addr = __TM_failure_address(&local_tdb); + if (addr != DEFAULT_ABORT_ADDRESS) + { + return 11; + } + } + { + long long tdb_abort_code; + + tdb_abort_code = __TM_failure_code(tdb); + if ((uint64_t)tdb_abort_code != abort_code) + { + fprintf( + stderr, "tm_ac %" PRIu64 ", ac %" PRIu64 + ", tdb_ac %" PRIu64 "\n", + (uint64_t)tdb_abort_code, abort_code, + (uint64_t)tdb->abort_code); + return 10; + } + } + expect_rc = (abort_code >= 256) ? 1 : 0; + rc = __TM_is_user_abort(tdb); + if (rc != expect_rc) + { + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 1; + } + { + unsigned char code; + + code = 0xffu; + rc = __TM_is_named_user_abort(tdb, &code); + if (rc != expect_rc) + { + fprintf( + stderr, "rc %ld, expect_rc %ld\n", rc, + expect_rc); + return 2; + } + if (expect_rc == 1 && code != abort_code - 256) + { + return 3; + } + } + if (abort_code > (uint64_t)num_abort_classes) + { + abort_code = (uint64_t)num_abort_classes; + } + expect_rc = (abort_classes[abort_code] == ABORT_T_ILLEGAL) ? 1 : 0; + rc = __TM_is_illegal(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 4; + } + expect_rc = + (abort_classes[abort_code] == ABORT_T_FOOTPRINT_EXCEEDED) ? + 1 : 0; + rc = __TM_is_footprint_exceeded(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 5; + } + expect_rc = + (abort_classes[abort_code] == ABORT_T_NESTED_TOO_DEEP) ? 1 : 0; + rc = __TM_is_nested_too_deep(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 6; + } + expect_rc = (abort_classes[abort_code] == ABORT_T_CONFLICT) ? 1 : 0; + rc = __TM_is_conflict(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 7; + } + + return 0; +} + +/* ---------------------------- local test functions ----------------------- */ + +/* Not a test; make sure that the involved global cachelines are reserved for + * writing. */ +static int init_cache(void) +{ + make_fake_tdb(&local_tdb); + make_fake_tdb(&local_tdb256); + global_int = 0; + global_u64 = 0; + global_float_1 = 1.0; + global_float_2 = 2.5; + global_float_3 = 0.0; + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + + return 0; +} + +static int test_abort_classification(void) +{ + int i; + + make_fake_tdb(&local_tdb); + for (i = 0; i <= 256; i++) + { + int rc; + + local_tdb.abort_code = (uint64_t)i; + rc = check_abort_code_in_tdb(&local_tdb, (uint64_t)i); + if (rc != 0) + { + return 100 * i + rc; + } + } + + return 0; +} + +static int test_cc_classification(void) +{ + long rc; + + rc = __TM_is_failure_persistent(0); + if (rc != 0) + { + return 1; + } + rc = __TM_is_failure_persistent(1); + if (rc != 0) + { + return 2; + } + rc = __TM_is_failure_persistent(2); + if (rc != 0) + { + return 3; + } + rc = __TM_is_failure_persistent(3); + if (rc != 1) + { + return 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tend(void) +{ + long rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __TM_simple_begin()) == 0) + { + __TM_non_transactional_store((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tabort(void) +{ + register float f; + + counters.c1 = 0; + counters.c2 = 0; + f = 0; + if (__TM_simple_begin() == 0) + { + __TM_non_transactional_store((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + f = 1; + __TM_named_abort(0); + return 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 0) + { + return 100 * counters.c2 + 3; + } + if (f != 0) + { + return 100 * f + 4; + } + + return 0; +} + +static int test_tbegin_aborts(void) +{ + float f; + long rc; + + f = 77; + if ((rc = __TM_simple_begin()) == 0) + { + f = 88; + __TM_abort(); + return 2; + } + else if (rc != 2) + { + return 3; + } + if (f != 77) + { + return 4; + } + f = 66; + if ((rc = __TM_simple_begin()) == 0) + { + f = 99; + __TM_named_abort(3); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + if ((rc = __TM_simple_begin()) == 0) + { + global_float_3 = global_float_1 + global_float_2; + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 8; + } + } + else + { + return 100 * rc + 9; + } + if (global_float_3 != global_float_1 + global_float_2) + { + return 100 * rc + 10; + } + + return 0; +} + +static int test_tbegin_tdb(void) +{ + long rc; + + local_tdb.format = 0; + if ((rc = __TM_begin(&local_tdb)) == 0) + { + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb(&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __TM_begin(&local_tdb)) == 0) + { + __TM_named_abort(1); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb(&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __TM_begin(&local_tdb256)) == 0) + { + rc = __TM_end(); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb(&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } +#if 1 /*!!!does not work*/ + local_tdb256.format = 0; + if ((rc = __TM_begin(&local_tdb256)) == 0) + { + __TM_named_abort(1); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb(&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } +#endif + + return 0; +} + +static int test_etnd(void) +{ + long rc; + + { + long nd; + + make_fake_tdb(&local_tdb); + local_tdb.nesting_depth = 0; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 0) + { + return 1; + } + local_tdb.nesting_depth = 7; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 7) + { + return 7; + } + local_tdb.format = 0; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 0) + { + return 2; + } + } + counters.c1 = 0; + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __TM_simple_begin()) == 0) + { + counters.c1 = __TM_nesting_depth(0); + if (__TM_simple_begin() == 0) + { + counters.c2 = __TM_nesting_depth(0); + if (__TM_simple_begin() == 0) + { + counters.c3 = __TM_nesting_depth(0); + __TM_end(); + } + __TM_end(); + } + __TM_end(); + } + else + { + return 100 * rc + 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 4; + } + + return 0; +} + +/* ---------------------------- local testing framework functions ---------- */ + +static int run_one_test(const test_table_entry_t *test_entry) +{ + int do_print_passes; + int succeeded; + int rc; + int i; + + do_print_passes = ( + test_entry->required_quorum != 1 || + test_entry->max_repetitions != 1); + printf("RRR RUN %s\n", test_entry->name); + if (do_print_passes == 1) + { + printf( + " (requires %d successful out of %d runs)\n", + test_entry->required_quorum, + test_entry->max_repetitions); + } + succeeded = 0; + rc = 0; + for (rc = 0, i = 0; i < test_entry->max_repetitions; i++) + { + if (do_print_passes == 1) + { + if (i == 0) + { + printf(" "); + } + else + { + printf(","); + } + } + rc = test_entry->test_func(); + if (rc == 0) + { + if (do_print_passes == 1) + { + printf(" success"); + } + succeeded++; + if (succeeded >= test_entry->required_quorum) + { + break; + } + } + else + { + printf(" failed (rc = %d)", rc); + } + } + if (do_print_passes == 1 || rc != 0) + { + printf("\n"); + } + if (succeeded >= test_entry->required_quorum) + { + printf("+++ OK %s\n", test_entry->name); + + return 0; + } + else + { + printf("--- FAIL %s\n", test_entry->name); + + return (rc != 0) ? rc : -1; + } +} + +static int run_all_tests(const test_table_entry_t *test_table) +{ + const test_table_entry_t *test; + int rc; + + for ( + rc = 0, test = &test_table[0]; + test->test_func != NULL && rc == 0; test++) + { + rc = run_one_test(test); + } + + return rc; +} + +/* ---------------------------- interface functions ------------------------ */ + +int main(void) +{ + const test_table_entry_t test_table[] = { + TEST_NO_REP(init_cache), + TEST_NO_REP(test_abort_classification), + TEST_NO_REP(test_cc_classification), + TEST_DF_REP(test_tbegin_ntstg_tend), + TEST_DF_REP(test_tbegin_ntstg_tabort), + TEST_DF_REP(test_tbegin_aborts), + TEST_DF_REP(test_tbegin_tdb), + TEST_DF_REP(test_etnd), + { (void *)0, 0, 0 } + }; + + { + int rc; + + rc = run_all_tests(test_table); + + return rc; + } +} diff --git a/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c new file mode 100644 index 00000000000..c1b98e2bba4 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c @@ -0,0 +1,164 @@ +/* This checks the availability of the low-level builtins introduced + for transactional execution. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +#include <stdint.h> +#include <htmintrin.h> + +int global = 0; +uint64_t g; +struct __htm_tdb global_tdb; + +int +foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) +{ + + int cc; + int n; + + __builtin_tbegin ((void *)0); + __builtin_tbegin ((void *)-99999); + __builtin_tbegin ((void *)99999); + while (__builtin_tbegin ((void *)0) != 0) + { + } + cc = __builtin_tbegin ((void *)0x12345678); + cc = __builtin_tbegin (tdb); + cc = __builtin_tbegin (&global_tdb); + cc = __builtin_tbegin ((void *)(long long)(reg + 0x12345678)); + cc = __builtin_tbegin ((void *)(long long)(reg)); + + __builtin_tbegin_nofloat ((void *)0); + __builtin_tbegin_nofloat ((void *)-99999); + __builtin_tbegin_nofloat ((void *)99999); + cc = __builtin_tbegin_nofloat ((void *)0x12345678); + cc = __builtin_tbegin_nofloat (tdb); + cc = __builtin_tbegin_nofloat (&global_tdb); + cc = __builtin_tbegin_nofloat ((void *)(long long)(reg + 0x12345678)); + cc = __builtin_tbegin_nofloat ((void *)(long long)(reg)); + + __builtin_tbegin_retry ((void *)0, 0); + cc = __builtin_tbegin_retry ((void *)0, 1); + cc = __builtin_tbegin_retry ((void *)0, -1); + cc = __builtin_tbegin_retry ((void *)0, 42); + cc = __builtin_tbegin_retry ((void *)0, reg); + cc = __builtin_tbegin_retry ((void *)0, *mem); + cc = __builtin_tbegin_retry ((void *)0, global); + cc = __builtin_tbegin_retry (tdb, 42); + cc = __builtin_tbegin_retry (&global_tdb, 42); + cc = __builtin_tbegin_retry ((void *)0x12345678, global); + cc = __builtin_tbegin_retry ( + (void *)(long long) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry ( + (void *)(long long)(reg), global - 1); + + __builtin_tbegin_retry_nofloat ((void *)0, 0); + cc = __builtin_tbegin_retry_nofloat ((void *)0, 1); + cc = __builtin_tbegin_retry_nofloat ((void *)0, -1); + cc = __builtin_tbegin_retry_nofloat ((void *)0, 42); + cc = __builtin_tbegin_retry_nofloat ((void *)0, reg); + cc = __builtin_tbegin_retry_nofloat ((void *)0, *mem); + cc = __builtin_tbegin_retry_nofloat ((void *)0, global); + cc = __builtin_tbegin_retry_nofloat (tdb, 42); + cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42); + cc = __builtin_tbegin_retry_nofloat ((void *)0x12345678, global); + cc = __builtin_tbegin_retry_nofloat ( + (void *)(long long) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry_nofloat ( + (void *)(long long)(reg), global - 1); + + __builtin_tbeginc (); + + __builtin_tx_nesting_depth (); + n = __builtin_tx_nesting_depth (); + + __builtin_non_tx_store (mem64, 0); + { + const uint64_t val_var = 0x1122334455667788; + + __builtin_non_tx_store (mem64, val_var); + } + __builtin_non_tx_store (mem64, (uint64_t)reg); + __builtin_non_tx_store (mem64, g); + __builtin_non_tx_store ((uint64_t *)0, 0); + __builtin_non_tx_store ((uint64_t *)0x12345678, 0); + __builtin_non_tx_store (&g, 23); + __builtin_non_tx_store (&g, reg); + __builtin_non_tx_store (&g, *mem); + __builtin_non_tx_store (&g, global); + + __builtin_tend(); + + __builtin_tx_assist (0); + __builtin_tx_assist (1); + __builtin_tx_assist (reg); + __builtin_tx_assist (*mem); + __builtin_tx_assist (global); +} + +/* The taborts must go into separate function since they are + "noreturn". */ + +void +tabort1 () +{ + __builtin_tabort (256); +} + +void +tabort2 (int reg) +{ + __builtin_tabort (reg); +} + +void +tabort3 (int reg) +{ + /* { dg-final { scan-assembler-times "tabort\t255" 1 } } */ + __builtin_tabort (reg + 255); +} + +void +tabort4 (int *mem) +{ + __builtin_tabort (*mem); +} + +void +tabort5 () +{ + __builtin_tabort (global); +} + +void +tabort6 (int *mem) +{ + /* Here global + 255 gets reloaded into a reg. Better would be to + just reload global or *mem and get the +255 for free as address + arithmetic. */ + __builtin_tabort (*mem + 255); +} + +void +tabort7 () +{ + __builtin_tabort (global + 255); +} + +void +tabort8 () +{ + __builtin_tabort (-1); +} + + +/* Make sure the tdb NULL argument ends up as immediate value in the + instruction. */ +/* { dg-final { scan-assembler-times "tbegin\t0," 17 } } */ +/* { dg-final { scan-assembler-times "tbegin\t" 41 } } */ +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "tbeginc\t" 1 } } */ +/* { dg-final { scan-assembler-times "tabort\t" 8 } } */ +/* { dg-final { scan-assembler "ppa\t" } } */ diff --git a/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c new file mode 100644 index 00000000000..67d76a6d3d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +void must_not_compile1 (void) +{ + __builtin_tabort (0); /* { dg-error "Invalid transaction abort code:" } */ +} + +void must_not_compile2 (void) +{ + __builtin_tabort (255); /* { dg-error "Invalid transaction abort code:" } */ +} diff --git a/gcc/testsuite/gcc.target/s390/htm-xl-intrin-1.c b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c index 77ceeb7706f..77ceeb7706f 100644 --- a/gcc/testsuite/gcc.target/s390/htm-xl-intrin-1.c +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp index a4a6609cb01..f7f9ad25607 100644 --- a/gcc/testsuite/gcc.target/s390/s390.exp +++ b/gcc/testsuite/gcc.target/s390/s390.exp @@ -24,6 +24,19 @@ if ![istarget s390*-*-*] then { # Load support procs. load_lib gcc-dg.exp +# Return 1 if htm (etnd - extract nesting depth) instructions can be +# compiled. +proc check_effective_target_htm { } { + if { ![check_runtime s390_check_htm [subst { + int main (void) + { + unsigned int nd = 77; + asm (".insn rre,0xb2ec0000,%0,0" : "=d" (nd)); + return nd; + } + }]] } { return 0 } else { return 1 } +} + # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr57517.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr57517.f90 new file mode 100644 index 00000000000..f32698aa3a6 --- /dev/null +++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr57517.f90 @@ -0,0 +1,13 @@ +SUBROUTINE cal_helicity (uh, ph, phb, wavg, ims, ime, its, ite) + INTEGER, INTENT( IN ) :: ims, ime, its, ite + REAL, DIMENSION( ims:ime), INTENT( IN ) :: ph, phb, wavg + REAL, DIMENSION( ims:ime), INTENT( INOUT ) :: uh + INTEGER :: i + REAL :: zu + DO i = its, ite + zu = (ph(i ) + phb(i)) + (ph(i-1) + phb(i-1)) + IF (wavg(i) .GT. 0) THEN + uh(i) = uh(i) + zu + ENDIF + END DO +END SUBROUTINE cal_helicity |