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
This commit is contained in:
parent
09cbbded0d
commit
37b7e7873d
|
@ -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).
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue