From 2a82beaa820410600441f36e49e91a3a18e04fc5 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 1 Apr 2019 07:16:38 +0000 Subject: [PATCH] re PR c/71598 (Wrong optimization with aliasing enums) 2019-04-01 Richard Biener PR c/71598 * gimple.c: Include langhooks.h. (gimple_get_alias_set): Treat enumeral types as the underlying integer type. c/ * c-tree.h (c_get_alias_set): Declare. * c-objc-common.h (LANG_HOOKS_GET_ALIAS_SET): Use c_get_alias_set. * c-objc-common.c (c_get_alias_set): Treat enumeral types as the underlying integer type. * gcc.dg/torture/pr71598-1.c: New testcase. * gcc.dg/torture/pr71598-2.c: Likewise. * gcc.dg/torture/pr71598-3.c: Likewise. From-SVN: r270052 --- gcc/ChangeLog | 7 ++++ gcc/c/ChangeLog | 8 ++++ gcc/c/c-objc-common.c | 19 ++++++++++ gcc/c/c-objc-common.h | 2 +- gcc/c/c-tree.h | 1 + gcc/gimple.c | 11 ++++++ gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/torture/pr71598-1.c | 21 +++++++++++ gcc/testsuite/gcc.dg/torture/pr71598-2.c | 47 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr71598-3.c | 21 +++++++++++ 10 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr71598-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr71598-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr71598-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13678514916..6982daaab18 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-04-01 Richard Biener + + PR c/71598 + * gimple.c: Include langhooks.h. + (gimple_get_alias_set): Treat enumeral types as the underlying + integer type. + 2019-03-29 Kugan Vivekanandarajah Eric Botcazou diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index fc8049e832e..076a9a26501 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2019-04-01 Richard Biener + + PR c/71598 + * c-tree.h (c_get_alias_set): Declare. + * c-objc-common.h (LANG_HOOKS_GET_ALIAS_SET): Use c_get_alias_set. + * c-objc-common.c (c_get_alias_set): Treat enumeral types + as the underlying integer type. + 2019-03-19 Martin Sebor PR tree-optimization/89688 diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c index 21ca7e6f84f..2b76737a74a 100644 --- a/gcc/c/c-objc-common.c +++ b/gcc/c/c-objc-common.c @@ -265,3 +265,22 @@ c_vla_unspec_p (tree x, tree fn ATTRIBUTE_UNUSED) { return c_vla_type_p (x); } + +/* Special routine to get the alias set of T for C. */ + +alias_set_type +c_get_alias_set (tree t) +{ + /* Allow aliasing between enumeral types and the underlying + integer type. This is required since those are compatible types. */ + if (TREE_CODE (t) == ENUMERAL_TYPE) + { + tree t1 = c_common_type_for_size (tree_to_uhwi (TYPE_SIZE (t)), + /* short-cut commoning to signed + type. */ + false); + return get_alias_set (t1); + } + + return c_common_get_alias_set (t); +} diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 7a90c7705ea..f5e820420f6 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET -#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set +#define LANG_HOOKS_GET_ALIAS_SET c_get_alias_set #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index d6e345afb37..9393f6d1545 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -623,6 +623,7 @@ extern bool c_missing_noreturn_ok_p (tree); extern bool c_warn_unused_global_decl (const_tree); extern void c_initialize_diagnostics (diagnostic_context *); extern bool c_vla_unspec_p (tree x, tree fn); +extern alias_set_type c_get_alias_set (tree); /* in c-typeck.c */ extern int in_alignof; diff --git a/gcc/gimple.c b/gcc/gimple.c index 3a91d1cb350..8fae60fb848 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "asan.h" +#include "langhooks.h" /* All the tuples have their operand vector (if present) at the very bottom @@ -2587,6 +2588,16 @@ gimple_get_alias_set (tree t) return get_alias_set (t1); } + /* Allow aliasing between enumeral types and the underlying + integer type. This is required for C since those are + compatible types. */ + else if (TREE_CODE (t) == ENUMERAL_TYPE) + { + tree t1 = lang_hooks.types.type_for_size (tree_to_uhwi (TYPE_SIZE (t)), + false /* short-cut above */); + return get_alias_set (t1); + } + return -1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index deb903bdc69..a6ac581f744 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-04-01 Richard Biener + + PR c/71598 + * gcc.dg/torture/pr71598-1.c: New testcase. + * gcc.dg/torture/pr71598-2.c: Likewise. + * gcc.dg/torture/pr71598-3.c: Likewise. + 2019-03-31 Marek Polacek PR c++/89852 - ICE with C++11 functional cast with { }. diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-1.c b/gcc/testsuite/gcc.dg/torture/pr71598-1.c new file mode 100644 index 00000000000..7dfcb3d80d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71598-1.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-short-enums" } */ + +enum e1 { c1 }; + +__attribute__((noinline,noclone)) +int f(enum e1 *p, unsigned *q) +{ + *p = c1; + *q = 2; + return *p; +} + +int main() +{ + unsigned x; + + if (f(&x, &x) != 2) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-2.c b/gcc/testsuite/gcc.dg/torture/pr71598-2.c new file mode 100644 index 00000000000..f140287d0a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71598-2.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fshort-enums" } */ + +enum e1 { c1 = -__INT_MAX__ }; + +__attribute__((noinline,noclone)) +int f(enum e1 *p, signed int *q) +{ + *p = c1; + *q = 2; + return *p; +} + +enum e2 { c2 = __SHRT_MAX__ + 1}; + +__attribute__((noinline,noclone)) +int g(enum e2 *p, unsigned short *q) +{ + *p = c2; + *q = 2; + return *p; +} + +enum e3 { c3 = __SCHAR_MAX__ }; + +__attribute__((noinline,noclone)) +int h(enum e3 *p, unsigned char *q) +{ + *p = c3; + *q = 2; + return *p; +} + +int main() +{ + signed x; + unsigned short y; + unsigned char z; + + if (f(&x, &x) != 2) + __builtin_abort(); + if (g(&y, &y) != 2) + __builtin_abort(); + if (h(&z, &z) != 2) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-3.c b/gcc/testsuite/gcc.dg/torture/pr71598-3.c new file mode 100644 index 00000000000..0b4b842133f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71598-3.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ + +enum e1 { A, B }; +enum e2 { C, D }; + +__attribute__((noinline,noclone)) +enum e1 f(unsigned int *p) +{ + *(enum e1 *)p = A; + *(enum e2 *)p = D; + return *(enum e1 *)p; +} + +int main() +{ + unsigned int storage; + + if (f(&storage) != B) + __builtin_abort(); + return 0; +} -- 2.30.2