Commit d90ffcfb by Martin Jambor Committed by Martin Jambor

Prevent SRA from removing type changing assignment

2017-12-08  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/83141
	* tree-sra.c (contains_vce_or_bfcref_p): Move up in the file, also
	test for MEM_REFs implicitely changing types with padding.  Remove
	inline keyword.
	(build_accesses_from_assign): Added contains_vce_or_bfcref_p checks.

testsuite/
	* gcc.dg/tree-ssa/pr83141.c: New test.
	* gcc.dg/guality/pr54970.c: XFAIL tests querying a[0].

From-SVN: r255510
parent 0123db8e
2017-12-08 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/83141
* tree-sra.c (contains_vce_or_bfcref_p): Move up in the file, also
test for MEM_REFs implicitely changing types with padding. Remove
inline keyword.
(build_accesses_from_assign): Added contains_vce_or_bfcref_p checks.
2017-12-08 Jakub Jelinek <jakub@redhat.com> 2017-12-08 Jakub Jelinek <jakub@redhat.com>
* config/arc/arc.c (arc_attribute_table): Add exclusions to * config/arc/arc.c (arc_attribute_table): Add exclusions to
2017-12-08 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/83141
* gcc.dg/tree-ssa/pr83141.c: New test.
* gcc.dg/guality/pr54970.c: XFAIL tests querying a[0].
2017-12-08 Jan Hubicka <hubicka@ucw.cz> 2017-12-08 Jan Hubicka <hubicka@ucw.cz>
PR middle-end/83609 PR middle-end/83609
......
...@@ -24,23 +24,23 @@ main () ...@@ -24,23 +24,23 @@ main ()
/* { dg-final { gdb-test 25 "*p" "13" } } */ /* { dg-final { gdb-test 25 "*p" "13" } } */
asm volatile (NOP); /* { dg-final { gdb-test 25 "*q" "12" } } */ asm volatile (NOP); /* { dg-final { gdb-test 25 "*q" "12" } } */
__builtin_memcpy (&a, (int [3]) { 4, 5, 6 }, sizeof (a)); __builtin_memcpy (&a, (int [3]) { 4, 5, 6 }, sizeof (a));
/* { dg-final { gdb-test 31 "a\[0\]" "4" } } */ /* { dg-final { gdb-test 31 "a\[0\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 31 "a\[1\]" "5" } } */ /* { dg-final { gdb-test 31 "a\[1\]" "5" } } */
/* { dg-final { gdb-test 31 "a\[2\]" "6" } } */ /* { dg-final { gdb-test 31 "a\[2\]" "6" } } */
/* { dg-final { gdb-test 31 "*p" "6" } } */ /* { dg-final { gdb-test 31 "*p" "6" } } */
asm volatile (NOP); /* { dg-final { gdb-test 31 "*q" "5" } } */ asm volatile (NOP); /* { dg-final { gdb-test 31 "*q" "5" } } */
*p += 20; /* { dg-final { gdb-test 36 "a\[0\]" "4" } } */ *p += 20; /* { dg-final { gdb-test 36 "a\[0\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 36 "a\[1\]" "5" } } */ /* { dg-final { gdb-test 36 "a\[1\]" "5" } } */
/* { dg-final { gdb-test 36 "a\[2\]" "26" } } */ /* { dg-final { gdb-test 36 "a\[2\]" "26" } } */
/* { dg-final { gdb-test 36 "*p" "26" } } */ /* { dg-final { gdb-test 36 "*p" "26" } } */
asm volatile (NOP); /* { dg-final { gdb-test 36 "*q" "5" } } */ asm volatile (NOP); /* { dg-final { gdb-test 36 "*q" "5" } } */
*q += 20; /* { dg-final { gdb-test 45 "a\[0\]" "4" } } */ *q += 20; /* { dg-final { gdb-test 45 "a\[0\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 45 "a\[1\]" "25" } } */ /* { dg-final { gdb-test 45 "a\[1\]" "25" } } */
/* { dg-final { gdb-test 45 "a\[2\]" "26" } } */ /* { dg-final { gdb-test 45 "a\[2\]" "26" } } */
/* { dg-final { gdb-test 45 "*p" "26" } } */ /* { dg-final { gdb-test 45 "*p" "26" } } */
/* { dg-final { gdb-test 45 "p\[-1\]" "25" } } */ /* { dg-final { gdb-test 45 "p\[-1\]" "25" } } */
/* { dg-final { gdb-test 45 "p\[-2\]" "4" } } */ /* { dg-final { gdb-test 45 "p\[-2\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 45 "q\[-1\]" "4" } } */ /* { dg-final { gdb-test 45 "q\[-1\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 45 "q\[1\]" "26" } } */ /* { dg-final { gdb-test 45 "q\[1\]" "26" } } */
asm volatile (NOP); /* { dg-final { gdb-test 45 "*q" "25" } } */ asm volatile (NOP); /* { dg-final { gdb-test 45 "*q" "25" } } */
return 0; return 0;
......
/* { dg-do run } */
/* { dg-options "-O -fdump-tree-esra-details" } */
volatile short vs;
volatile long vl;
struct A { short s; long i; long j; };
struct A a, b;
void foo ()
{
struct A c;
__builtin_memcpy (&c, &b, sizeof (struct A));
__builtin_memcpy (&a, &c, sizeof (struct A));
vs = c.s;
vl = c.i;
vl = c.j;
}
int main()
{
if ((sizeof (short) != 2)
|| (__builtin_offsetof (struct A, i) < 4))
return 0;
__builtin_memset (&b, 0, sizeof (struct A));
b.s = 1;
__builtin_memcpy ((char *)&b+2, &b, 2);
foo ();
__builtin_memcpy (&a, (char *)&a+2, 2);
if (a.s != 1)
__builtin_abort ();
return 0;
}
/* { dg-final { scan-tree-dump-not "Will attempt to totally scalarize" "esra" } } */
...@@ -1141,6 +1141,33 @@ contains_view_convert_expr_p (const_tree ref) ...@@ -1141,6 +1141,33 @@ contains_view_convert_expr_p (const_tree ref)
return false; return false;
} }
/* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs
type conversion or a COMPONENT_REF with a bit-field field declaration. */
static bool
contains_vce_or_bfcref_p (const_tree ref)
{
while (handled_component_p (ref))
{
if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
|| (TREE_CODE (ref) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
return true;
ref = TREE_OPERAND (ref, 0);
}
if (TREE_CODE (ref) != MEM_REF
|| TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
return false;
tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
!= TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
return true;
return false;
}
/* Search the given tree for a declaration by skipping handled components and /* Search the given tree for a declaration by skipping handled components and
exclude it from the candidates. */ exclude it from the candidates. */
...@@ -1339,7 +1366,14 @@ build_accesses_from_assign (gimple *stmt) ...@@ -1339,7 +1366,14 @@ build_accesses_from_assign (gimple *stmt)
racc->grp_assignment_read = 1; racc->grp_assignment_read = 1;
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt) if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
&& !is_gimple_reg_type (racc->type)) && !is_gimple_reg_type (racc->type))
bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base)); {
if (contains_vce_or_bfcref_p (rhs))
bitmap_set_bit (cannot_scalarize_away_bitmap,
DECL_UID (racc->base));
else
bitmap_set_bit (should_scalarize_away_bitmap,
DECL_UID (racc->base));
}
if (storage_order_barrier_p (lhs)) if (storage_order_barrier_p (lhs))
racc->grp_unscalarizable_region = 1; racc->grp_unscalarizable_region = 1;
} }
...@@ -3416,24 +3450,6 @@ get_repl_default_def_ssa_name (struct access *racc) ...@@ -3416,24 +3450,6 @@ get_repl_default_def_ssa_name (struct access *racc)
return get_or_create_ssa_default_def (cfun, racc->replacement_decl); return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
} }
/* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
bit-field field declaration somewhere in it. */
static inline bool
contains_vce_or_bfcref_p (const_tree ref)
{
while (handled_component_p (ref))
{
if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
|| (TREE_CODE (ref) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
return true;
ref = TREE_OPERAND (ref, 0);
}
return false;
}
/* Examine both sides of the assignment statement pointed to by STMT, replace /* Examine both sides of the assignment statement pointed to by STMT, replace
them with a scalare replacement if there is one and generate copying of them with a scalare replacement if there is one and generate copying of
replacements if scalarized aggregates have been used in the assignment. GSI replacements if scalarized aggregates have been used in the assignment. GSI
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment