diff options
author | Michael Matz <matz@suse.de> | 2012-06-12 11:52:41 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2012-06-12 11:52:41 +0000 |
commit | 175a7536b131a2b90213a8ded70437339f4af1e4 (patch) | |
tree | 08829258d4fe6802e2f465d6ba336e5a409258ca | |
parent | d3b00ce368f3d32a4db4dac4538a90920f6365ef (diff) | |
download | gcc-175a7536b131a2b90213a8ded70437339f4af1e4.zip gcc-175a7536b131a2b90213a8ded70437339f4af1e4.tar.gz gcc-175a7536b131a2b90213a8ded70437339f4af1e4.tar.bz2 |
alias.c (nonoverlapping_component_refs_p): Take two rtx arguments.
* alias.c (nonoverlapping_component_refs_p): Take two rtx arguments.
(nonoverlapping_memrefs_p): Don't call it here ...
(true_dependence_1): ... but here.
testsuite/
* gcc.dg/torture/alias-1.c: New test.
From-SVN: r188448
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/alias.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/alias-1.c | 38 |
4 files changed, 58 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 152d478..213703c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-06-12 Michael Matz <matz@suse.de> + + * alias.c (nonoverlapping_component_refs_p): Take two rtx arguments. + (nonoverlapping_memrefs_p): Don't call it here ... + (true_dependence_1): ... but here. + 2012-06-12 Richard Guenther <rguenther@suse.de> * emit-rtl.c (set_mem_attributes_minus_bitpos): Remove dead code. diff --git a/gcc/alias.c b/gcc/alias.c index fbc4e10..c11b13f 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -156,7 +156,7 @@ static rtx find_base_value (rtx); static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx); static int insert_subset_children (splay_tree_node, void*); static alias_set_entry get_alias_set_entry (alias_set_type); -static bool nonoverlapping_component_refs_p (const_tree, const_tree); +static bool nonoverlapping_component_refs_p (const_rtx, const_rtx); static tree decl_for_component_ref (tree); static int write_dependence_p (const_rtx, const_rtx, int); @@ -2181,11 +2181,15 @@ read_dependence (const_rtx mem, const_rtx x) overlap for any pair of objects. */ static bool -nonoverlapping_component_refs_p (const_tree x, const_tree y) +nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly) { + const_tree x = MEM_EXPR (rtlx), y = MEM_EXPR (rtly); const_tree fieldx, fieldy, typex, typey, orig_y; - if (!flag_strict_aliasing) + if (!flag_strict_aliasing + || !x || !y + || TREE_CODE (x) != COMPONENT_REF + || TREE_CODE (y) != COMPONENT_REF) return false; do @@ -2304,13 +2308,6 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) && ! MEM_OFFSET_KNOWN_P (y))) return 0; - /* If both are field references, we may be able to determine something. */ - if (TREE_CODE (exprx) == COMPONENT_REF - && TREE_CODE (expry) == COMPONENT_REF - && nonoverlapping_component_refs_p (exprx, expry)) - return 1; - - /* If the field reference test failed, look at the DECLs involved. */ moffsetx_known_p = MEM_OFFSET_KNOWN_P (x); if (moffsetx_known_p) @@ -2516,6 +2513,9 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, if (nonoverlapping_memrefs_p (mem, x, false)) return 0; + if (nonoverlapping_component_refs_p (mem, x)) + return 0; + return rtx_refs_may_alias_p (x, mem, true); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2954f59..1cc3484 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-06-12 Michael Matz <matz@suse.de> + + * gcc.dg/torture/alias-1.c: New test. + 2012-06-12 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/53589 diff --git a/gcc/testsuite/gcc.dg/torture/alias-1.c b/gcc/testsuite/gcc.dg/torture/alias-1.c new file mode 100644 index 0000000..1e60341 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/alias-1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-fschedule-insns" } */ + +extern void abort (void) __attribute__((noreturn)); + +struct B { int a; int b;}; +struct wrapper { +union setconflict +{ + struct S { char one1; struct B b1; } s; + struct T { struct B b2; char two2; } t; +} a; +}; + +int +main () +{ + int sum = 0; + int i; + struct wrapper w; + struct B *p; + + p = &w.a.s.b1; + asm ("": "=r" (p):"0" (p)); + p->a = 0; + asm ("": "=r" (p):"0" (p)); + sum += p->a; + + p = &w.a.t.b2; + asm ("": "=r" (p):"0" (p)); + p->b = 1; + asm ("": "=r" (p):"0" (p)); + sum += p->b; + + if (sum != 1) + abort(); + return 0; +} |