diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 284661dfa1b..06b57ff6c0c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2014-08-15 Richard Biener + + PR tree-optimization/62031 + * tree-data-ref.c (dr_analyze_indices): Do not set + DR_UNCONSTRAINED_BASE. + (dr_may_alias_p): All indirect accesses have to go the + formerly DR_UNCONSTRAINED_BASE path. + * tree-data-ref.h (struct indices): Remove + unconstrained_base member. + (DR_UNCONSTRAINED_BASE): Remove. + 2014-08-15 Jakub Jelinek PR middle-end/62092 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a55214702cb..ab8e0544302 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-08-15 Richard Biener + + PR tree-optimization/62031 + * gcc.dg/torture/pr62031.c: New testcase. + 2014-08-15 Bin Cheng * gcc.dg/tree-ssa/ivopts-lt-2.c: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr62031.c b/gcc/testsuite/gcc.dg/torture/pr62031.c new file mode 100644 index 00000000000..f0dcef44b1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr62031.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#include + +#define NUM_OF_STATES 4 +typedef unsigned int entry_t[2]; +typedef struct entries_item { entry_t metricEntries_[0]; } entries_item_t; + +void __attribute__((noinline,noclone)) +test_00(size_t numOfStates, entries_item_t* p_bm, + const unsigned int* polyArray, + size_t polyArraySize) +{ + size_t idx; + unsigned int hlp0, hlp1; + for (idx = 0; idx < numOfStates; ++idx) + { + size_t idy; + + hlp0 = (idx << 1) | 0x00; + hlp1 = (idx << 1) | 0x01; + p_bm->metricEntries_[idx][0] = 0; + p_bm->metricEntries_[idx][1] = 0; + for (idy = 0; idy < polyArraySize; ++idy) + { + p_bm->metricEntries_[idx][0] + |= __builtin_parity(hlp0 & polyArray[idy]) << idy; + p_bm->metricEntries_[idx][1] + |= __builtin_parity(hlp1 & polyArray[idy]) << idy; + } + } +} + +int main() +{ + unsigned int polyArray[] = { 0x07, 0x05 }; + entries_item_t* pBranchMetrics; + pBranchMetrics = malloc(sizeof(entry_t) * NUM_OF_STATES); + test_00(NUM_OF_STATES, pBranchMetrics, polyArray, + sizeof(polyArray) / sizeof(polyArray[0])); + if (pBranchMetrics->metricEntries_[0][0] != 0 + || pBranchMetrics->metricEntries_[0][1] != 3 + || pBranchMetrics->metricEntries_[1][0] != 1 + || pBranchMetrics->metricEntries_[1][1] != 2 + || pBranchMetrics->metricEntries_[2][0] != 3 + || pBranchMetrics->metricEntries_[2][1] != 0 + || pBranchMetrics->metricEntries_[3][0] != 2 + || pBranchMetrics->metricEntries_[3][1] != 1) + abort (); + free(pBranchMetrics); + return 0; +} diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 55dbf6a65d3..1d3efa67813 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -982,7 +982,6 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) ref = fold_build2_loc (EXPR_LOCATION (ref), MEM_REF, TREE_TYPE (ref), base, memoff); - DR_UNCONSTRAINED_BASE (dr) = true; access_fns.safe_push (access_fn); } } @@ -1389,14 +1388,20 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, return false; } - /* If we had an evolution in a MEM_REF BASE_OBJECT we do not know - the size of the base-object. So we cannot do any offset/overlap - based analysis but have to rely on points-to information only. */ + /* If we had an evolution in a pointer-based MEM_REF BASE_OBJECT we + do not know the size of the base-object. So we cannot do any + offset/overlap based analysis but have to rely on points-to + information only. */ if (TREE_CODE (addr_a) == MEM_REF - && DR_UNCONSTRAINED_BASE (a)) + && TREE_CODE (TREE_OPERAND (addr_a, 0)) == SSA_NAME) { - if (TREE_CODE (addr_b) == MEM_REF - && DR_UNCONSTRAINED_BASE (b)) + /* For true dependences we can apply TBAA. */ + if (flag_strict_aliasing + && DR_IS_WRITE (a) && DR_IS_READ (b) + && !alias_sets_conflict_p (get_alias_set (DR_REF (a)), + get_alias_set (DR_REF (b)))) + return false; + if (TREE_CODE (addr_b) == MEM_REF) return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0), TREE_OPERAND (addr_b, 0)); else @@ -1404,9 +1409,21 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, build_fold_addr_expr (addr_b)); } else if (TREE_CODE (addr_b) == MEM_REF - && DR_UNCONSTRAINED_BASE (b)) - return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a), - TREE_OPERAND (addr_b, 0)); + && TREE_CODE (TREE_OPERAND (addr_b, 0)) == SSA_NAME) + { + /* For true dependences we can apply TBAA. */ + if (flag_strict_aliasing + && DR_IS_WRITE (a) && DR_IS_READ (b) + && !alias_sets_conflict_p (get_alias_set (DR_REF (a)), + get_alias_set (DR_REF (b)))) + return false; + if (TREE_CODE (addr_a) == MEM_REF) + return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0), + TREE_OPERAND (addr_b, 0)); + else + return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a), + TREE_OPERAND (addr_b, 0)); + } /* Otherwise DR_BASE_OBJECT is an access that covers the whole object that is being subsetted in the loop nest. */ diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index f4075fc5bd7..a96c5ff4c47 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -81,10 +81,6 @@ struct indices /* A list of chrecs. Access functions of the indices. */ vec access_fns; - - /* Whether BASE_OBJECT is an access representing the whole object - or whether the access could not be constrained. */ - bool unconstrained_base; }; struct dr_alias @@ -195,7 +191,6 @@ struct data_reference #define DR_STMT(DR) (DR)->stmt #define DR_REF(DR) (DR)->ref #define DR_BASE_OBJECT(DR) (DR)->indices.base_object -#define DR_UNCONSTRAINED_BASE(DR) (DR)->indices.unconstrained_base #define DR_ACCESS_FNS(DR) (DR)->indices.access_fns #define DR_ACCESS_FN(DR, I) DR_ACCESS_FNS (DR)[I] #define DR_NUM_DIMENSIONS(DR) DR_ACCESS_FNS (DR).length ()