From: H.J. Lu Date: Wed, 30 Jul 2008 19:24:02 +0000 (+0000) Subject: func-vararg-alternate-d128-2.c: New. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b2488ca6ece182f2136a20ee5fa0bb92f935b0f;p=platform%2Fupstream%2Fgcc.git func-vararg-alternate-d128-2.c: New. 2008-07-30 H.J. Lu Joey Ye * gcc.dg/dfp/func-vararg-alternate-d128-2.c: New. * gcc.dg/dfp/func-vararg-mixed-2.c: Likewise. * gcc.dg/torture/stackalign/alloca-1.c: Likewise. * gcc.dg/torture/stackalign/builtin-apply-1.c: Likewise. * gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise. * gcc.dg/torture/stackalign/builtin-apply-3.c: Likewise. * gcc.dg/torture/stackalign/builtin-apply-4.c: Likewise. * gcc.dg/torture/stackalign/builtin-return-1.c: Likewise. * gcc.dg/torture/stackalign/check.h: Likewise. * gcc.dg/torture/stackalign/comp-goto-1.c: Likewise. * gcc.dg/torture/stackalign/fastcall-1.c: Likewise. * gcc.dg/torture/stackalign/global-1.c: Likewise. * gcc.dg/torture/stackalign/inline-1.c: Likewise. * gcc.dg/torture/stackalign/inline-2.c: Likewise. * gcc.dg/torture/stackalign/nested-1.c: Likewise. * gcc.dg/torture/stackalign/nested-2.c: Likewise. * gcc.dg/torture/stackalign/nested-3.c: Likewise. * gcc.dg/torture/stackalign/nested-4.c: Likewise. * gcc.dg/torture/stackalign/nested-5.c: Likewise. * gcc.dg/torture/stackalign/nested-6.c: Likewise. * gcc.dg/torture/stackalign/non-local-goto-1.c: Likewise. * gcc.dg/torture/stackalign/non-local-goto-2.c: Likewise. * gcc.dg/torture/stackalign/non-local-goto-3.c: Likewise. * gcc.dg/torture/stackalign/non-local-goto-4.c: Likewise. * gcc.dg/torture/stackalign/non-local-goto-5.c: Likewise. * gcc.dg/torture/stackalign/pr16660-1.c: Likewise. * gcc.dg/torture/stackalign/pr16660-2.c: Likewise. * gcc.dg/torture/stackalign/pr16660-3.c: Likewise. * gcc.dg/torture/stackalign/regparm-1.c: Likewise. * gcc.dg/torture/stackalign/ret-struct-1.c: Likewise. * gcc.dg/torture/stackalign/setjmp-1.c: Likewise. * gcc.dg/torture/stackalign/setjmp-2.c: Likewise. * gcc.dg/torture/stackalign/setjmp-3.c: Likewise. * gcc.dg/torture/stackalign/setjmp-4.c: Likewise. * gcc.dg/torture/stackalign/sibcall-1.c: Likewise. * gcc.dg/torture/stackalign/stackalign.exp: Likewise. * gcc.dg/torture/stackalign/struct-1.c: Likewise. * gcc.dg/torture/stackalign/vararg-1.c: Likewise. * gcc.dg/torture/stackalign/vararg-2.c: Likewise. * gcc.target/i386/align-main-1.c: Likewise. * gcc.target/i386/align-main-2.c: Likewise. * gcc.target/i386/pr32000-2.c: Likewise. * gcc.target/i386/stackalign/asm-1.c: Likewise. * gcc.target/i386/stackalign/return-1.c: Likewise. * gcc.target/i386/stackalign/return-2.c: Likewise. * gcc.target/i386/stackalign/return-3.c: Likewise. * gcc.target/i386/stackalign/return-4.c: Likewise. * gcc.target/i386/stackalign/return-5.c: Likewise. * gcc.target/i386/stackalign/return-6.c: Likewise. * gcc.target/i386/stackalign/stackalign.exp: Likewise. * g++.dg/torture/stackalign/check.h: Likewise. * g++.dg/torture/stackalign/eh-alloca-1.C: Likewise. * g++.dg/torture/stackalign/eh-fastcall-1.C: Likewise. * g++.dg/torture/stackalign/eh-global-1.C: Likewise. * g++.dg/torture/stackalign/eh-inline-1.C: Likewise. * g++.dg/torture/stackalign/eh-inline-2.C: Likewise. * g++.dg/torture/stackalign/eh-vararg-1.C: Likewise. * g++.dg/torture/stackalign/eh-vararg-2.C: Likewise. * g++.dg/torture/stackalign/stackalign.exp: Likewise. * g++.dg/torture/stackalign/stdcall-1.C: Likewise. * g++.dg/torture/stackalign/test-unwind.h: Likewise. * g++.dg/torture/stackalign/throw-1.C: Likewise. * g++.dg/torture/stackalign/throw-2.C: Likewise. * g++.dg/torture/stackalign/throw-3.C: Likewise. * g++.dg/torture/stackalign/throw-4.C: Likewise. * g++.dg/torture/stackalign/unwind-0.C: Likewise. * g++.dg/torture/stackalign/unwind-1.C: Likewise. * g++.dg/torture/stackalign/unwind-2.C: Likewise. * g++.dg/torture/stackalign/unwind-3.C: Likewise. * g++.dg/torture/stackalign/unwind-4.C: Likewise. * g++.dg/torture/stackalign/unwind-5.C: Likewise. * g++.dg/torture/stackalign/unwind-6.C: Likewise. * gcc.target/i386/20060512-1.c: Add -mpreferred-stack-boundary=4. (main): Move "popl" after check. * gcc.target/i386/20060512-3.c: Likewise. * gcc.target/i386/20060512-2.c: Add -mpreferred-stack-boundary=4. Remove dg-error. * gcc.target/i386/20060512-4.c: Add -mpreferred-stack-boundary=4. Remove dg-warning. * lib/target-supports.exp (check_effective_target_unaligned_stack): Always return 0. (check_effective_target_automatic_stack_alignment): New. Co-Authored-By: Joey Ye From-SVN: r138336 --- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cdfa294..ab4b945 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,93 @@ +2008-07-30 H.J. Lu + Joey Ye + + * gcc.dg/dfp/func-vararg-alternate-d128-2.c: New. + * gcc.dg/dfp/func-vararg-mixed-2.c: Likewise. + * gcc.dg/torture/stackalign/alloca-1.c: Likewise. + * gcc.dg/torture/stackalign/builtin-apply-1.c: Likewise. + * gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise. + * gcc.dg/torture/stackalign/builtin-apply-3.c: Likewise. + * gcc.dg/torture/stackalign/builtin-apply-4.c: Likewise. + * gcc.dg/torture/stackalign/builtin-return-1.c: Likewise. + * gcc.dg/torture/stackalign/check.h: Likewise. + * gcc.dg/torture/stackalign/comp-goto-1.c: Likewise. + * gcc.dg/torture/stackalign/fastcall-1.c: Likewise. + * gcc.dg/torture/stackalign/global-1.c: Likewise. + * gcc.dg/torture/stackalign/inline-1.c: Likewise. + * gcc.dg/torture/stackalign/inline-2.c: Likewise. + * gcc.dg/torture/stackalign/nested-1.c: Likewise. + * gcc.dg/torture/stackalign/nested-2.c: Likewise. + * gcc.dg/torture/stackalign/nested-3.c: Likewise. + * gcc.dg/torture/stackalign/nested-4.c: Likewise. + * gcc.dg/torture/stackalign/nested-5.c: Likewise. + * gcc.dg/torture/stackalign/nested-6.c: Likewise. + * gcc.dg/torture/stackalign/non-local-goto-1.c: Likewise. + * gcc.dg/torture/stackalign/non-local-goto-2.c: Likewise. + * gcc.dg/torture/stackalign/non-local-goto-3.c: Likewise. + * gcc.dg/torture/stackalign/non-local-goto-4.c: Likewise. + * gcc.dg/torture/stackalign/non-local-goto-5.c: Likewise. + * gcc.dg/torture/stackalign/pr16660-1.c: Likewise. + * gcc.dg/torture/stackalign/pr16660-2.c: Likewise. + * gcc.dg/torture/stackalign/pr16660-3.c: Likewise. + * gcc.dg/torture/stackalign/regparm-1.c: Likewise. + * gcc.dg/torture/stackalign/ret-struct-1.c: Likewise. + * gcc.dg/torture/stackalign/setjmp-1.c: Likewise. + * gcc.dg/torture/stackalign/setjmp-2.c: Likewise. + * gcc.dg/torture/stackalign/setjmp-3.c: Likewise. + * gcc.dg/torture/stackalign/setjmp-4.c: Likewise. + * gcc.dg/torture/stackalign/sibcall-1.c: Likewise. + * gcc.dg/torture/stackalign/stackalign.exp: Likewise. + * gcc.dg/torture/stackalign/struct-1.c: Likewise. + * gcc.dg/torture/stackalign/vararg-1.c: Likewise. + * gcc.dg/torture/stackalign/vararg-2.c: Likewise. + * gcc.target/i386/align-main-1.c: Likewise. + * gcc.target/i386/align-main-2.c: Likewise. + * gcc.target/i386/pr32000-2.c: Likewise. + * gcc.target/i386/stackalign/asm-1.c: Likewise. + * gcc.target/i386/stackalign/return-1.c: Likewise. + * gcc.target/i386/stackalign/return-2.c: Likewise. + * gcc.target/i386/stackalign/return-3.c: Likewise. + * gcc.target/i386/stackalign/return-4.c: Likewise. + * gcc.target/i386/stackalign/return-5.c: Likewise. + * gcc.target/i386/stackalign/return-6.c: Likewise. + * gcc.target/i386/stackalign/stackalign.exp: Likewise. + * g++.dg/torture/stackalign/check.h: Likewise. + * g++.dg/torture/stackalign/eh-alloca-1.C: Likewise. + * g++.dg/torture/stackalign/eh-fastcall-1.C: Likewise. + * g++.dg/torture/stackalign/eh-global-1.C: Likewise. + * g++.dg/torture/stackalign/eh-inline-1.C: Likewise. + * g++.dg/torture/stackalign/eh-inline-2.C: Likewise. + * g++.dg/torture/stackalign/eh-vararg-1.C: Likewise. + * g++.dg/torture/stackalign/eh-vararg-2.C: Likewise. + * g++.dg/torture/stackalign/stackalign.exp: Likewise. + * g++.dg/torture/stackalign/stdcall-1.C: Likewise. + * g++.dg/torture/stackalign/test-unwind.h: Likewise. + * g++.dg/torture/stackalign/throw-1.C: Likewise. + * g++.dg/torture/stackalign/throw-2.C: Likewise. + * g++.dg/torture/stackalign/throw-3.C: Likewise. + * g++.dg/torture/stackalign/throw-4.C: Likewise. + * g++.dg/torture/stackalign/unwind-0.C: Likewise. + * g++.dg/torture/stackalign/unwind-1.C: Likewise. + * g++.dg/torture/stackalign/unwind-2.C: Likewise. + * g++.dg/torture/stackalign/unwind-3.C: Likewise. + * g++.dg/torture/stackalign/unwind-4.C: Likewise. + * g++.dg/torture/stackalign/unwind-5.C: Likewise. + * g++.dg/torture/stackalign/unwind-6.C: Likewise. + + * gcc.target/i386/20060512-1.c: Add -mpreferred-stack-boundary=4. + (main): Move "popl" after check. + * gcc.target/i386/20060512-3.c: Likewise. + + * gcc.target/i386/20060512-2.c: Add -mpreferred-stack-boundary=4. + Remove dg-error. + + * gcc.target/i386/20060512-4.c: Add -mpreferred-stack-boundary=4. + Remove dg-warning. + + * lib/target-supports.exp (check_effective_target_unaligned_stack): + Always return 0. + (check_effective_target_automatic_stack_alignment): New. + 2008-07-30 Richard Guenther PR tree-optimization/36967 diff --git a/gcc/testsuite/g++.dg/torture/stackalign/check.h b/gcc/testsuite/g++.dg/torture/stackalign/check.h new file mode 100644 index 0000000..af19885 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/check.h @@ -0,0 +1,36 @@ +#include +#ifdef DEBUG +#include +#endif + +#ifdef __cplusplus +extern "C" void abort (void); +#else +extern void abort (void); +#endif + +int +check_int (int *i, int align) +{ + *i = 20; + if ((((ptrdiff_t) i) & (align - 1)) != 0) + { +#ifdef DEBUG + printf ("\nUnalign address (%d): %p!\n", align, i); +#endif + abort (); + } + return *i; +} + +void +check (void *p, int align) +{ + if ((((ptrdiff_t) p) & (align - 1)) != 0) + { +#ifdef DEBUG + printf ("\nUnalign address (%d): %p!\n", align, p); +#endif + abort (); + } +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C new file mode 100644 index 0000000..a20f074 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C @@ -0,0 +1,56 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +void +foo (int size) throw (B,A) +{ + char *p = (char*) __builtin_alloca (size + 1); + aligned i; + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + throw A(); +} + +int +main() +{ + try { foo (5); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C new file mode 100644 index 0000000..4b849a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C @@ -0,0 +1,43 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +__attribute__ ((fastcall)) +void +foo (int j, int k, int m, int n, int o) throw (B,A) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5) + abort (); + + throw A(); +} + +int +main() +{ + try { foo (1, 2, 3, 4, 5); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C new file mode 100644 index 0000000..2692f94 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +void +foo (void) throw (B,A) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + throw A(); +} + +int +main() +{ + try { foo (); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C new file mode 100644 index 0000000..72ac7fd --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +static void +inline __attribute__((always_inline)) +foo (void) throw (B,A) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + throw A(); +} + +int +main() +{ + try { foo (); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C new file mode 100644 index 0000000..4feb3f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C @@ -0,0 +1,57 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +static void +inline __attribute__((always_inline)) +foo (int size) throw (B,A) +{ + char *p = (char *) __builtin_alloca (size + 1); + aligned i; + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + throw A(); +} + +int +main() +{ + try { foo (5); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C new file mode 100644 index 0000000..74b48fa --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C @@ -0,0 +1,72 @@ +/* { dg-do run } */ + +#include +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +void +foo (const char *fmt, ...) throw (B,A) +{ + va_list arg; + char *p; + aligned i; + int size; + double x; + + va_start (arg, fmt); + size = va_arg (arg, int); + if (size != 5) + abort (); + p = (char *) __builtin_alloca (size + 1); + + x = va_arg (arg, double); + if (x != 5.0) + abort (); + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + throw A(); + + va_end (arg); +} + +int +main() +{ + try { foo ("foo", 5, 5.0); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C new file mode 100644 index 0000000..719c839 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C @@ -0,0 +1,77 @@ +/* { dg-do run } */ + +#include +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +class Base {}; + +struct A : virtual public Base +{ + A() {} +}; + +struct B {}; + +void +test (va_list arg) throw (B,A) +{ + char *p; + aligned i; + int size; + double x; + + size = va_arg (arg, int); + if (size != 5) + abort (); + + p = (char *) __builtin_alloca (size + 1); + + x = va_arg (arg, double); + if (x != 5.0) + abort (); + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + throw A(); +} + +void +foo (const char *fmt, ...) +{ + va_list arg; + va_start (arg, fmt); + test (arg); + va_end (arg); +} +int +main() +{ + try { foo ("foo", 5, 5.0); } + catch (A& a) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp new file mode 100644 index 0000000..bfa413e --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp @@ -0,0 +1,39 @@ +# Copyright (C) 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This harness is for tests that should be run at all optimisation levels. + +load_lib g++-dg.exp + +# Only run on targets which support automatic stack alignment. +if { ![check_effective_target_automatic_stack_alignment] } then { + return +} + +set additional_flags "" +if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then { + lappend additional_flags "-mstackrealign" + lappend additional_flags "-mpreferred-stack-boundary=5" +} + +dg-init +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags +if { [check_effective_target_fpic] } then { + lappend additional_flags "-fpic" + gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags +} +dg-finish diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C new file mode 100644 index 0000000..393b37e --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C @@ -0,0 +1,17 @@ +// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + +// This case is to detect an assertion failure in stack branch development. + +bool f(); +struct S { + __attribute__ ((stdcall)) ~S(); +}; +void g() { + for (;;) { + S s1, s2, s3; + if (f()) + continue; + if (f()) + return; + } +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h new file mode 100644 index 0000000..e6493ff --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h @@ -0,0 +1,132 @@ +#include "check.h" + +#ifdef __cplusplus +extern "C" void abort (void); +#else +extern void abort (void); +#endif + +extern void foo(void); + +#define INIT_EDI 1 +#define INIT_ESI 2 +#define INIT_EBX 3 + +/* Set DI/SI/BX to wrong value + Use following template so that RA will save/restore callee + save registers in prologue/epilogue */ +#define ALTER_REGS() \ + { \ + int dummy; \ + __asm__ __volatile__ (\ + "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\ + );\ + __asm__ __volatile__ (\ + "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\ + );\ + __asm__ __volatile__ (\ + "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\ + );\ + } + +#ifdef __PIC__ +int +main () +{ + return 0; +} +#else +void __attribute__ ((noinline)) +copy (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +int g_edi=INIT_EDI, g_esi=INIT_ESI, g_ebx=INIT_EBX; +int g_ebp, g_ebp_save, g_esp, g_esp_save; +int n_error; + +int +main() +{ + int dummy; + // Init registers to correct value. + // Use following template so that RA will save/restore callee + // save registers in prologue/epilogue + __asm__ __volatile__ ( + "movl %1, %0" + : "=D" (dummy) + : "i" (INIT_EDI) + ); + __asm__ __volatile__ ( + "movl %1, %0" + : "=S" (dummy) + : "i" (INIT_ESI) + ); + __asm__ __volatile__ ( + "movl %1, %0" + : "=b" (dummy) + : "i" (INIT_EBX) + ); + __asm__ __volatile__ ( + "movl %ebp, g_ebp_save\n\t" + "movl %esp, g_esp_save\n\t" + ); + try { + foo(); + } + catch (...) + { + } + + // Get DI/SI/BX register value after exception caught + __asm__ __volatile__ ( + "movl %edi, g_edi\n\t" + "movl %esi, g_esi\n\t" + "movl %ebx, g_ebx\n\t" + "movl %ebp, g_ebp\n\t" + "movl %esp, g_esp\n\t" + ); + + // Check if DI/SI/BX register value are the same as before calling + // foo. + if (g_edi != INIT_EDI) + { + n_error++; +#ifdef DEBUG + printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI); +#endif + } + if (g_esi != INIT_ESI) + { + n_error++; +#ifdef DEBUG + printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI); +#endif + } + if (g_ebx != INIT_EBX) + { + n_error++; +#ifdef DEBUG + printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX); +#endif + } + if (g_ebp != g_ebp_save) + { + n_error++; +#ifdef DEBUG + printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save); +#endif + } + if (g_esp != g_esp_save) + { + n_error++; +#ifdef DEBUG + printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save); +#endif + } + if (n_error !=0) + abort(); + return 0; +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C new file mode 100644 index 0000000..b1d2e27 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C @@ -0,0 +1,61 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int t_align __attribute__((aligned(ALIGNMENT))); + + +int global, global2; +void bar() +{ + volatile t_align a = 1; + int i,j,k,l,m,n; + i=j=k=0; + for (i=0; i < global; i++) + for (j=0; j < i; j++) + for (k=0; k < j; k++) + for (l=0; l < k; l++) + for (m=0; m < l; m++) + for (n=0; n < m; n++) + global2 = k; + if (check_int ((int *) &a, __alignof__(a)) != a) + abort (); + throw 0; +} + +void foo() +{ + bar(); +} + +int main() +{ + int ll = 1; + int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5; + try { + for (; i < global; i++) + for (; j < i; j++) + for (; k < j; k++) + for (; l < k; l++) + for (; m < l; m++) + for (; n < m; n++) + global2 = k; + foo(); + } + catch (...) + { + } + ll = i+j+k+l+m+n; + if (ll != 15) + { +#ifdef DEBUG + printf("FAIL: sum %d != 15\n", ll); +#endif + abort(); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C new file mode 100644 index 0000000..5f3f1dc --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int t_align __attribute__((aligned(ALIGNMENT))); + + +int global, global2; +void bar() +{ + volatile t_align a = 1; + int i,j,k; + i=j=k=0; + for (i=0; i < global; i++) + for (j=0; j < i; j++) + global2 = k; + if (check_int ((int *) &a, __alignof__(a)) != a) + abort (); + throw 0; +} + +int main() +{ + int ll = 1; + int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5; + try { + for (; i < global; i++) + for (; j < i; j++) + for (; k < j; k++) + for (; l < k; l++) + for (; m < l; m++) + for (; n < m; n++) + global2 = k; + bar (); + } + catch (...) + { + } + ll = i+j+k+l+m+n; + if (ll != 15) + { +#ifdef DEBUG + printf("FAIL: sum %d != 15\n", ll); +#endif + abort(); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C new file mode 100644 index 0000000..d3e53b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int t_align __attribute__((aligned(ALIGNMENT))); + + +int global, global2; +void bar() +{ + volatile t_align a = 1; + int i,j,k; + i=j=k=0; + for (i=0; i < global; i++) + for (j=0; j < i; j++) + global2 = k; + throw 0; + if (check_int ((int *) &a, __alignof__(a)) != a) + abort (); +} + +int main() +{ + int ll = 1; + int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5; + try { + for (; i < global; i++) + for (; j < i; j++) + for (; k < j; k++) + for (; l < k; l++) + for (; m < l; m++) + for (; n < m; n++) + global2 = k; + bar (); + } + catch (...) + { + } + ll = i+j+k+l+m+n; + if (ll != 15) + { +#ifdef DEBUG + printf("FAIL: sum %d != 15\n", ll); +#endif + abort(); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C new file mode 100644 index 0000000..a9c15bd --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C @@ -0,0 +1,54 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int t_align __attribute__((aligned(ALIGNMENT))); + + +int global, global2; +void bar() +{ + volatile t_align a = 1; + int i,j,k; + i=j=k=0; + for (i=0; i < global; i++) + for (j=0; j < i; j++) + { + global2 = k; + throw 0; + } + if (check_int ((int *) &a, __alignof__(a)) != a) + abort (); +} + +int main() +{ + int ll = 1; + int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5; + try { + for (; i < global; i++) + for (; j < i; j++) + for (; k < j; k++) + for (; l < k; l++) + for (; m < l; m++) + for (; n < m; n++) + global2 = k; + bar (); + } + catch (...) + { + } + ll = i+j+k+l+m+n; + if (ll != 15) + { +#ifdef DEBUG + printf("FAIL: sum %d != 15\n", ll); +#endif + abort(); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C new file mode 100644 index 0000000..546123b --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C @@ -0,0 +1,12 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +void __attribute__ ((noinline)) foo() +{ + ALTER_REGS(); + // Throw the except and expect returning to main + throw 1; +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C new file mode 100644 index 0000000..3b80964 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C @@ -0,0 +1,16 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +/* Test situation 1: Stack really realign without DRAP */ +void __attribute__ ((noinline)) +foo () +{ + int __attribute__ ((aligned(64))) a=1; + if (check_int (&a, __alignof__(a)) != a) + abort (); + ALTER_REGS(); + throw a; +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C new file mode 100644 index 0000000..1569ed8 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C @@ -0,0 +1,29 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +/* Test situation 2: stack really realign with DRAP reg CX */ +void __attribute__ ((noinline)) +foo () +{ + int __attribute__ ((aligned(64))) a=4; + char * s = (char *) __builtin_alloca (a + 1); + + copy (s, a); + if (__builtin_strncmp (s, "good", a) != 0) + { +#ifdef DEBUG + s[a] = '\0'; + printf ("Failed: %s != good\n", s); +#endif + abort (); + } + + if (check_int (&a, __alignof__(a)) != a) + abort (); + + ALTER_REGS(); + throw a; +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C new file mode 100644 index 0000000..48eddaf --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C @@ -0,0 +1,35 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +/* Test situation 3: Stack realign really happen with DRAP reg DI */ +void __attribute__ ((noinline)) __attribute__ ((regparm(3))) +bar (int arg1, int arg2, int arg3) +{ + int __attribute__ ((aligned(64))) a=1; + char * s = (char *) __builtin_alloca (arg3 + 1); + + copy (s, arg3); + if (__builtin_strncmp (s, "good", arg3) != 0) + { +#ifdef DEBUG + s[arg3] = '\0'; + printf ("Failed: %s != good\n", s); +#endif + abort (); + } + + if (check_int (&a, __alignof__(a)) != a) + abort (); + + ALTER_REGS(); + throw arg1+arg2+arg3+a; +} + +void +foo() +{ + bar (1,2,3); +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C new file mode 100644 index 0000000..dacbd3d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C @@ -0,0 +1,17 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +volatile int __attribute__ ((aligned(32))) g_a=1; +/* Test situation 4: no Drap and stack realign doesn't really happen */ +void __attribute__ ((noinline)) +foo() +{ + int i; + ALTER_REGS(); + for (i=0; i < 10; i++) + g_a++; + throw g_a; +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C new file mode 100644 index 0000000..fde430b --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C @@ -0,0 +1,31 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +double g_f=1.0; +/* Test situation 5: Stack realign dosn't really happen with DRAP reg CX */ +void __attribute__ ((noinline)) __attribute__ ((regparm(2))) +bar(int arg1, int arg2, int arg3, int arg4) +{ + char * s = (char *) __builtin_alloca (arg4 + 1); + + copy (s, arg4); + if (__builtin_strncmp (s, "good", arg4) != 0) + { +#ifdef DEBUG + s[arg4] = '\0'; + printf ("Failed: %s != good\n", s); +#endif + abort (); + } + ALTER_REGS(); + if (g_f) throw arg1+arg2+arg3+ g_f; +} + +void __attribute__((noinline)) +foo() +{ + bar(1,2,3,4); +} +#endif diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C new file mode 100644 index 0000000..7c9dee1 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C @@ -0,0 +1,31 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "test-unwind.h" + +#ifndef __PIC__ +double g_f=1.0; +/* Test situation 6: Stack realign dosn't really happen with DRAP reg DI */ +void __attribute__ ((noinline)) __attribute__ ((regparm(3))) +bar(int arg1, int arg2, int arg3, int arg4) +{ + char * s = (char *) __builtin_alloca (arg4 + 1); + + copy (s, arg4); + if (__builtin_strncmp (s, "good", arg4) != 0) + { +#ifdef DEBUG + s[arg4] = '\0'; + printf ("Failed: %s != good\n", s); +#endif + abort (); + } + ALTER_REGS(); + if (g_f) throw arg1+arg2+arg3+ g_f; +} + +void __attribute__((noinline)) +foo() +{ + bar(1,2,3,4); +} +#endif diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c new file mode 100644 index 0000000..167da24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c @@ -0,0 +1,21 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */ + +/* Simple test of vararg passing for problematic types with and without + double values passed between them. */ + +#define DTYPE _Decimal128 +#define ONE 1.0dl +#define THREE 3.0dl +#define SEVEN 7.0dl +#define ELEVEN 11.0dl +#define INTS 4 + +#include "func-vararg-alternate.h" + +int +main () +{ + doit (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c new file mode 100644 index 0000000..c1b349c --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c @@ -0,0 +1,118 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */ + +/* C99 6.5.2.2 Function calls. + Test passing varargs of the combination of decimal float types and + other types. */ + +#include + +extern void abort (void); +static int failcnt = 0; + +/* Support compiling the test to report individual failures; default is + to abort as soon as a check fails. */ +#ifdef DBG +#include +#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; } +#else +#define FAILURE abort (); +#endif + +/* Supposing the list of varying number of arguments is: + unsigned int, _Decimal128, double, _Decimal32, _Decimal64. */ + +static _Decimal32 +vararg_d32 (unsigned arg, ...) +{ + va_list ap; + _Decimal32 result; + + va_start (ap, arg); + + va_arg (ap, unsigned int); + va_arg (ap, _Decimal128); + va_arg (ap, double); + result = va_arg (ap, _Decimal32); + + va_end (ap); + return result; +} + +static _Decimal32 +vararg_d64 (unsigned arg, ...) +{ + va_list ap; + _Decimal64 result; + + va_start (ap, arg); + + va_arg (ap, unsigned int); + va_arg (ap, _Decimal128); + va_arg (ap, double); + va_arg (ap, _Decimal32); + result = va_arg (ap, _Decimal64); + + va_end (ap); + return result; +} + +static _Decimal128 +vararg_d128 (unsigned arg, ...) +{ + va_list ap; + _Decimal128 result; + + va_start (ap, arg); + + va_arg (ap, unsigned int); + result = va_arg (ap, _Decimal128); + + va_end (ap); + return result; +} + +static unsigned int +vararg_int (unsigned arg, ...) +{ + va_list ap; + unsigned int result; + + va_start (ap, arg); + + result = va_arg (ap, unsigned int); + + va_end (ap); + return result; +} + +static double +vararg_double (unsigned arg, ...) +{ + va_list ap; + float result; + + va_start (ap, arg); + + va_arg (ap, unsigned int); + va_arg (ap, _Decimal128); + result = va_arg (ap, double); + + va_end (ap); + return result; +} + + +int +main () +{ + if (vararg_d32 (3, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 3.0df) FAILURE + if (vararg_d64 (4, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 4.0dd) FAILURE + if (vararg_d128 (1, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 1.0dl) FAILURE + if (vararg_int (0, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 0) FAILURE + if (vararg_double (2, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 2.0) FAILURE + + if (failcnt != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c new file mode 100644 index 0000000..1370f63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +void +foo (int size) +{ + char *p = __builtin_alloca (size + 1); + aligned i; + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); +} + +int +main() +{ + foo (5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c new file mode 100644 index 0000000..38b384e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c @@ -0,0 +1,9 @@ +/* PR 11184 */ +/* Origin: Dara Hazeghi */ + +void * +objc_msg_sendv (char * arg_frame, void (*foo)()) +{ + return __builtin_apply ( foo, arg_frame, 4); +} + diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c new file mode 100644 index 0000000..a1ba20f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c @@ -0,0 +1,30 @@ +/* PR target/12503 */ +/* Origin: */ + +/* Verify that __builtin_apply behaves correctly on targets + with pre-pushed arguments (e.g. SPARC). */ + +/* { dg-do run } */ + + +#define INTEGER_ARG 5 + +extern void abort(void); + +void foo(char *name, double d, double e, double f, int g) +{ + if (g != INTEGER_ARG) + abort(); +} + +void bar(char *name, ...) +{ + __builtin_apply(foo, __builtin_apply_args(), 64); +} + +int main(void) +{ + bar("eeee", 5.444567, 8.90765, 4.567789, INTEGER_ARG); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c new file mode 100644 index 0000000..1335d09 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c @@ -0,0 +1,31 @@ +/* PR middle-end/12210 */ +/* Origin: Ossadchy Yury A. */ + +/* This used to fail on i686 because the argument was not copied + to the right location by __builtin_apply after the direct call. */ + +/* { dg-do run } */ + + +#define INTEGER_ARG 5 + +extern void abort(void); + +void foo(int arg) +{ + if (arg != INTEGER_ARG) + abort(); +} + +void bar(int arg) +{ + foo(arg); + __builtin_apply(foo, __builtin_apply_args(), 16); +} + +int main(void) +{ + bar(INTEGER_ARG); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c new file mode 100644 index 0000000..28dc610 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/20076 */ +/* { dg-do run } */ + +extern void abort (void); + +double +foo (int arg) +{ + if (arg != 116) + abort(); + return arg + 1; +} + +inline double +bar (int arg) +{ + foo (arg); + __builtin_return (__builtin_apply ((void (*) ()) foo, + __builtin_apply_args (), 16)); +} + +int +main (int argc, char **argv) +{ + if (bar (116) != 117.0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c new file mode 100644 index 0000000..75c9acd --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c @@ -0,0 +1,34 @@ +/* PR middle-end/11151 */ +/* Originator: Andrew Church */ +/* { dg-do run } */ + +/* This used to fail on SPARC because the (undefined) return + value of 'bar' was overwriting that of 'foo'. */ + +extern void abort(void); + +int foo(int n) +{ + return n+1; +} + +int bar(int n) +{ + __builtin_return(__builtin_apply((void (*)(void))foo, __builtin_apply_args(), 64)); +} + +char *g; + +int main(void) +{ + /* Allocate 64 bytes on the stack to make sure that __builtin_apply + can read at least 64 bytes above the return address. */ + char dummy[64]; + + g = dummy; + + if (bar(1) != 2) + abort(); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/check.h b/gcc/testsuite/gcc.dg/torture/stackalign/check.h new file mode 100644 index 0000000..af19885 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/check.h @@ -0,0 +1,36 @@ +#include +#ifdef DEBUG +#include +#endif + +#ifdef __cplusplus +extern "C" void abort (void); +#else +extern void abort (void); +#endif + +int +check_int (int *i, int align) +{ + *i = 20; + if ((((ptrdiff_t) i) & (align - 1)) != 0) + { +#ifdef DEBUG + printf ("\nUnalign address (%d): %p!\n", align, i); +#endif + abort (); + } + return *i; +} + +void +check (void *p, int align) +{ + if ((((ptrdiff_t) p) & (align - 1)) != 0) + { +#ifdef DEBUG + printf ("\nUnalign address (%d): %p!\n", align, p); +#endif + abort (); + } +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c new file mode 100644 index 0000000..7558f01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ + +#ifdef STACK_SIZE +#define DEPTH ((STACK_SIZE) / 512 + 1) +#else +#define DEPTH 1000 +#endif + +extern void abort (void); +extern void exit (int); + +#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES) +int +x(a) +{ + __label__ xlab; + void y(a) + { + void *x = &&llab; + if (a==-1) + goto *x; + if (a==0) + goto xlab; + llab: + y (a-1); + } + y (a); + xlab:; + return a; +} +#endif + +int +main () +{ +#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES) + if (x (DEPTH) != DEPTH) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c new file mode 100644 index 0000000..d1cda10 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c @@ -0,0 +1,31 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +__attribute__ ((fastcall)) +void +foo (int j, int k, int m, int n, int o) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5) + abort (); +} + +int +main() +{ + foo (1, 2, 3, 4, 5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c new file mode 100644 index 0000000..284daad --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +foo (void) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); +} + +int +main() +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c new file mode 100644 index 0000000..11e71c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +static void +inline __attribute__((always_inline)) +foo (void) +{ + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); +} + +int +main() +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c new file mode 100644 index 0000000..fd51b5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +static void +inline __attribute__((always_inline)) +foo (int size) +{ + char *p = __builtin_alloca (size + 1); + aligned i; + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); +} + +int +main() +{ + foo (5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c new file mode 100644 index 0000000..4e2c872 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +foo (void) +{ + aligned j; + + void bar () + { + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); + + j = -20; + } + bar (); + + if (j != -20) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); +} + +int +main() +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c new file mode 100644 index 0000000..d54e3b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +foo (void) +{ + aligned j; + + __attribute__ ((__noinline__)) + void bar () + { + aligned i; + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); + + j = -20; + } + bar (); + + if (j != -20) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); +} + +int +main() +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c new file mode 100644 index 0000000..3732991 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c @@ -0,0 +1,62 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +copy (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +void +foo (int size) +{ + aligned j; + + __attribute__ ((__noinline__)) + void bar (int size) + { + char *p = __builtin_alloca (size + 1); + aligned i; + + copy (p, size); + if (strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); + + j = -20; + } + bar (size); + + if (j != -20) + abort (); + + if (check_int (&j, __alignof__(j)) != j) + abort (); +} + +int +main() +{ + foo (5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c new file mode 100644 index 0000000..60322fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int n; + +void +g (void) +{ + __label__ lab; + void h (void) + { + aligned t; + if (check_int (&t, __alignof__(t)) != t) + abort (); + if (n+t == 0) goto lab; + } + h(); +lab: + return; +} + +int main() +{ + g(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c new file mode 100644 index 0000000..95eba04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +extern void abort (void); +extern void exit (int); + +#ifndef NO_TRAMPOLINES +static void recursive (int n, void (*proc) (void)) +{ + __label__ l1; + + void do_goto (void) + { + goto l1; + } + + if (n == 3) + recursive (n - 1, do_goto); + else if (n > 0) + recursive (n - 1, proc); + else + (*proc) (); + return; + +l1: + if (n == 3) + exit (0); + else + abort (); +} + +int main () +{ + recursive (10, abort); + abort (); +} +#else +int main () { return 0; } +#endif diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c new file mode 100644 index 0000000..d853825 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#ifndef NO_TRAMPOLINES + +typedef __SIZE_TYPE__ size_t; +extern void abort (void); +extern void exit (int); +extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + +int main () +{ + __label__ nonlocal; + int compare (const void *a, const void *b) + { + goto nonlocal; + } + + char array[3]; + qsort (array, 3, 1, compare); + abort (); + + nonlocal: + exit (0); +} + +#else +int main() { return 0; } +#endif diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c new file mode 100644 index 0000000..263d448 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ + +extern void abort (void); + +int global; + +static void foo(void) __attribute__((noinline)); + +static void foo(void) +{ + global = 1; +} + +static void bar(void) +{ + foo (); +} + +int execute(int cmd) +{ + __label__ start; + + void raise(void) + { + goto start; + } + + int last = -1; + + bar (); + + last = 0; + +start: + + if (last == 0) + while (1) + { + last = 1; + raise (); + } + + if (last == 0) + return 0; + else + return cmd; +} + +int main(void) +{ + if (execute (1) == 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c new file mode 100644 index 0000000..5a64d54 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c @@ -0,0 +1,56 @@ +/* { dg-do run } */ + +extern void abort (void); + +int global; + +static void foo(void) __attribute__((noinline)); + +static void foo(void) +{ + global = 1; +} + +static void bar(void) +{ + foo (); + global = 0; +} + +int execute(int cmd) +{ + __label__ start; + + void raise(void) + { + goto start; + } + + int last = -1; + + bar (); + + last = 0; + +start: + + if (last == 0) + while (1) + { + last = 1; + raise (); + } + + if (last == 0) + return 0; + else + return cmd; +} + +int main(void) +{ + if (execute (1) == 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c new file mode 100644 index 0000000..3afc8cc6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ + +#ifndef NO_TRAMPOLINES +extern void abort (void); + +int x(int a, int b) +{ + __label__ xlab; + + void y(int b) + { + switch (b) + { + case 1: goto xlab; + case 2: goto xlab; + } + } + + a = a + 2; + y (b); + + xlab: + return a; +} + +int main () +{ + int i, j; + + for (j = 1; j <= 2; ++j) + for (i = 1; i <= 2; ++i) + { + int a = x (j, i); + if (a != 2 + j) + abort (); + } + + return 0; +} +#else +int main() { return 0; } +#endif diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c new file mode 100644 index 0000000..3673f1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +extern void abort (void); +extern void exit (int); + +#ifdef STACK_SIZE +#define DEPTH ((STACK_SIZE) / 512 + 1) +#else +#define DEPTH 1000 +#endif + +#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES) +int + +x(a) +{ + __label__ xlab; + void y(a) + { + if (a==0) + goto xlab; + y (a-1); + } + y (a); + xlab:; + return a; +} +#endif + +int +main () +{ +#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES) + if (x (DEPTH) != DEPTH) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c new file mode 100644 index 0000000..08ca95d76 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ + +#if !defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES) +extern void abort (void); +extern void exit (int); +int s(i){if(i>0){__label__ l1;int f(int i){if(i==2)goto l1;return 0;}return f(i);l1:;}return 1;} +int x(){return s(0)==1&&s(1)==0&&s(2)==1;} +int main(){if(x()!=1)abort();exit(0);} +#else +int main(){ exit (0); } +#endif diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c new file mode 100644 index 0000000..b68c3d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ + +void +f () +{ + unsigned long tmp[4] __attribute__((aligned(16))); + asm("movaps %%xmm0, (%0)" : : "r" (tmp) : "memory"); +} + +int +main() +{ + f(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c new file mode 100644 index 0000000..9a039eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ + +#include "check.h" + +typedef __SIZE_TYPE__ size_t; +#define ALIGNMENT 256 +int main(void) +{ + int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT))); + check (&a, ALIGNMENT); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c new file mode 100644 index 0000000..1c1ddd1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ + +#include "check.h" + +typedef __SIZE_TYPE__ size_t; +#define ALIGNMENT 256 +int main(void) +{ + int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT))); + check (&a, ALIGNMENT); + int b[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT))); + check (&b, ALIGNMENT); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c new file mode 100644 index 0000000..9dac024 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c @@ -0,0 +1,60 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int test_nested (int i) +{ + aligned y; + + int __attribute__ ((__noinline__, __regparm__(2))) foo (int j, int k, int l) + { + aligned x; + + if (check_int (&x, __alignof__(x)) != x) + abort (); + + if (x != 20) + abort (); + + return i + j + k + l; + } + + if (check_int (&y, __alignof__(y)) != y) + abort (); + + if (y != 20) + abort (); + + return foo(i, i+1, i+2) * i; +} + +int __attribute__ ((__noinline__, __regparm__(3), __force_align_arg_pointer__)) +test_realigned (int j, int k, int l) +{ + aligned y; + + if (check_int (&y, __alignof__(y)) != y) + abort (); + + if (y != 20) + abort (); + + return j + k + l; +} + +int main () +{ + if (test_nested(10) != 430) + abort (); + + if (test_realigned(10, 11, 12) != 33) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c new file mode 100644 index 0000000..163e54c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +extern void abort(); +typedef struct my_struct +{ + char str[31]; +} stype ; + +stype g_s; + +stype __attribute__((noinline)) +foo (char arg1, char arg2, char arg3) +{ + stype __attribute__((aligned(ALIGNMENT))) s; + s.str[0] = arg1; + s.str[1] = arg2; + s.str[30] = arg3; + check(&s, ALIGNMENT); + return s; +} + +int main() +{ + g_s = foo(1,2,3); + + if (g_s.str[0] != 1 || g_s.str[1] != 2 || g_s.str[30] !=3) + abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c new file mode 100644 index 0000000..6ab67e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ + +extern int strcmp(const char *, const char *); +extern char *strcpy(char *, const char *); +extern void abort(void); +extern void exit(int); + +void *buf[20]; + +void __attribute__((noinline)) +sub2 (void) +{ + __builtin_longjmp (buf, 1); +} + +int +main () +{ + char *p = 0; + + p = (char *) __builtin_alloca (20); + + strcpy (p, "test"); + + if (__builtin_setjmp (buf)) + { + if (strcmp (p, "test") != 0) + abort (); + + exit (0); + } + + { + int *q = (int *) __builtin_alloca (p[2] * sizeof (int)); + int i; + + for (i = 0; i < p[2]; i++) + q[i] = 0; + + while (1) + sub2 (); + } +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c new file mode 100644 index 0000000..c93ffa8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c @@ -0,0 +1,46 @@ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */ + +#include +#include + +#ifndef NULL +#define NULL ((void *)0) +#endif +static jmp_buf segv_jmpbuf; + +static void segv_handler(int seg) +{ + __builtin_longjmp(segv_jmpbuf, 1); +} + +static int is_addressable(void *p, size_t size) +{ + volatile char * volatile cp = (volatile char *)p; + volatile int ret; + struct sigaction sa, origsa; + sigset_t mask; + + sa.sa_handler = segv_handler; + sa.sa_flags = 0; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, &origsa); + sigprocmask(SIG_SETMASK, NULL, &mask); + + if (__builtin_setjmp(segv_jmpbuf) == 0) { + while(size--) + *cp++; + ret = 1; + } else + ret = 0; + + sigaction(SIGSEGV, &origsa, NULL); + sigprocmask(SIG_SETMASK, &mask, NULL); + + return ret; +} + +int main(int argc, char **argv) +{ + is_addressable(0x0, 1); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c new file mode 100644 index 0000000..fee0d28 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ + +#include + +extern void abort (void); + +jmp_buf buf; + +void raise0(void) +{ + __builtin_longjmp (buf, 1); +} + +int execute(int cmd) +{ + int last = 0; + + if (__builtin_setjmp (buf) == 0) + while (1) + { + last = 1; + raise0 (); + } + + if (last == 0) + return 0; + else + return cmd; +} + +int main(void) +{ + if (execute (1) == 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c new file mode 100644 index 0000000..d167122 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c @@ -0,0 +1,39 @@ +/* { dg-do run } */ + +#include + +extern void abort (void); + +jmp_buf buf; + +void raise0(void) +{ + __builtin_longjmp (buf, 1); +} + +int execute(int cmd) +{ + int last = 0; + + __builtin_setjmp (buf); + + if (last == 0) + while (1) + { + last = 1; + raise0 (); + } + + if (last == 0) + return 0; + else + return cmd; +} + +int main(void) +{ + if (execute (1) == 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c new file mode 100644 index 0000000..8c17475 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ + +extern int ok (int); +extern void exit (); +static int gen_x86_64_shrd (int); +static int +gen_x86_64_shrd(int a __attribute__ ((__unused__))) +{ + return 0; +} + +extern int gen_x86_shrd_1 (int); +extern void ix86_split_ashr (int); + +void +ix86_split_ashr (int mode) +{ + (mode != 0 + ? ok + : gen_x86_64_shrd) (0); +} + +volatile int one = 1; +int +main (void) +{ + ix86_split_ashr (one); + return 1; +} + +int +ok (int i) +{ + exit (i); +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp new file mode 100644 index 0000000..3574e4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp @@ -0,0 +1,52 @@ +# Copyright (C) 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This harness is for tests that should be run at all optimisation levels. + +load_lib gcc-dg.exp + +# Only run on targets which support automatic stack alignment. +if { ![check_effective_target_automatic_stack_alignment] } then { + return +} + +set additional_flags "" +if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then { + lappend additional_flags "-mstackrealign" + lappend additional_flags "-mpreferred-stack-boundary=5" +} + +dg-init + +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags +if { [check_effective_target_fpic] } then { + set pic_additional_flags $additional_flags + lappend pic_additional_flags "-fpic" + gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags +} + +if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then { + lappend additional_flags "-mforce-drap" + gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags + if { [check_effective_target_fpic] } then { + set pic_additional_flags $additional_flags + lappend pic_additional_flags "-fpic" + gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags + } +} + +dg-finish diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c new file mode 100644 index 0000000..79e3733 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +void +foo (void) +{ + struct i + { + aligned i; + } i; + + if (check_int (&i.i, __alignof__(i.i)) != i.i) + abort (); +} + +int +main() +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c new file mode 100644 index 0000000..62b2365 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c @@ -0,0 +1,59 @@ +/* { dg-do run } */ + +#include +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +void +foo (const char *fmt, ...) +{ + va_list arg; + char *p; + aligned i; + int size; + double x; + + va_start (arg, fmt); + size = va_arg (arg, int); + if (size != 5) + abort (); + p = __builtin_alloca (size + 1); + + x = va_arg (arg, double); + if (x != 5.0) + abort (); + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); + va_end (arg); +} + +int +main() +{ + foo ("foo", 5, 5.0); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c new file mode 100644 index 0000000..00b723b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c @@ -0,0 +1,65 @@ +/* { dg-do run } */ + +#include +#include "check.h" + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +int global; + +void +bar (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +void +test (va_list arg) +{ + char *p; + aligned i; + int size; + double x; + + size = va_arg (arg, int); + if (size != 5) + abort (); + + p = __builtin_alloca (size + 1); + + x = va_arg (arg, double); + if (x != 5.0) + abort (); + + bar (p, size); + if (__builtin_strncmp (p, "good", size) != 0) + { +#ifdef DEBUG + p[size] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + if (check_int (&i, __alignof__(i)) != i) + abort (); +} + +void +foo (const char *fmt, ...) +{ + va_list arg; + va_start (arg, fmt); + test (arg); + va_end (arg); +} +int +main() +{ + foo ("foo", 5, 5.0); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/20060512-1.c b/gcc/testsuite/gcc.target/i386/20060512-1.c index 3defe64..8109f94 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-1.c +++ b/gcc/testsuite/gcc.target/i386/20060512-1.c @@ -1,6 +1,6 @@ /* { dg-do run } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-std=gnu99 -msse2" } */ +/* { dg-options "-std=gnu99 -msse2 -mpreferred-stack-boundary=4" } */ #include "sse2-check.h" @@ -28,7 +28,7 @@ sse2_test (void) int result; asm ("pushl %esi"); /* Disalign runtime stack. */ result = self_aligning_function (g_1, g_2); - asm ("popl %esi"); if (result != 42) abort (); + asm ("popl %esi"); } diff --git a/gcc/testsuite/gcc.target/i386/20060512-2.c b/gcc/testsuite/gcc.target/i386/20060512-2.c index 0e446cf..fe1af56 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-2.c +++ b/gcc/testsuite/gcc.target/i386/20060512-2.c @@ -1,12 +1,12 @@ /* { dg-do compile } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-std=gnu99" } */ +/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=4" } */ int outer_function (int x, int y) { int __attribute__ ((__noinline__, __force_align_arg_pointer__)) nested_function (int x, int y) - { /* { dg-error "force_align_arg_pointer not supported for nested functions" } */ + { return (x + y); } return (3 + nested_function (x, y)); diff --git a/gcc/testsuite/gcc.target/i386/20060512-3.c b/gcc/testsuite/gcc.target/i386/20060512-3.c index 5ffa8129e..847f0eb 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-3.c +++ b/gcc/testsuite/gcc.target/i386/20060512-3.c @@ -1,6 +1,6 @@ /* { dg-do run } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-std=gnu99 -msse2 -mstackrealign" } */ +/* { dg-options "-std=gnu99 -msse2 -mstackrealign -mpreferred-stack-boundary=4" } */ #include "sse2-check.h" @@ -28,7 +28,7 @@ sse2_test (void) int result; asm ("pushl %esi"); /* Disalign runtime stack. */ result = self_aligning_function (g_1, g_2); - asm ("popl %esi"); if (result != 42) abort (); + asm ("popl %esi"); } diff --git a/gcc/testsuite/gcc.target/i386/20060512-4.c b/gcc/testsuite/gcc.target/i386/20060512-4.c index f2dd264..ee7b8a4 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-4.c +++ b/gcc/testsuite/gcc.target/i386/20060512-4.c @@ -1,12 +1,12 @@ /* { dg-do compile } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-mstackrealign" } */ +/* { dg-options "-mstackrealign -mpreferred-stack-boundary=4" } */ int outer_function (int x, int y) { int __attribute__ ((__noinline__)) nested_function (int x, int y) - { /* { dg-warning "-mstackrealign ignored for nested functions" } */ + { return (x + y); } return (3 + nested_function (x, y)); diff --git a/gcc/testsuite/gcc.target/i386/align-main-1.c b/gcc/testsuite/gcc.target/i386/align-main-1.c new file mode 100644 index 0000000..5bbc101 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/align-main-1.c @@ -0,0 +1,25 @@ +/* Test for stack alignment when PREFERRED_STACK_BOUNDARY < alignment + of local variable. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */ +/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */ +/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */ + +#include + +#define ALIGNMENT 128 +typedef int aligned __attribute__((aligned(ALIGNMENT))); +extern void abort(void); + +void check(void * a) +{ + if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0) + abort(); +} + +int main() +{ + aligned a = 1; + check(&a); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/align-main-2.c b/gcc/testsuite/gcc.target/i386/align-main-2.c new file mode 100644 index 0000000..df45f0e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/align-main-2.c @@ -0,0 +1,25 @@ +/* Test for stack alignment when PREFERRED_STACK_BOUNDARY > alignment + of local variable. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */ +/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */ +/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */ + +#include + +#define ALIGNMENT 32 +typedef int aligned __attribute__((aligned(ALIGNMENT))); +extern void abort(void); + +void check(void * a) +{ + if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0) + abort(); +} + +int main() +{ + aligned a = 1; + check(&a); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr32000-2.c b/gcc/testsuite/gcc.target/i386/pr32000-2.c new file mode 100644 index 0000000..7230258 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr32000-2.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ilp32 && dfp } */ +/* { dg-options "-O -msse2 -std=gnu99 -mpreferred-stack-boundary=2" } */ + +#include "sse2-check.h" + +typedef struct { _Decimal128 f __attribute__((packed)); } packed; + +_Decimal128 __attribute__((noinline)) +foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4, + _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8, + int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y) +{ + return y.f; +} + +void +sse2_test (void) +{ + packed x; + _Decimal128 y = -1; + x.f = y; + y = foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, -1, x); + if (__builtin_memcmp (&y, &x.f, sizeof (y))) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c b/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c new file mode 100644 index 0000000..e4d4f20 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" } */ + +/* This case is to detect a compile time regression introduced in stack + branch development. */ +f(){asm("%0"::"r"(1.5F));}g(){asm("%0"::"r"(1.5));} diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-1.c b/gcc/testsuite/gcc.target/i386/stackalign/return-1.c new file mode 100644 index 0000000..c5b32e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ + +double +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-2.c b/gcc/testsuite/gcc.target/i386/stackalign/return-2.c new file mode 100644 index 0000000..113e71b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ +void baz (void); + +double foo (void) +{ + baz (); + return; +} + +double bar (void) +{ + baz (); +} diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-3.c b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c new file mode 100644 index 0000000..d8ab69b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 && dfp } */ +/* { dg-options "-msse -std=gnu99 -mpreferred-stack-boundary=2" } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ +_Decimal128 test (void) +{ + return 1234123412341234.123412341234dl; +} diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-4.c b/gcc/testsuite/gcc.target/i386/stackalign/return-4.c new file mode 100644 index 0000000..c66c369 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-mpreferred-stack-boundary=4" } */ +/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ +typedef int aligned __attribute__((aligned(64))); + +aligned +foo (void) { } diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-5.c b/gcc/testsuite/gcc.target/i386/stackalign/return-5.c new file mode 100644 index 0000000..84531dd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mpreferred-stack-boundary=4" } */ +/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ +struct bar +{ + int x; +} __attribute__((aligned(64))); + + +struct bar +foo (void) { } diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-6.c b/gcc/testsuite/gcc.target/i386/stackalign/return-6.c new file mode 100644 index 0000000..ceadbad --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/return-6.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mpreferred-stack-boundary=4" } */ +/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */ + +/* This compile only test is to detect an assertion failure in stack branch + development. */ +struct bar +{ + int x __attribute__((aligned(64))); +}; + + +struct bar +foo (void) { } diff --git a/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp b/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp new file mode 100644 index 0000000..463ba61 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp @@ -0,0 +1,47 @@ +# Copyright (C) 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +load_lib gcc-dg.exp + +# Only run on targets which support automatic stack alignment. +if { ![check_effective_target_automatic_stack_alignment] } then { + return +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS "-w" +} + +# Initialize `dg'. +dg-init + +set additional_flags "-mstackrealign" + +dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS + +set additional_flags "-mno-stackrealign" + +dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS + +dg-finish diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5f42666..f56b3f4 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1841,10 +1841,6 @@ proc check_effective_target_unaligned_stack { } { verbose "check_effective_target_unaligned_stack: using cached result" 2 } else { set et_unaligned_stack_saved 0 - if { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) - && (! [istarget *-*-darwin*] ) } { - set et_unaligned_stack_saved 1 - } } verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2 return $et_unaligned_stack_saved @@ -2466,3 +2462,14 @@ proc check_effective_target_4byte_wchar_t { } { int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1]; }] } + +# Return 1 if the target supports automatic stack alignment. + +proc check_effective_target_automatic_stack_alignment { } { + if { [istarget i?86*-*-*] + || [istarget x86_64-*-*] } then { + return 1 + } else { + return 0 + } +}