diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg')
92 files changed, 6718 insertions, 683 deletions
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-1.c b/gcc/testsuite/gcc.dg/gomp/atomic-1.c deleted file mode 100644 index 3e4bc569ba7..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-10.c b/gcc/testsuite/gcc.dg/gomp/atomic-10.c deleted file mode 100644 index 936d0c1f223..00000000000 --- a/gcc/testsuite/gcc.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/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/atomic-12.c b/gcc/testsuite/gcc.dg/gomp/atomic-12.c deleted file mode 100644 index 618c4c8e648..00000000000 --- a/gcc/testsuite/gcc.dg/gomp/atomic-12.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/gcc.dg/gomp/atomic-13.c b/gcc/testsuite/gcc.dg/gomp/atomic-13.c deleted file mode 100644 index 0146825f2bb..00000000000 --- a/gcc/testsuite/gcc.dg/gomp/atomic-13.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-12.c" diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-14.c b/gcc/testsuite/gcc.dg/gomp/atomic-14.c deleted file mode 100644 index f8fc9d87257..00000000000 --- a/gcc/testsuite/gcc.dg/gomp/atomic-14.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/gcc.dg/gomp/atomic-15.c b/gcc/testsuite/gcc.dg/gomp/atomic-15.c deleted file mode 100644 index 13a9e0ce48a..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-2.c b/gcc/testsuite/gcc.dg/gomp/atomic-2.c deleted file mode 100644 index 720ec9e8ba0..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-3.c b/gcc/testsuite/gcc.dg/gomp/atomic-3.c deleted file mode 100644 index 7ea792d3457..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-4.c b/gcc/testsuite/gcc.dg/gomp/atomic-4.c deleted file mode 100644 index 7f27370d535..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-7.c b/gcc/testsuite/gcc.dg/gomp/atomic-7.c deleted file mode 100644 index 612e97f4530..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-8.c b/gcc/testsuite/gcc.dg/gomp/atomic-8.c deleted file mode 100644 index 2f04151f0ed..00000000000 --- a/gcc/testsuite/gcc.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/gcc.dg/gomp/atomic-9.c b/gcc/testsuite/gcc.dg/gomp/atomic-9.c deleted file mode 100644 index 2fafbd4097a..00000000000 --- a/gcc/testsuite/gcc.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/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; } |