I am testing the following patch to fix PR52406. We cannot simply feed DR_BASE_OBJECT to the alias-oracle as it does not reflect a real memory access. Only if we query two 'structurally compatible' references we may do this. So the following patch reverts to using DR_REF instead and improves data-ref index disambiguation by handling COMPONENT_REFs as extra access dimension (similar to how we handle REALPART/IMAGPART_EXPR).
Bootstrap / regtest pending on x86_64-unknown-linux-gnu. Richard. 2012-02-28 Richard Guenther <rguent...@suse.de> PR tree-optimization/52406 * tree-data-ref.c (dr_analyze_indices): For outer COMPONENT_REFs add indices to allow their disambiguation. (dr_may_alias_p): Use DR_REF for querying the alias oracle. (compute_affine_dependence): Make dumps easier to read and more verbose. * gcc.dg/torture/pr52406.c: New testcase. Index: gcc/tree-data-ref.c =================================================================== *** gcc/tree-data-ref.c (revision 184622) --- gcc/tree-data-ref.c (working copy) *************** dr_analyze_indices (struct data_referenc *** 886,891 **** --- 886,908 ---- VEC_safe_push (tree, heap, access_fns, integer_one_node); } + /* For outermost COMPONENT_REFs of records (but not unions!) use the + FIELD_DECL offset as constant access function so we can + disambiguate a[i].f1 and a[i].f2. */ + while (TREE_CODE (ref) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE) + { + tree off = component_ref_field_offset (ref); + off = size_binop (PLUS_EXPR, + size_binop (MULT_EXPR, + fold_convert (bitsizetype, off), + bitsize_int (BITS_PER_UNIT)), + DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1))); + ref = TREE_OPERAND (ref, 0); + VEC_safe_push (tree, heap, access_fns, off); + continue; + } + /* Analyze access functions of dimensions we know to be independent. */ aref = &ref; while (handled_component_p (*aref)) *************** bool *** 1325,1332 **** dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, bool loop_nest) { ! tree addr_a = DR_BASE_OBJECT (a); ! tree addr_b = DR_BASE_OBJECT (b); /* If we are not processing a loop nest but scalar code we do not need to care about possible cross-iteration dependences --- 1342,1349 ---- dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, bool loop_nest) { ! tree addr_a = DR_REF (a); ! tree addr_b = DR_REF (b); /* If we are not processing a loop nest but scalar code we do not need to care about possible cross-iteration dependences *************** compute_affine_dependence (struct data_d *** 4049,4059 **** if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "(compute_affine_dependence\n"); ! fprintf (dump_file, " (stmt_a = \n"); ! print_gimple_stmt (dump_file, DR_STMT (dra), 0, 0); ! fprintf (dump_file, ")\n (stmt_b = \n"); ! print_gimple_stmt (dump_file, DR_STMT (drb), 0, 0); ! fprintf (dump_file, ")\n"); } /* Analyze only when the dependence relation is not yet known. */ --- 4066,4075 ---- if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "(compute_affine_dependence\n"); ! fprintf (dump_file, " stmt_a: "); ! print_gimple_stmt (dump_file, DR_STMT (dra), 0, TDF_SLIM); ! fprintf (dump_file, " stmt_b: "); ! print_gimple_stmt (dump_file, DR_STMT (drb), 0, TDF_SLIM); } /* Analyze only when the dependence relation is not yet known. */ *************** compute_affine_dependence (struct data_d *** 4129,4135 **** } if (dump_file && (dump_flags & TDF_DETAILS)) ! fprintf (dump_file, ")\n"); } /* Compute in DEPENDENCE_RELATIONS the data dependence graph for all --- 4145,4158 ---- } if (dump_file && (dump_flags & TDF_DETAILS)) ! { ! if (DDR_ARE_DEPENDENT (ddr) == chrec_known) ! fprintf (dump_file, ") -> no dependence\n"); ! else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) ! fprintf (dump_file, ") -> dependence analysis failed\n"); ! else ! fprintf (dump_file, ")\n"); ! } } /* Compute in DEPENDENCE_RELATIONS the data dependence graph for all Index: gcc/testsuite/gcc.dg/torture/pr52406.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr52406.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr52406.c (revision 0) *************** *** 0 **** --- 1,29 ---- + /* { dg-do run } */ + + extern void abort (void); + struct { int f1; } a[2]; + + int *b, *const k = &a[1].f1; + static int **c = &b; + + int e, f, d; + + int + main () + { + int **l = &b; + *l = k; + for (; d <= 0; d++) + { + int *j = &e; + **c = 1; + *l = k; + *k ^= 0; + f = **l; + *j = f; + } + if (e != 1) + abort (); + return 0; + } +