diff options
Diffstat (limited to 'gcc/testsuite/gcc.target')
59 files changed, 1371 insertions, 27 deletions
diff --git a/gcc/testsuite/gcc.target/arm/eliminate.c b/gcc/testsuite/gcc.target/arm/eliminate.c new file mode 100644 index 00000000000..f254dd811d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/eliminate.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct X +{ + int c; +}; + +extern void bar(struct X *); + +void foo () +{ + struct X x; + bar (&x); + bar (&x); + bar (&x); +} + +/* { dg-final { scan-assembler-times "r0,\[\\t \]*sp" 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr40900.c b/gcc/testsuite/gcc.target/arm/pr40900.c new file mode 100644 index 00000000000..278bc370223 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr40900.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-optimize-sibling-calls" } */ + +extern short shortv2(); +short shortv1() +{ + return shortv2(); +} + +/* { dg-final { scan-assembler-not "lsl" } } */ +/* { dg-final { scan-assembler-not "asr" } } */ +/* { dg-final { scan-assembler-not "sxth" } } */ diff --git a/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-1.c b/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-1.c new file mode 100644 index 00000000000..d75f13aa089 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-1.c @@ -0,0 +1,12 @@ +/* Use ADDS clobbering source operand, rather than CMN */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "adds" } } */ +/* { dg-final { scan-assembler-not "cmn" } } */ + +void foo1(void); +void bar5(int x) +{ + if (x == -15) + foo1(); +} diff --git a/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-2.c b/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-2.c new file mode 100644 index 00000000000..358bc6e143c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-2.c @@ -0,0 +1,12 @@ +/* Use ADDS with a scratch, rather than CMN */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "adds" } } */ +/* { dg-final { scan-assembler-not "cmn" } } */ + +void foo1(int); +void bar5(int x) +{ + if (x == -1) + foo1(x); +} diff --git a/gcc/testsuite/gcc.target/arm/wmul-1.c b/gcc/testsuite/gcc.target/arm/wmul-1.c index df85e7cb285..ccb3041551a 100644 --- a/gcc/testsuite/gcc.target/arm/wmul-1.c +++ b/gcc/testsuite/gcc.target/arm/wmul-1.c @@ -15,4 +15,4 @@ int mac(const short *a, const short *b, int sqr, int *sum) return sqr; } -/* { dg-final { scan-assembler-times "smulbb" 2 } } */ +/* { dg-final { scan-assembler-times "smlabb" 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/wmul-3.c b/gcc/testsuite/gcc.target/arm/wmul-3.c new file mode 100644 index 00000000000..325dcebbbda --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv6t2" } */ + +int mac(const short *a, const short *b, int sqr, int *sum) +{ + int i; + int dotp = *sum; + + for (i = 0; i < 150; i++) { + dotp -= b[i] * a[i]; + sqr -= b[i] * b[i]; + } + + *sum = dotp; + return sqr; +} + +/* { dg-final { scan-assembler-times "smulbb" 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/wmul-4.c b/gcc/testsuite/gcc.target/arm/wmul-4.c new file mode 100644 index 00000000000..e8642f8aed1 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-4.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv6t2" } */ + +int mac(const int *a, const int *b, long long sqr, long long *sum) +{ + int i; + long long dotp = *sum; + + for (i = 0; i < 150; i++) { + dotp += (long long) b[i] * a[i]; + sqr += (long long) b[i] * b[i]; + } + + *sum = dotp; + return sqr; +} + +/* { dg-final { scan-assembler-times "smlal" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/abi-2.c b/gcc/testsuite/gcc.target/i386/abi-2.c index 5ed6b4a56dd..39eafc25039 100644 --- a/gcc/testsuite/gcc.target/i386/abi-2.c +++ b/gcc/testsuite/gcc.target/i386/abi-2.c @@ -1,6 +1,7 @@ /* Make certain that we pass __m256i in the correct register for AVX. */ /* { dg-do compile } */ /* { dg-options "-O1 -mavx" } */ +/* { dg-options "-mabi=sysv -O1 -mavx" { target x86_64-*-mingw* } } */ typedef long long __m256i __attribute__ ((__vector_size__ (32))); __m256i foo (void) { return (__m256i){ 1, 2, 3, 4 }; } diff --git a/gcc/testsuite/gcc.target/i386/aes-avx-check.h b/gcc/testsuite/gcc.target/i386/aes-avx-check.h index e73e36eab25..e91e88173cf 100644 --- a/gcc/testsuite/gcc.target/i386/aes-avx-check.h +++ b/gcc/testsuite/gcc.target/i386/aes-avx-check.h @@ -6,6 +6,13 @@ static void aes_avx_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + aes_avx_test (); +} + int main () { @@ -17,7 +24,7 @@ main () /* Run AES + AVX test only if host has AES + AVX support. */ if ((ecx & (bit_AVX | bit_AES)) == (bit_AVX | bit_AES)) { - aes_avx_test (); + do_test (); #ifdef DEBUG printf ("PASSED\n"); #endif diff --git a/gcc/testsuite/gcc.target/i386/aes-check.h b/gcc/testsuite/gcc.target/i386/aes-check.h index f56f1adeb3e..7e794423e47 100644 --- a/gcc/testsuite/gcc.target/i386/aes-check.h +++ b/gcc/testsuite/gcc.target/i386/aes-check.h @@ -5,6 +5,13 @@ static void aes_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + aes_test (); +} + int main () { @@ -16,7 +23,7 @@ main () /* Run AES test only if host has AES support. */ if (ecx & bit_AES) { - aes_test (); + do_test (); #ifdef DEBUG printf ("PASSED\n"); #endif diff --git a/gcc/testsuite/gcc.target/i386/amd64-abi-3.c b/gcc/testsuite/gcc.target/i386/amd64-abi-3.c index 8db7f13b1ea..6b7bf6a6e5f 100644 --- a/gcc/testsuite/gcc.target/i386/amd64-abi-3.c +++ b/gcc/testsuite/gcc.target/i386/amd64-abi-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O2 -fomit-frame-pointer -mno-sse" } */ +/* { dg-options "-O2 -fomit-frame-pointer -mno-sse -mtune=k8" } */ /* { dg-final { scan-assembler "subq\[\\t \]*\\\$88,\[\\t \]*%rsp" } } */ /* { dg-final { scan-assembler-not "subq\[\\t \]*\\\$216,\[\\t \]*%rsp" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx-check.h b/gcc/testsuite/gcc.target/i386/avx-check.h index 8db55a10357..7736fc9f40b 100644 --- a/gcc/testsuite/gcc.target/i386/avx-check.h +++ b/gcc/testsuite/gcc.target/i386/avx-check.h @@ -4,6 +4,13 @@ static void avx_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + avx_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run AVX test only if host has AVX support. */ if (ecx & bit_AVX) { - avx_test (); + do_test (); #ifdef DEBUG printf ("PASSED\n"); #endif diff --git a/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-3.c b/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-3.c new file mode 100644 index 00000000000..b7d4a373101 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-3.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx } */ +/* { dg-options "-O2 -mavx" } */ + +#define OFFSET 0 + +#include "avx-vextractf128-256-1.c" diff --git a/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-4.c b/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-4.c new file mode 100644 index 00000000000..973fa58b12a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-vextractf128-256-4.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx } */ +/* { dg-options "-O2 -mavx" } */ + +#define OFFSET 0 + +#include "avx-vextractf128-256-2.c" diff --git a/gcc/testsuite/gcc.target/i386/extract-1.c b/gcc/testsuite/gcc.target/i386/extract-1.c new file mode 100644 index 00000000000..102beb230ac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +int +foo (unsigned char x, unsigned char y) +{ + return (x % y) != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-d\]l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-2.c b/gcc/testsuite/gcc.target/i386/extract-2.c new file mode 100644 index 00000000000..3bb5f154c4e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +int +foo (unsigned char x, unsigned char y) +{ + return (x % y) > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-d\]h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-d\]l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-3.c b/gcc/testsuite/gcc.target/i386/extract-3.c new file mode 100644 index 00000000000..520bf3bb557 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned char c1; + unsigned char c2; + unsigned char c3; + unsigned char c4; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-4.c b/gcc/testsuite/gcc.target/i386/extract-4.c new file mode 100644 index 00000000000..716ae2299ea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned char c1; + unsigned char c2; + unsigned char c3; + unsigned char c4; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-5.c b/gcc/testsuite/gcc.target/i386/extract-5.c new file mode 100644 index 00000000000..a488dafa20f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned int c1:8; + unsigned int c2:8; + unsigned int c3:8; + unsigned int c4:8; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-6.c b/gcc/testsuite/gcc.target/i386/extract-6.c new file mode 100644 index 00000000000..1440ec3be35 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-6.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned int c1:8; + unsigned int c2:8; + unsigned int c3:8; + unsigned int c4:8; + +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/fma4-check.h b/gcc/testsuite/gcc.target/i386/fma4-check.h index 76fcdef99b6..dc7ee574878 100644 --- a/gcc/testsuite/gcc.target/i386/fma4-check.h +++ b/gcc/testsuite/gcc.target/i386/fma4-check.h @@ -4,6 +4,13 @@ static void fma4_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + fma4_test (); +} + int main () { @@ -14,7 +21,7 @@ main () /* Run FMA4 test only if host has FMA4 support. */ if (ecx & bit_FMA4) - fma4_test (); + do_test (); exit (0); } diff --git a/gcc/testsuite/gcc.target/i386/mmx-3dnow-check.h b/gcc/testsuite/gcc.target/i386/mmx-3dnow-check.h index 458e7cda898..4f2f7f3ac40 100644 --- a/gcc/testsuite/gcc.target/i386/mmx-3dnow-check.h +++ b/gcc/testsuite/gcc.target/i386/mmx-3dnow-check.h @@ -5,6 +5,13 @@ static void mmx_3dnow_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + mmx_3dnow_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run 3DNow! test only if host has 3DNow! support. */ if (edx & bit_3DNOW) - mmx_3dnow_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/mmx-check.h b/gcc/testsuite/gcc.target/i386/mmx-check.h index aefdc4e8799..faf9b876f38 100644 --- a/gcc/testsuite/gcc.target/i386/mmx-check.h +++ b/gcc/testsuite/gcc.target/i386/mmx-check.h @@ -5,6 +5,13 @@ static void mmx_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + mmx_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run MMX test only if host has MMX support. */ if (edx & bit_MMX) - mmx_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/mod-1.c b/gcc/testsuite/gcc.target/i386/mod-1.c new file mode 100644 index 00000000000..a7b1a92258d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mod-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -mtune=generic" } */ + +typedef struct { + int a; +} VCR; + +typedef struct { + VCR vcr[8]; +} VCRC; + +typedef struct { + char vcr; +} OWN; + +OWN Own[16]; + +void +f (VCRC *x, OWN *own) +{ + x[own->vcr / 8].vcr[own->vcr % 8].a--; + x[own->vcr / 8].vcr[own->vcr % 8].a = x[own->vcr / 8].vcr[own->vcr % 8].a; +} + +/* { dg-final { scan-assembler-times "idivb" 1 } } */ +/* { dg-final { scan-assembler-not "incl" } } */ +/* { dg-final { scan-assembler-not "orl" } } */ +/* { dg-final { scan-assembler-not "andb" } } */ +/* { dg-final { scan-assembler-not "jns" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pclmul-avx-check.h b/gcc/testsuite/gcc.target/i386/pclmul-avx-check.h index de633336157..550e49904d9 100644 --- a/gcc/testsuite/gcc.target/i386/pclmul-avx-check.h +++ b/gcc/testsuite/gcc.target/i386/pclmul-avx-check.h @@ -6,6 +6,13 @@ static void pclmul_avx_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + pclmul_avx_test (); +} + int main () { @@ -17,7 +24,7 @@ main () /* Run PCLMUL + AVX test only if host has PCLMUL + AVX support. */ if ((ecx & (bit_AVX | bit_PCLMUL)) == (bit_AVX | bit_PCLMUL)) { - pclmul_avx_test (); + do_test (); #ifdef DEBUG printf ("PASSED\n"); #endif diff --git a/gcc/testsuite/gcc.target/i386/pclmul-check.h b/gcc/testsuite/gcc.target/i386/pclmul-check.h index 706fd640034..7526cbe2ddf 100644 --- a/gcc/testsuite/gcc.target/i386/pclmul-check.h +++ b/gcc/testsuite/gcc.target/i386/pclmul-check.h @@ -5,6 +5,13 @@ static void pclmul_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + pclmul_test (); +} + int main () { @@ -16,7 +23,7 @@ main () /* Run PCLMULQDQ test only if host has PCLMULQDQ support. */ if (ecx & bit_PCLMUL) { - pclmul_test (); + do_test (); #ifdef DEBUG printf ("PASSED\n"); #endif diff --git a/gcc/testsuite/gcc.target/i386/pr27971.c b/gcc/testsuite/gcc.target/i386/pr27971.c index 8c706adda59..27888de6d2f 100644 --- a/gcc/testsuite/gcc.target/i386/pr27971.c +++ b/gcc/testsuite/gcc.target/i386/pr27971.c @@ -3,7 +3,13 @@ unsigned array[4]; -unsigned foo(unsigned long x) +#ifdef _WIN64 +__extension__ typedef unsigned long long TYPE; +#else +#define TYPE unsigned long +#endif + +unsigned foo(TYPE x) { return array[(x>>2)&3ul]; } diff --git a/gcc/testsuite/gcc.target/i386/pr39139.c b/gcc/testsuite/gcc.target/i386/pr39139.c index 95ea7fda9ba..e4cb845f9ec 100644 --- a/gcc/testsuite/gcc.target/i386/pr39139.c +++ b/gcc/testsuite/gcc.target/i386/pr39139.c @@ -12,22 +12,24 @@ # define SI_REG asm ("esi") #endif +__extension__ typedef __SIZE_TYPE__ size_t; + static inline int foo (unsigned int x, void *y) { - register unsigned long r AX_REG; - register unsigned long a1 DI_REG; - register unsigned long a2 SI_REG; - a1 = (unsigned long) x; - a2 = (unsigned long) y; + register size_t r AX_REG; + register size_t a1 DI_REG; + register size_t a2 SI_REG; + a1 = (size_t) x; + a2 = (size_t) y; asm volatile ("" : "=r" (r), "+r" (a1), "+r" (a2) : : "memory"); return (int) r; } -struct T { unsigned long t1, t2; unsigned int t3, t4, t5; }; +struct T { size_t t1, t2; unsigned int t3, t4, t5; }; int -bar (unsigned long x, unsigned int y, unsigned long u, unsigned int v) +bar (size_t x, unsigned int y, size_t u, unsigned int v) { long r; struct T e = { .t1 = x, .t2 = u }; diff --git a/gcc/testsuite/gcc.target/i386/pr39315-check.c b/gcc/testsuite/gcc.target/i386/pr39315-check.c index ff926057536..8f7376015d0 100644 --- a/gcc/testsuite/gcc.target/i386/pr39315-check.c +++ b/gcc/testsuite/gcc.target/i386/pr39315-check.c @@ -1,4 +1,6 @@ +/* { dg-compile } */ typedef float __m128 __attribute__ ((__vector_size__ (16))); +__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t; extern void foo (__m128 *); extern void abort (void); @@ -8,7 +10,7 @@ __m128 y = { 0.0, 1.0, 2.0, 3.0 }; void bar (__m128 *x, int align) { - if ((((__PTRDIFF_TYPE__) x) & (align - 1)) != 0) + if ((((ptrdiff_t) x) & (align - 1)) != 0) abort (); if (__builtin_memcmp (x, &y, sizeof (y)) != 0) abort (); diff --git a/gcc/testsuite/gcc.target/i386/pr44481.c b/gcc/testsuite/gcc.target/i386/pr44481.c new file mode 100644 index 00000000000..701268b5656 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr44481.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +static inline unsigned +parity (unsigned x) +{ + return (unsigned) __builtin_parity (x); +} + +unsigned +f (unsigned rpoly) +{ + return parity (rpoly & 1) ^ parity (rpoly & 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr44546.c b/gcc/testsuite/gcc.target/i386/pr44546.c new file mode 100644 index 00000000000..517446fdc8f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr44546.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -ffast-math -mfpmath=387" } */ + +typedef __SIZE_TYPE__ size_t; +typedef struct +{ + float *ewgts; +} vtx_data; + +extern void *zmalloc (size_t); +extern int whatever (vtx_data *); + +float * +compute_apsp_artifical_weights_packed (vtx_data * graph, int n) +{ + float *weights; + + weights = (float *) zmalloc (n * sizeof (float)); + weights[n] = + whatever (graph) > graph[n].ewgts[n] ? + whatever (graph) : graph[n].ewgts[n]; +} diff --git a/gcc/testsuite/gcc.target/i386/sse-check.h b/gcc/testsuite/gcc.target/i386/sse-check.h index 79ea4815517..85629cc71b9 100644 --- a/gcc/testsuite/gcc.target/i386/sse-check.h +++ b/gcc/testsuite/gcc.target/i386/sse-check.h @@ -6,6 +6,13 @@ static void sse_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse_test (); +} + int main () { @@ -16,7 +23,7 @@ main () /* Run SSE test only if host has SSE support. */ if (edx & bit_SSE) - sse_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/sse2-check.h b/gcc/testsuite/gcc.target/i386/sse2-check.h index a69333e391a..e9f17f04079 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-check.h +++ b/gcc/testsuite/gcc.target/i386/sse2-check.h @@ -4,6 +4,13 @@ static void sse2_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse2_test (); +} + int main () { @@ -14,7 +21,7 @@ main () /* Run SSE2 test only if host has SSE2 support. */ if (edx & bit_SSE2) - sse2_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/sse2-vec-2a.c b/gcc/testsuite/gcc.target/i386/sse2-vec-2a.c new file mode 100644 index 00000000000..f230f27d45a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-vec-2a.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse2 -mtune=atom" } */ +/* { dg-require-effective-target sse2 } */ + +#include "sse2-vec-2.c" diff --git a/gcc/testsuite/gcc.target/i386/sse3-check.h b/gcc/testsuite/gcc.target/i386/sse3-check.h index 92930d10a3f..df0e63a4575 100644 --- a/gcc/testsuite/gcc.target/i386/sse3-check.h +++ b/gcc/testsuite/gcc.target/i386/sse3-check.h @@ -5,6 +5,13 @@ static void sse3_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse3_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run SSE3 test only if host has SSE3 support. */ if (ecx & bit_SSE3) - sse3_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-check.h b/gcc/testsuite/gcc.target/i386/sse4_1-check.h index 2d1c4e835a3..788f65d61cb 100644 --- a/gcc/testsuite/gcc.target/i386/sse4_1-check.h +++ b/gcc/testsuite/gcc.target/i386/sse4_1-check.h @@ -7,6 +7,13 @@ static void sse4_1_test (void); #define MASK 0x2 +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse4_1_test (); +} + int main () { @@ -17,7 +24,7 @@ main () /* Run SSE4.1 test only if host has SSE4.1 support. */ if (ecx & bit_SSE4_1) - sse4_1_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/sse4_2-check.h b/gcc/testsuite/gcc.target/i386/sse4_2-check.h index 2a397e88683..d10e6c7d7e2 100644 --- a/gcc/testsuite/gcc.target/i386/sse4_2-check.h +++ b/gcc/testsuite/gcc.target/i386/sse4_2-check.h @@ -5,6 +5,13 @@ static void sse4_2_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse4_2_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run SSE4.2 test only if host has SSE4.2 support. */ if (ecx & bit_SSE4_2) - sse4_2_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/sse4a-check.h b/gcc/testsuite/gcc.target/i386/sse4a-check.h index d6140e8969c..d43b4b222b1 100644 --- a/gcc/testsuite/gcc.target/i386/sse4a-check.h +++ b/gcc/testsuite/gcc.target/i386/sse4a-check.h @@ -5,6 +5,13 @@ static void sse4a_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse4a_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run SSE4a test only if host has SSE4a support. */ if (ecx & bit_SSE4a) - sse4a_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/ssse3-check.h b/gcc/testsuite/gcc.target/i386/ssse3-check.h index 78df15db7d7..3ca79333c7f 100644 --- a/gcc/testsuite/gcc.target/i386/ssse3-check.h +++ b/gcc/testsuite/gcc.target/i386/ssse3-check.h @@ -5,6 +5,13 @@ static void ssse3_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + ssse3_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run SSSE3 test only if host has SSSE3 support. */ if (ecx & bit_SSSE3) - ssse3_test (); + do_test (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/umod-1.c b/gcc/testsuite/gcc.target/i386/umod-1.c new file mode 100644 index 00000000000..54edf139d5a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/umod-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=atom" } */ + +unsigned char +foo (unsigned char x, unsigned char y) +{ + return x % y; +} + +/* { dg-final { scan-assembler-times "divb" 1 } } */ +/* { dg-final { scan-assembler-not "divw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/umod-2.c b/gcc/testsuite/gcc.target/i386/umod-2.c new file mode 100644 index 00000000000..6fe73846833 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/umod-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=atom" } */ + +extern unsigned char z; + +unsigned char +foo (unsigned char x, unsigned char y) +{ + z = x/y; + return x % y; +} + +/* { dg-final { scan-assembler-times "divb" 1 } } */ +/* { dg-final { scan-assembler-not "divw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/umod-3.c b/gcc/testsuite/gcc.target/i386/umod-3.c new file mode 100644 index 00000000000..7123bc9f256 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/umod-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=atom" } */ + +extern void abort (void); +extern void exit (int); + +unsigned char cx = 7; + +int +main () +{ + unsigned char cy; + + cy = cx / 6; if (cy != 1) abort (); + cy = cx % 6; if (cy != 1) abort (); + + exit(0); +} + +/* { dg-final { scan-assembler-times "divb" 1 } } */ +/* { dg-final { scan-assembler-not "divw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vararg-1.c b/gcc/testsuite/gcc.target/i386/vararg-1.c index cfb1e30ab07..9ed9ab087d0 100644 --- a/gcc/testsuite/gcc.target/i386/vararg-1.c +++ b/gcc/testsuite/gcc.target/i386/vararg-1.c @@ -1,6 +1,7 @@ /* PR middle-end/36858 */ /* { dg-do run } */ /* { dg-options "-w" { target { lp64 } } } */ +/* { dg-options "-w" { target { llp64 } } } */ /* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */ /* { dg-require-effective-target sse2 } */ diff --git a/gcc/testsuite/gcc.target/i386/vararg-2.c b/gcc/testsuite/gcc.target/i386/vararg-2.c index 60793173d6c..804801256f1 100644 --- a/gcc/testsuite/gcc.target/i386/vararg-2.c +++ b/gcc/testsuite/gcc.target/i386/vararg-2.c @@ -1,6 +1,7 @@ /* PR middle-end/36859 */ /* { dg-do run } */ /* { dg-options "-w" { target { lp64 } } } */ +/* { dg-options "-w" { target { llp64 } } } */ /* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */ /* { dg-require-effective-target sse2 } */ diff --git a/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c b/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c new file mode 100644 index 00000000000..01a35f9f920 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-volatile-bitfields" } */ + +typedef struct { + char a:1; + char b:7; + int c; +} BitStruct; + +volatile BitStruct bits; + +int foo () +{ + return bits.b; +} + +/* { dg-final { scan-assembler "movzbl.*bits" } } */ diff --git a/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c b/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c new file mode 100644 index 00000000000..302625a199b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-strict-volatile-bitfields" } */ + +typedef struct { + char a:1; + char b:7; + int c; +} BitStruct; + +volatile BitStruct bits; + +int foo () +{ + return bits.b; +} + +/* { dg-final { scan-assembler "movl.*bits" } } */ diff --git a/gcc/testsuite/gcc.target/i386/xop-check.h b/gcc/testsuite/gcc.target/i386/xop-check.h index fb98c6d4bd4..7e8e665c79f 100644 --- a/gcc/testsuite/gcc.target/i386/xop-check.h +++ b/gcc/testsuite/gcc.target/i386/xop-check.h @@ -5,6 +5,13 @@ static void xop_test (void); +static void +__attribute__ ((noinline)) +do_test (void) +{ + xop_test (); +} + int main () { @@ -15,7 +22,7 @@ main () /* Run XOP test only if host has XOP support. */ if (ecx & bit_XOP) - xop_test (); + do_test (); exit (0); } diff --git a/gcc/testsuite/gcc.target/mips/madd-9.c b/gcc/testsuite/gcc.target/mips/madd-9.c new file mode 100644 index 00000000000..25dbd18a510 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/madd-9.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 isa_rev>=1 -mgp32" } */ +/* { dg-final { scan-assembler-not "\tmul\t" } } */ +/* { dg-final { scan-assembler "\tmadd\t" } } */ + +NOMIPS16 long long +f1 (int *a, int *b, int n) +{ + long long int x; + int i; + + x = 0; + for (i = 0; i < n; i++) + x += (long long) a[i] * b[i]; + return x; +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-1.c b/gcc/testsuite/gcc.target/powerpc/recip-1.c new file mode 100644 index 00000000000..d1e383dc4ea --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mrecip -ffast-math -mcpu=power6" } */ +/* { dg-final { scan-assembler-times "frsqrte" 2 } } */ +/* { dg-final { scan-assembler-times "fmsub" 2 } } */ +/* { dg-final { scan-assembler-times "fmul" 8 } } */ +/* { dg-final { scan-assembler-times "fnmsub" 4 } } */ + +double +rsqrt_d (double a) +{ + return 1.0 / __builtin_sqrt (a); +} + +float +rsqrt_f (float a) +{ + return 1.0f / __builtin_sqrtf (a); +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-2.c b/gcc/testsuite/gcc.target/powerpc/recip-2.c new file mode 100644 index 00000000000..69442733aab --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mrecip -ffast-math -mcpu=power5" } */ +/* { dg-final { scan-assembler-times "frsqrtes" 1 } } */ +/* { dg-final { scan-assembler-times "fmsubs" 1 } } */ +/* { dg-final { scan-assembler-times "fmuls" 6 } } */ +/* { dg-final { scan-assembler-times "fnmsubs" 3 } } */ +/* { dg-final { scan-assembler-times "fsqrt" 1 } } */ + +/* power5 resqrte is not accurate enough, and should not be generated by + default for -mrecip. */ +double +rsqrt_d (double a) +{ + return 1.0 / __builtin_sqrt (a); +} + +float +rsqrt_f (float a) +{ + return 1.0f / __builtin_sqrtf (a); +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-3.c b/gcc/testsuite/gcc.target/powerpc/recip-3.c new file mode 100644 index 00000000000..80a34e8ee59 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2 -mrecip -ffast-math -mcpu=power7" } */ +/* { dg-final { scan-assembler-times "xsrsqrtedp" 1 } } */ +/* { dg-final { scan-assembler-times "xsmsub.dp" 1 } } */ +/* { dg-final { scan-assembler-times "xsmuldp" 4 } } */ +/* { dg-final { scan-assembler-times "xsnmsub.dp" 2 } } */ +/* { dg-final { scan-assembler-times "frsqrtes" 1 } } */ +/* { dg-final { scan-assembler-times "fmsubs" 1 } } */ +/* { dg-final { scan-assembler-times "fmuls" 4 } } */ +/* { dg-final { scan-assembler-times "fnmsubs" 2 } } */ + +double +rsqrt_d (double a) +{ + return 1.0 / __builtin_sqrt (a); +} + +float +rsqrt_f (float a) +{ + return 1.0f / __builtin_sqrtf (a); +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-4.c b/gcc/testsuite/gcc.target/powerpc/recip-4.c new file mode 100644 index 00000000000..bd496d70e25 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-4.c @@ -0,0 +1,36 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O3 -ftree-vectorize -mrecip -ffast-math -mcpu=power7 -fno-unroll-loops" } */ +/* { dg-final { scan-assembler-times "xvrsqrtedp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmsub.dp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmuldp" 4 } } */ +/* { dg-final { scan-assembler-times "xvnmsub.dp" 2 } } */ +/* { dg-final { scan-assembler-times "xvrsqrtesp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmsub.sp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmulsp" 4 } } */ +/* { dg-final { scan-assembler-times "xvnmsub.sp" 2 } } */ + +#define SIZE 1024 + +extern double a_d[SIZE] __attribute__((__aligned__(32))); +extern double b_d[SIZE] __attribute__((__aligned__(32))); + +void +vectorize_rsqrt_d (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a_d[i] = 1.0 / __builtin_sqrt (b_d[i]); +} + +extern float a_f[SIZE] __attribute__((__aligned__(32))); +extern float b_f[SIZE] __attribute__((__aligned__(32))); + +void +vectorize_rsqrt_f (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + a_f[i] = 1.0f / __builtin_sqrtf (b_f[i]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-5.c b/gcc/testsuite/gcc.target/powerpc/recip-5.c new file mode 100644 index 00000000000..4a9c496201a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-5.c @@ -0,0 +1,94 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O3 -ftree-vectorize -mrecip=all -ffast-math -mcpu=power7 -fno-unroll-loops" } */ +/* { dg-final { scan-assembler-times "xvredp" 4 } } */ +/* { dg-final { scan-assembler-times "xvresp" 5 } } */ +/* { dg-final { scan-assembler-times "xsredp" 2 } } */ +/* { dg-final { scan-assembler-times "fres" 2 } } */ + +#include <altivec.h> + +float f_recip (float a, float b) { return __builtin_recipdivf (a, b); } +double d_recip (double a, double b) { return __builtin_recipdiv (a, b); } + +float f_div (float a, float b) { return a / b; } +double d_div (double a, double b) { return a / b; } + +#define SIZE 1024 + +double d_a[SIZE] __attribute__((__aligned__(32))); +double d_b[SIZE] __attribute__((__aligned__(32))); +double d_c[SIZE] __attribute__((__aligned__(32))); + +float f_a[SIZE] __attribute__((__aligned__(32))); +float f_b[SIZE] __attribute__((__aligned__(32))); +float f_c[SIZE] __attribute__((__aligned__(32))); + +void vec_f_recip (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + f_a[i] = __builtin_recipdivf (f_b[i], f_c[i]); +} + +void vec_d_recip (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + d_a[i] = __builtin_recipdiv (d_b[i], d_c[i]); +} + +void vec_f_div (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + f_a[i] = f_b[i] / f_c[i]; +} + +void vec_f_div2 (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + f_a[i] = f_b[i] / 2.0f; +} + +void vec_f_div53 (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + f_a[i] = f_b[i] / 53.0f; +} + +void vec_d_div (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + d_a[i] = d_b[i] / d_c[i]; +} + +void vec_d_div2 (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + d_a[i] = d_b[i] / 2.0; +} + +void vec_d_div53 (void) +{ + int i; + + for (i = 0; i < SIZE; i++) + d_a[i] = d_b[i] / 53.0; +} + +vector float v4sf_recip1 (vector float a, vector float b) { return vec_recipdiv (a, b); } +vector float v4sf_recip2 (vector float a, vector float b) { return __builtin_altivec_vrecipdivfp (a, b); } +vector double v2df_recip1 (vector double a, vector double b) { return vec_recipdiv (a, b); } +vector float v4sf_recip3 (vector float a, vector float b) { return __builtin_vsx_xvrecipdivsp (a, b); } +vector double v2df_recip2 (vector double a, vector double b) { return __builtin_vsx_xvrecipdivdp (a, b); } diff --git a/gcc/testsuite/gcc.target/powerpc/recip-6.c b/gcc/testsuite/gcc.target/powerpc/recip-6.c new file mode 100644 index 00000000000..7d71df6709d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-6.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-mcpu=power7 -O3 -ftree-vectorize -ffast-math -mrecip=all -mrecip-precision" } */ + +/* Check reciprocal estimate functions for accuracy. */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> +#include <float.h> +#include <string.h> + +#include "recip-test.h" diff --git a/gcc/testsuite/gcc.target/powerpc/recip-7.c b/gcc/testsuite/gcc.target/powerpc/recip-7.c new file mode 100644 index 00000000000..7b32ba076a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-7.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */ +/* { dg-require-effective-target ppc_recip_hw } */ +/* { dg-options "-O3 -ftree-vectorize -ffast-math -mrecip -mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb" } */ + +/* Check reciprocal estimate functions for accuracy. */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> +#include <float.h> +#include <string.h> + +#include "recip-test.h" diff --git a/gcc/testsuite/gcc.target/powerpc/recip-test.h b/gcc/testsuite/gcc.target/powerpc/recip-test.h new file mode 100644 index 00000000000..7a42df5757d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-test.h @@ -0,0 +1,149 @@ +/* Check reciprocal estimate functions for accuracy. */ + +#ifdef _ARCH_PPC64 +typedef unsigned long uns64_t; +#define UNUM64(x) x ## L + +#else +typedef unsigned long long uns64_t; +#define UNUM64(x) x ## LL +#endif + +typedef unsigned int uns32_t; + +#define TNAME2(x) #x +#define TNAME(x) TNAME2(x) + +/* + * Float functions. + */ + +#define TYPE float +#define NAME(PREFIX) PREFIX ## _float +#define UNS_TYPE uns32_t +#define UNS_ABS __builtin_abs +#define EXP_SIZE 8 +#define MAN_SIZE 23 +#define FABS __builtin_fabsf +#define FMAX __builtin_fmaxf +#define FMIN __builtin_fminf +#define SQRT __builtin_sqrtf +#define RMIN 1.0e-10 +#define RMAX 1.0e+10 +#define BDIV 1 +#define BRSQRT 2 +#define ASMDIV "fdivs" +#define ASMSQRT "fsqrts" + +#define INIT_DIV \ +{ \ + { 0x4fffffff }, /* 8589934080 */ \ + { 0x4effffff }, /* 2147483520 */ \ + { 0x40ffffff }, /* 7.99999952316284 */ \ + { 0x3fffffff }, /* 1.99999988079071 */ \ + { 0x417fffff }, /* 15.9999990463257 */ \ + { 0x42ffffff }, /* 127.999992370605 */ \ + { 0x3dffffff }, /* 0.124999992549419 */ \ + { 0x3effffff }, /* 0.499999970197678 */ \ +} + +#define INIT_RSQRT \ +{ \ + { 0x457ffffe }, /* 4096 - small amount */ \ + { 0x4c7fffff }, /* 6.71089e+07 */ \ + { 0x3d7fffff }, /* 0.0625 - small amount */ \ + { 0x307ffffe }, /* 9.31322e-10 */ \ + { 0x4c7ffffe }, /* 6.71089e+07 */ \ + { 0x397ffffe }, /* 0.000244141 */ \ + { 0x2e7fffff }, /* 5.82077e-11 */ \ + { 0x2f7fffff }, /* 2.32831e-10 */ \ +} + + +#include "recip-test2.h" + +/* + * Double functions. + */ + +#undef TYPE +#undef NAME +#undef UNS_TYPE +#undef UNS_ABS +#undef EXP_SIZE +#undef MAN_SIZE +#undef FABS +#undef FMAX +#undef FMIN +#undef SQRT +#undef RMIN +#undef RMAX +#undef BDIV +#undef BRSQRT +#undef ASMDIV +#undef ASMSQRT +#undef INIT_DIV +#undef INIT_RSQRT + +#define TYPE double +#define NAME(PREFIX) PREFIX ## _double +#define UNS_TYPE uns64_t +#define UNS_ABS __builtin_imaxabs +#define EXP_SIZE 11 +#define MAN_SIZE 52 +#define FABS __builtin_fabs +#define FMAX __builtin_fmax +#define FMIN __builtin_fmin +#define SQRT __builtin_sqrt +#define RMIN 1.0e-100 +#define RMAX 1.0e+100 +#define BDIV 1 +#define BRSQRT 2 +#define ASMDIV "fdiv" +#define ASMSQRT "fsqrt" + +#define INIT_DIV \ +{ \ + { UNUM64 (0x2b57be53f2a2f3a0) }, /* 6.78462e-100 */ \ + { UNUM64 (0x2b35f8e8ea553e52) }, /* 1.56963e-100 */ \ + { UNUM64 (0x2b5b9d861d2fe4fb) }, /* 7.89099e-100 */ \ + { UNUM64 (0x2b45dc44a084e682) }, /* 3.12327e-100 */ \ + { UNUM64 (0x2b424ce16945d777) }, /* 2.61463e-100 */ \ + { UNUM64 (0x2b20b5023d496b50) }, /* 5.96749e-101 */ \ + { UNUM64 (0x2b61170547f57caa) }, /* 9.76678e-100 */ \ + { UNUM64 (0x2b543b9d498aac37) }, /* 5.78148e-100 */ \ +} + +#define INIT_RSQRT \ +{ \ + { UNUM64 (0x2b616f2d8cbbc646) }, /* 9.96359e-100 */ \ + { UNUM64 (0x2b5c4db2da0a011d) }, /* 8.08764e-100 */ \ + { UNUM64 (0x2b55a82d5735b262) }, /* 6.1884e-100 */ \ + { UNUM64 (0x2b50b52908258cb8) }, /* 4.77416e-100 */ \ + { UNUM64 (0x2b363989a4fb29af) }, /* 1.58766e-100 */ \ + { UNUM64 (0x2b508b9f6f4180a9) }, /* 4.7278e-100 */ \ + { UNUM64 (0x2b4f7a1d48accb40) }, /* 4.49723e-100 */ \ + { UNUM64 (0x2b1146a37372a81f) }, /* 3.08534e-101 */ \ + { UNUM64 (0x2b33f876a8c48050) }, /* 1.42663e-100 */ \ +} + +#include "recip-test2.h" + +int +main (int argc __attribute__((__unused__)), + char *argv[] __attribute__((__unused__))) +{ + srand48 (1); + run_float (); + +#ifdef VERBOSE + printf ("\n"); +#endif + + run_double (); + + if (error_count_float != 0 || error_count_double != 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-test2.h b/gcc/testsuite/gcc.target/powerpc/recip-test2.h new file mode 100644 index 00000000000..3ec356cdfd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/recip-test2.h @@ -0,0 +1,432 @@ +/* + * Included file to common source float/double checking + * The following macros should be defined: + * TYPE -- floating point type + * NAME -- convert a name to include the type + * UNS_TYPE -- type to hold TYPE as an unsigned number + * EXP_SIZE -- size in bits of the exponent + * MAN_SIZE -- size in bits of the mantissa + * UNS_ABS -- absolute value for UNS_TYPE + * FABS -- absolute value function for TYPE + * FMAX -- maximum function for TYPE + * FMIN -- minimum function for TYPE + * SQRT -- square root function for TYPE + * RMIN -- minimum random number to generate + * RMAX -- maximum random number to generate + * ASMDIV -- assembler instruction to do divide + * ASMSQRT -- assembler instruction to do square root + * BDIV -- # of bits of inaccuracy to allow for division + * BRSQRT -- # of bits of inaccuracy to allow for 1/sqrt + * INIT_DIV -- Initial values to test 1/x against + * INIT_RSQRT -- Initial values to test 1/sqrt(x) against + */ + +typedef union +{ + UNS_TYPE i; + TYPE x; +} NAME (union); + +/* + * Input/output arrays. + */ + +static NAME (union) NAME (div_input) [] __attribute__((__aligned__(32))) = INIT_DIV; +static NAME (union) NAME (rsqrt_input)[] __attribute__((__aligned__(32))) = INIT_RSQRT; + +#define DIV_SIZE (sizeof (NAME (div_input)) / sizeof (TYPE)) +#define RSQRT_SIZE (sizeof (NAME (rsqrt_input)) / sizeof (TYPE)) + +static TYPE NAME (div_expected)[DIV_SIZE] __attribute__((__aligned__(32))); +static TYPE NAME (div_output) [DIV_SIZE] __attribute__((__aligned__(32))); + +static TYPE NAME (rsqrt_expected)[RSQRT_SIZE] __attribute__((__aligned__(32))); +static TYPE NAME (rsqrt_output) [RSQRT_SIZE] __attribute__((__aligned__(32))); + + +/* + * Crack a floating point number into sign bit, exponent, and mantissa. + */ + +static void +NAME (crack) (TYPE number, unsigned int *p_sign, unsigned *p_exponent, UNS_TYPE *p_mantissa) +{ + NAME (union) u; + UNS_TYPE bits; + + u.x = number; + bits = u.i; + + *p_sign = (unsigned int)((bits >> (EXP_SIZE + MAN_SIZE)) & 0x1); + *p_exponent = (unsigned int)((bits >> MAN_SIZE) & ((((UNS_TYPE)1) << EXP_SIZE) - 1)); + *p_mantissa = bits & ((((UNS_TYPE)1) << MAN_SIZE) - 1); + return; +} + + +/* + * Prevent optimizer from eliminating + 0.0 to remove -0.0. + */ + +volatile TYPE NAME (math_diff_0) = ((TYPE) 0.0); + +/* + * Return negative if two numbers are significanly different or return the + * number of bits that are different in the mantissa. + */ + +static int +NAME (math_diff) (TYPE a, TYPE b, int bits) +{ + TYPE zero = NAME (math_diff_0); + unsigned int sign_a, sign_b; + unsigned int exponent_a, exponent_b; + UNS_TYPE mantissa_a, mantissa_b, diff; + int i; + + /* eliminate signed zero. */ + a += zero; + b += zero; + + /* special case Nan. */ + if (__builtin_isnan (a)) + return (__builtin_isnan (b) ? 0 : -1); + + if (a == b) + return 0; + + /* special case infinity. */ + if (__builtin_isinf (a)) + return (__builtin_isinf (b) ? 0 : -1); + + /* punt on denormal numbers. */ + if (!__builtin_isnormal (a) || !__builtin_isnormal (b)) + return -1; + + NAME (crack) (a, &sign_a, &exponent_a, &mantissa_a); + NAME (crack) (b, &sign_b, &exponent_b, &mantissa_b); + + /* If the sign is different, there is no hope. */ + if (sign_a != sign_b) + return -1; + + /* If the exponent is off by 1, see if the values straddle the power of two, + and adjust things to do the mantassa check if we can. */ + if ((exponent_a == (exponent_b+1)) || (exponent_a == (exponent_b-1))) + { + TYPE big = FMAX (a, b); + TYPE small = FMIN (a, b); + TYPE diff = FABS (a - b); + unsigned int sign_big, sign_small, sign_test; + unsigned int exponent_big, exponent_small, exponent_test; + UNS_TYPE mantissa_big, mantissa_small, mantissa_test; + + NAME (crack) (big, &sign_big, &exponent_big, &mantissa_big); + NAME (crack) (small, &sign_small, &exponent_small, &mantissa_small); + + NAME (crack) (small - diff, &sign_test, &exponent_test, &mantissa_test); + if ((sign_test == sign_small) && (exponent_test == exponent_small)) + { + mantissa_a = mantissa_small; + mantissa_b = mantissa_test; + } + + else + { + NAME (crack) (big + diff, &sign_test, &exponent_test, &mantissa_test); + if ((sign_test == sign_big) && (exponent_test == exponent_big)) + { + mantissa_a = mantissa_big; + mantissa_b = mantissa_test; + } + + else + return -1; + } + } + + else if (exponent_a != exponent_b) + return -1; + + diff = UNS_ABS (mantissa_a - mantissa_b); + for (i = MAN_SIZE; i > 0; i--) + { + if ((diff & ((UNS_TYPE)1) << (i-1)) != 0) + return i; + } + + return -1; +} + + +/* + * Turn off inlining to make code inspection easier. + */ + +static void NAME (asm_div) (void) __attribute__((__noinline__)); +static void NAME (vector_div) (void) __attribute__((__noinline__)); +static void NAME (scalar_div) (void) __attribute__((__noinline__)); +static void NAME (asm_rsqrt) (void) __attribute__((__noinline__)); +static void NAME (vector_rsqrt) (void) __attribute__((__noinline__)); +static void NAME (scalar_rsqrt) (void) __attribute__((__noinline__)); +static void NAME (check_div) (const char *) __attribute__((__noinline__)); +static void NAME (check_rsqrt) (const char *) __attribute__((__noinline__)); +static void NAME (run) (void) __attribute__((__noinline__)); + + +/* + * Division function that might be vectorized. + */ + +static void +NAME (vector_div) (void) +{ + size_t i; + + for (i = 0; i < DIV_SIZE; i++) + NAME (div_output)[i] = ((TYPE) 1.0) / NAME (div_input)[i].x; +} + +/* + * Division function that is not vectorized. + */ + +static void +NAME (scalar_div) (void) +{ + size_t i; + + for (i = 0; i < DIV_SIZE; i++) + { + TYPE x = ((TYPE) 1.0) / NAME (div_input)[i].x; + TYPE y; + __asm__ ("" : "=d" (y) : "0" (x)); + NAME (div_output)[i] = y; + } +} + +/* + * Generate the division instruction via asm. + */ + +static void +NAME (asm_div) (void) +{ + size_t i; + + for (i = 0; i < DIV_SIZE; i++) + { + TYPE x; + __asm__ (ASMDIV " %0,%1,%2" + : "=d" (x) + : "d" ((TYPE) 1.0), "d" (NAME (div_input)[i].x)); + NAME (div_expected)[i] = x; + } +} + +/* + * Reciprocal square root function that might be vectorized. + */ + +static void +NAME (vector_rsqrt) (void) +{ + size_t i; + + for (i = 0; i < RSQRT_SIZE; i++) + NAME (rsqrt_output)[i] = ((TYPE) 1.0) / SQRT (NAME (rsqrt_input)[i].x); +} + +/* + * Reciprocal square root function that is not vectorized. + */ + +static void +NAME (scalar_rsqrt) (void) +{ + size_t i; + + for (i = 0; i < RSQRT_SIZE; i++) + { + TYPE x = ((TYPE) 1.0) / SQRT (NAME (rsqrt_input)[i].x); + TYPE y; + __asm__ ("" : "=d" (y) : "0" (x)); + NAME (rsqrt_output)[i] = y; + } +} + +/* + * Generate the 1/sqrt instructions via asm. + */ + +static void +NAME (asm_rsqrt) (void) +{ + size_t i; + + for (i = 0; i < RSQRT_SIZE; i++) + { + TYPE x; + TYPE y; + __asm__ (ASMSQRT " %0,%1" : "=d" (x) : "d" (NAME (rsqrt_input)[i].x)); + __asm__ (ASMDIV " %0,%1,%2" : "=d" (y) : "d" ((TYPE) 1.0), "d" (x)); + NAME (rsqrt_expected)[i] = y; + } +} + + +/* + * Functions to abort or report errors. + */ + +static int NAME (error_count) = 0; + +#ifdef VERBOSE +static int NAME (max_bits_div) = 0; +static int NAME (max_bits_rsqrt) = 0; +#endif + + +/* + * Compare the expected value with the value we got. + */ + +static void +NAME (check_div) (const char *test) +{ + size_t i; + int b; + + for (i = 0; i < DIV_SIZE; i++) + { + TYPE exp = NAME (div_expected)[i]; + TYPE out = NAME (div_output)[i]; + b = NAME (math_diff) (exp, out, BDIV); + +#ifdef VERBOSE + if (b != 0) + { + NAME (union) u_in = NAME (div_input)[i]; + NAME (union) u_exp; + NAME (union) u_out; + char explanation[64]; + const char *p_exp; + + if (b < 0) + p_exp = "failed"; + else + { + p_exp = explanation; + sprintf (explanation, "%d bit error%s", b, (b > BDIV) ? ", failed" : ""); + } + + u_exp.x = exp; + u_out.x = out; + printf ("%s %s %s for 1.0 / %g [0x%llx], expected %g [0x%llx], got %g [0x%llx]\n", + TNAME (TYPE), test, p_exp, + (double) u_in.x, (unsigned long long) u_in.i, + (double) exp, (unsigned long long) u_exp.i, + (double) out, (unsigned long long) u_out.i); + } +#endif + + if (b < 0 || b > BDIV) + NAME (error_count)++; + +#ifdef VERBOSE + if (b > NAME (max_bits_div)) + NAME (max_bits_div) = b; +#endif + } +} + +static void +NAME (check_rsqrt) (const char *test) +{ + size_t i; + int b; + + for (i = 0; i < RSQRT_SIZE; i++) + { + TYPE exp = NAME (rsqrt_expected)[i]; + TYPE out = NAME (rsqrt_output)[i]; + b = NAME (math_diff) (exp, out, BRSQRT); + +#ifdef VERBOSE + if (b != 0) + { + NAME (union) u_in = NAME (rsqrt_input)[i]; + NAME (union) u_exp; + NAME (union) u_out; + char explanation[64]; + const char *p_exp; + + if (b < 0) + p_exp = "failed"; + else + { + p_exp = explanation; + sprintf (explanation, "%d bit error%s", b, (b > BDIV) ? ", failed" : ""); + } + + u_exp.x = exp; + u_out.x = out; + printf ("%s %s %s for 1 / sqrt (%g) [0x%llx], expected %g [0x%llx], got %g [0x%llx]\n", + TNAME (TYPE), test, p_exp, + (double) u_in.x, (unsigned long long) u_in.i, + (double) exp, (unsigned long long) u_exp.i, + (double) out, (unsigned long long) u_out.i); + } +#endif + + if (b < 0 || b > BRSQRT) + NAME (error_count)++; + +#ifdef VERBOSE + if (b > NAME (max_bits_rsqrt)) + NAME (max_bits_rsqrt) = b; +#endif + } +} + + +/* + * Now do everything. + */ + +static void +NAME (run) (void) +{ +#ifdef VERBOSE + printf ("start run_%s, divide size = %ld, rsqrt size = %ld, %d bit%s for a/b, %d bit%s for 1/sqrt(a)\n", + TNAME (TYPE), + (long)DIV_SIZE, + (long)RSQRT_SIZE, + BDIV, (BDIV == 1) ? "" : "s", + BRSQRT, (BRSQRT == 1) ? "" : "s"); +#endif + + NAME (asm_div) (); + + NAME (scalar_div) (); + NAME (check_div) ("scalar"); + + NAME (vector_div) (); + NAME (check_div) ("vector"); + + NAME (asm_rsqrt) (); + + NAME (scalar_rsqrt) (); + NAME (check_rsqrt) ("scalar"); + + NAME (vector_rsqrt) (); + NAME (check_rsqrt) ("vector"); + +#ifdef VERBOSE + printf ("end run_%s, errors = %d, max div bits = %d, max rsqrt bits = %d\n", + TNAME (TYPE), + NAME (error_count), + NAME (max_bits_div), + NAME (max_bits_rsqrt)); +#endif +} diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-1.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-1.c new file mode 100644 index 00000000000..35f8b53cac1 --- /dev/null +++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=sysv" } */ + +__attribute__ ((ms_abi)) +int foo (void) +{ + return 0; +} + +/* { dg-final { scan-assembler-not "%rsp" } } */ + diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c new file mode 100644 index 00000000000..2a54bc89cfc --- /dev/null +++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=sysv" } */ + +extern int glb1, gbl2, gbl3; + +__attribute__ ((ms_abi)) +int foo (void) +{ + int r = 1; + int i, j, k; + for (i = 0; i < glb1; i++) + { + r *= (i + 1); + for (j = gbl2; j > 0; --j) + { + for (k = 0; k < gbl3; k++) + r += (i + k * j); + } + } + + return r; +} + +/* { dg-final { scan-assembler-not "%rsp" } } */ + |