From: Jakub Jelinek Date: Sat, 20 Jan 2018 09:58:31 +0000 (+0100) Subject: re PR middle-end/83945 (internal compiler error: Segmentation fault with -O -fcode... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37b7e7873d3a3e79523f4474a330fe41e1a90b36;p=gcc.git re PR middle-end/83945 (internal compiler error: Segmentation fault with -O -fcode-hoisting) PR middle-end/83945 * tree-emutls.c: Include gimplify.h. (lower_emutls_2): New function. (lower_emutls_1): If ADDR_EXPR is a gimple invariant and walk_tree with lower_emutls_2 callback finds some TLS decl in it, unshare_expr it before further processing. * gcc.dg/tls/pr83945.c: New test. From-SVN: r256916 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 983675622ae..321066c6b0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2018-01-20 Jakub Jelinek + PR middle-end/83945 + * tree-emutls.c: Include gimplify.h. + (lower_emutls_2): New function. + (lower_emutls_1): If ADDR_EXPR is a gimple invariant and walk_tree + with lower_emutls_2 callback finds some TLS decl in it, unshare_expr + it before further processing. + PR target/83930 * simplify-rtx.c (simplify_binary_operation_1) : Use UINTVAL (trueop1) instead of INTVAL (op1). diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e58ae1e2817..a88e459c73a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-01-20 Jakub Jelinek + PR middle-end/83945 + * gcc.dg/tls/pr83945.c: New test. + PR target/83930 * gcc.dg/pr83930.c: New test. diff --git a/gcc/testsuite/gcc.dg/tls/pr83945.c b/gcc/testsuite/gcc.dg/tls/pr83945.c new file mode 100644 index 00000000000..dade2388eea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/pr83945.c @@ -0,0 +1,21 @@ +/* PR middle-end/83945 */ +/* { dg-do compile { target tls } } */ +/* { dg-options "-O2" } */ + +struct S { int a[1]; }; +__thread struct T { int c; } e; +int f; +void bar (int); + +void +foo (int f, int x) +{ + struct S *h = (struct S *) &e.c; + for (;;) + { + int *a = h->a, i; + for (i = x; i; i--) + bar (a[f]); + bar (a[f]); + } +} diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index ae8c6e5f155..fa4b7e15c45 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-walk.h" #include "langhooks.h" #include "tree-iterator.h" +#include "gimplify.h" /* Whenever a target does not support thread-local storage (TLS) natively, we can emulate it with some run-time support in libgcc. This will in @@ -429,6 +430,20 @@ gen_emutls_addr (tree decl, struct lower_emutls_data *d) return addr; } +/* Callback for lower_emutls_1, return non-NULL if there is any TLS + VAR_DECL in the subexpressions. */ + +static tree +lower_emutls_2 (tree *ptr, int *walk_subtrees, void *) +{ + tree t = *ptr; + if (TREE_CODE (t) == VAR_DECL) + return DECL_THREAD_LOCAL_P (t) ? t : NULL_TREE; + else if (!EXPR_P (t)) + *walk_subtrees = 0; + return NULL_TREE; +} + /* Callback for walk_gimple_op. D = WI->INFO is a struct lower_emutls_data. Given an operand *PTR within D->STMT, if the operand references a TLS variable, then lower the reference to a call to the runtime. Insert @@ -455,6 +470,13 @@ lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data) { bool save_changed; + /* Gimple invariants are shareable trees, so before changing + anything in them if we will need to change anything, unshare + them. */ + if (is_gimple_min_invariant (t) + && walk_tree (&TREE_OPERAND (t, 0), lower_emutls_2, NULL, NULL)) + *ptr = t = unshare_expr (t); + /* If we're allowed more than just is_gimple_val, continue. */ if (!wi->val_only) {