From 137eddca1e884c7f157b6ad05c5f68b812ce4a89 Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 2 Apr 2013 18:27:45 +0000 Subject: [PATCH] PR c++/34949 * tree-ssa-alias.c (stmt_kills_ref_p_1): If base != ref->base and both of them are MEM_REFs, just compare first argument for equality and attempt to deal even with differing offsets. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197370 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/tree-ssa-alias.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6cfd74..81321f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,11 @@ 2013-04-02 Jakub Jelinek PR c++/34949 + * tree-ssa-alias.c (stmt_kills_ref_p_1): If base != ref->base + and both of them are MEM_REFs, just compare first argument for + equality and attempt to deal even with differing offsets. + + PR c++/34949 * tree-cfg.c (verify_gimple_assign_single): Allow lhs of gimple_clobber_p to be MEM_REF. * gimplify.c (gimplify_modify_expr): Gimplify *to_p of diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index a83e351..968c505 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1889,20 +1889,50 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) && !stmt_can_throw_internal (stmt)) { tree base, lhs = gimple_get_lhs (stmt); - HOST_WIDE_INT size, offset, max_size; + HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset; base = get_ref_base_and_extent (lhs, &offset, &size, &max_size); /* We can get MEM[symbol: sZ, index: D.8862_1] here, so base == ref->base does not always hold. */ - if (base == ref->base) + if (base != ref->base) { - /* For a must-alias check we need to be able to constrain - the access properly. */ - if (size != -1 && size == max_size) + /* If both base and ref->base are MEM_REFs, only compare the + first operand, and if the second operand isn't equal constant, + try to add the offsets into offset and ref_offset. */ + if (TREE_CODE (base) == MEM_REF && TREE_CODE (ref->base) == MEM_REF + && TREE_OPERAND (base, 0) == TREE_OPERAND (ref->base, 0)) { - if (offset <= ref->offset - && offset + size >= ref->offset + ref->max_size) - return true; + if (!tree_int_cst_equal (TREE_OPERAND (base, 0), + TREE_OPERAND (ref->base, 0))) + { + double_int off1 = mem_ref_offset (base); + off1 = off1.alshift (BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT); + off1 = off1 + double_int::from_shwi (offset); + double_int off2 = mem_ref_offset (ref->base); + off2 = off2.alshift (BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT); + off2 = off2 + double_int::from_shwi (ref_offset); + if (off1.fits_shwi () && off2.fits_shwi ()) + { + offset = off1.to_shwi (); + ref_offset = off2.to_shwi (); + } + else + size = -1; + } } + else + size = -1; + } + /* For a must-alias check we need to be able to constrain + the access properly. */ + if (size != -1 && size == max_size) + { + if (offset <= ref_offset + && offset + size >= ref_offset + ref->max_size) + return true; } } -- 2.7.4