aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-01-20 10:58:31 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-01-20 10:58:31 +0100
commit37b7e7873d3a3e79523f4474a330fe41e1a90b36 (patch)
tree637882dab05745b1e461c3f9b187d24c7441155b
parent09cbbded0d197f2da4f01be6f90c8535474b8200 (diff)
downloadgcc-37b7e7873d3a3e79523f4474a330fe41e1a90b36.zip
gcc-37b7e7873d3a3e79523f4474a330fe41e1a90b36.tar.gz
gcc-37b7e7873d3a3e79523f4474a330fe41e1a90b36.tar.bz2
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr83945.c21
-rw-r--r--gcc/tree-emutls.c22
4 files changed, 53 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9836756..321066c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2018-01-20 Jakub Jelinek <jakub@redhat.com>
+ 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) <case UMOD>: Use
UINTVAL (trueop1) instead of INTVAL (op1).
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e58ae1e..a88e459 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2018-01-20 Jakub Jelinek <jakub@redhat.com>
+ 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 0000000..dade238
--- /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 ae8c6e5..fa4b7e1 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)
{