From 251901a027bfefffce90ca3d0776c677879d7124 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Feb 2014 11:54:20 +0100 Subject: [PATCH] re PR target/60062 (wrong code (for code with the optimize attribute) at -O1 and above on x86_64-linux-gnu in 32-bit mode) PR target/60062 * tree.h (opts_for_fn): New inline function. (opt_for_fn): Define. * config/i386/i386.c (ix86_function_regparm): Use opt_for_fn (decl, optimize) instead of optimize. * gcc.c-torture/execute/pr60062.c: New test. * gcc.c-torture/execute/pr60072.c: New test. From-SVN: r207549 --- gcc/ChangeLog | 8 ++++++ gcc/config/i386/i386.c | 7 +++++- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.c-torture/execute/pr60062.c | 25 +++++++++++++++++++ gcc/testsuite/gcc.c-torture/execute/pr60072.c | 16 ++++++++++++ gcc/tree.h | 14 +++++++++++ 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr60062.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr60072.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 078192de17a..7028dd60e6d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-02-06 Jakub Jelinek + + PR target/60062 + * tree.h (opts_for_fn): New inline function. + (opt_for_fn): Define. + * config/i386/i386.c (ix86_function_regparm): Use + opt_for_fn (decl, optimize) instead of optimize. + 2014-02-06 Marcus Shawcroft * config/aarch64/aarch64.c (aarch64_classify_symbol): Fix logic diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 58f36e0445a..abe05aab36e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5608,7 +5608,12 @@ ix86_function_regparm (const_tree type, const_tree decl) /* Use register calling convention for local functions when possible. */ if (decl && TREE_CODE (decl) == FUNCTION_DECL - && optimize + /* Caller and callee must agree on the calling convention, so + checking here just optimize means that with + __attribute__((optimize (...))) caller could use regparm convention + and callee not, or vice versa. Instead look at whether the callee + is optimized or not. */ + && opt_for_fn (decl, optimize) && !(profile_flag && !flag_fentry)) { /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a91c110d7e6..552b591e240 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-02-06 Jakub Jelinek + + PR target/60062 + * gcc.c-torture/execute/pr60062.c: New test. + * gcc.c-torture/execute/pr60072.c: New test. + 2014-02-06 Ian Bolton * gcc.dg/tree-ssa/pr59597.c: Make called function static diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60062.c b/gcc/testsuite/gcc.c-torture/execute/pr60062.c new file mode 100644 index 00000000000..62973d458a4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr60062.c @@ -0,0 +1,25 @@ +/* PR target/60062 */ + +int a; + +static void +foo (const char *p1, int p2) +{ + if (__builtin_strcmp (p1, "hello") != 0) + __builtin_abort (); +} + +static void +bar (const char *p1) +{ + if (__builtin_strcmp (p1, "hello") != 0) + __builtin_abort (); +} + +__attribute__((optimize (0))) int +main () +{ + foo ("hello", a); + bar ("hello"); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60072.c b/gcc/testsuite/gcc.c-torture/execute/pr60072.c new file mode 100644 index 00000000000..566874d635e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr60072.c @@ -0,0 +1,16 @@ +/* PR target/60072 */ + +int c = 1; + +__attribute__ ((optimize (1))) +static int *foo (int *p) +{ + return p; +} + +int +main () +{ + *foo (&c) = 2; + return c - 2; +} diff --git a/gcc/tree.h b/gcc/tree.h index e918ec54d24..0dc8d0dcd4f 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4470,6 +4470,20 @@ may_be_aliased (const_tree var) || TREE_ADDRESSABLE (var))); } +/* Return pointer to optimization flags of FNDECL. */ +static inline struct cl_optimization * +opts_for_fn (const_tree fndecl) +{ + tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); + if (fn_opts == NULL_TREE) + fn_opts = optimization_default_node; + return TREE_OPTIMIZATION (fn_opts); +} + +/* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is + the optimization level of function fndecl. */ +#define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt) + /* For anonymous aggregate types, we need some sort of name to hold on to. In practice, this should not appear, but it should not be harmful if it does. */ -- 2.30.2