On Fri, 19 Aug 2011, Richard Guenther wrote: > > This is the fix for the testcase in PR50067. We strip outermost > (yes, outermost only, which makes it very inefficient) MEM_REFs > which causes the DR base objects in the PR to agree for two > conflicting DRs, but with the issues we have with how we > compose access functions they still get disambiguated. > > Bootstrap and regtest pending on x86_64-unknown-linux-gnu.
Updated patch, which exposes some latent wide-multiply GIMPLE type issues at least. Fixes all known testcases I have. We can't really use the MEM_REF (or maybe any?) offset from the base object as independent access-function. Nor can we replace the base with scev_not_known - the alias oracle will assume funny things about this (a latent issue for sure). Bootstrap and regtest running on x86_64-unknown-linux-gnu, I'll have to dig into the latent issue exposed first, but that's for next week only. Eventually all these changes need backporting to 4.6, even if the individual testcases do not fail there. Thanks, Richard. 2011-08-19 Richard Guenther <rguent...@suse.de> PR tree-optimization/50067 * tree-data-ref.c (dr_analyze_indices): Do not strip outermost MEM_REF off its ADDR_EXPR operand. Do not strip offset operand off MEM_REFs. Do not leak scev_not_known into DR_BASE_OBJECT. * gcc.dg/torture/pr50067-3.c: New testcase. * gcc.dg/torture/pr50067-4.c: Likewise. Index: gcc/tree-data-ref.c =================================================================== *** gcc/tree-data-ref.c (revision 177903) --- gcc/tree-data-ref.c (working copy) *************** dr_analyze_indices (struct data_referenc *** 868,894 **** op = TREE_OPERAND (aref, 0); access_fn = analyze_scalar_evolution (loop, op); access_fn = instantiate_scev (before_loop, loop, access_fn); ! base = initial_condition (access_fn); ! split_constant_offset (base, &base, &off); ! if (!integer_zerop (TREE_OPERAND (aref, 1))) { ! off = size_binop (PLUS_EXPR, off, ! fold_convert (ssizetype, TREE_OPERAND (aref, 1))); ! TREE_OPERAND (aref, 1) ! = build_int_cst (TREE_TYPE (TREE_OPERAND (aref, 1)), 0); } - access_fn = chrec_replace_initial_condition (access_fn, - fold_convert (TREE_TYPE (base), off)); - - TREE_OPERAND (aref, 0) = base; VEC_safe_push (tree, heap, access_fns, access_fn); } - if (TREE_CODE (ref) == MEM_REF - && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (ref, 1))) - ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); - /* For canonicalization purposes we'd like to strip all outermost zero-offset component-refs. ??? For now simply handle zero-index array-refs. */ --- 868,884 ---- op = TREE_OPERAND (aref, 0); access_fn = analyze_scalar_evolution (loop, op); access_fn = instantiate_scev (before_loop, loop, access_fn); ! if (!automatically_generated_chrec_p (access_fn)) { ! base = initial_condition (access_fn); ! split_constant_offset (base, &base, &off); ! access_fn = chrec_replace_initial_condition ! (access_fn, fold_convert (TREE_TYPE (base), off)); ! TREE_OPERAND (aref, 0) = base; } VEC_safe_push (tree, heap, access_fns, access_fn); } /* For canonicalization purposes we'd like to strip all outermost zero-offset component-refs. ??? For now simply handle zero-index array-refs. */ Index: gcc/testsuite/gcc.dg/torture/pr50067-3.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr50067-3.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr50067-3.c (revision 0) *************** *** 0 **** --- 1,20 ---- + /* { dg-do run } */ + /* { dg-options "-fpredictive-commoning" } */ + + extern void abort (void); + int a[6] = { 0, 0, 0, 0, 7, 0 }; + static int *p = &a[4]; + + int + main () + { + int i; + for (i = 0; i < 4; ++i) + { + a[i + 1] = a[i + 2] > i; + *p &= ~1; + } + if (a[4] != 0) + abort (); + return 0; + } Index: gcc/testsuite/gcc.dg/torture/pr50067-4.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr50067-4.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr50067-4.c (revision 0) *************** *** 0 **** --- 1,20 ---- + /* { dg-do run } */ + + /* Verify we do not get a bogus access function with 0B vs. 1B which + disambiguates both accesses and leads to vectorization. */ + + extern int memcmp(const void *, const void *, __SIZE_TYPE__); + extern void abort (void); + short a[33] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; + short b[33] = { 0, }; + int main() + { + int i; + for (i = 0; i < 64; ++i) + { + (*((char(*)[])&a[1]))[i] = (*((char(*)[])&a[0]))[i+1]; + } + if (memcmp (&a, &b, sizeof (a)) != 0) + abort (); + return 0; + }