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>
* 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>
PR middle-end/83609
......
......@@ -24,23 +24,23 @@ main ()
/* { dg-final { gdb-test 25 "*p" "13" } } */
asm volatile (NOP); /* { dg-final { gdb-test 25 "*q" "12" } } */
__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\[2\]" "6" } } */
/* { dg-final { gdb-test 31 "*p" "6" } } */
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\[2\]" "26" } } */
/* { dg-final { gdb-test 36 "*p" "26" } } */
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\[2\]" "26" } } */
/* { dg-final { gdb-test 45 "*p" "26" } } */
/* { dg-final { gdb-test 45 "p\[-1\]" "25" } } */
/* { dg-final { gdb-test 45 "p\[-2\]" "4" } } */
/* { dg-final { gdb-test 45 "q\[-1\]" "4" } } */
/* { dg-final { gdb-test 45 "p\[-2\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 45 "q\[-1\]" "4" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test 45 "q\[1\]" "26" } } */
asm volatile (NOP); /* { dg-final { gdb-test 45 "*q" "25" } } */
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)
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
exclude it from the candidates. */
......@@ -1339,7 +1366,14 @@ build_accesses_from_assign (gimple *stmt)
racc->grp_assignment_read = 1;
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
&& !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))
racc->grp_unscalarizable_region = 1;
}
......@@ -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 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
them with a scalare replacement if there is one and generate copying of
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