From: Richard Biener Date: Wed, 26 Nov 2014 13:15:16 +0000 (+0000) Subject: Backport PRs 61969, 62031, 63379, 63605, 63665 X-Git-Tag: releases/gcc-4.8.4~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af57f28b16d81fc37eba8656c0a433e7ed06609c;p=thirdparty%2Fgcc.git Backport PRs 61969, 62031, 63379, 63605, 63665 2014-11-26 Richard Biener Backport from mainline 2014-10-08 Richard Biener PR tree-optimization/61969 * tree-nrv.c (pass_nrv::execute): Properly test for automatic variables. 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. * gcc.dg/torture/pr62031.c: New testcase. 2014-10-10 Richard Biener PR tree-optimization/63379 * tree-vect-slp.c (vect_get_constant_vectors): Do not compute a neutral operand for min/max when it is not a reduction chain. * gcc.dg/vect/pr63379.c: New testcase. 2014-11-07 Richard Biener PR tree-optimization/63605 * fold-const.c (fold_binary_loc): Properly use element_precision for types that may not be scalar. * gcc.dg/vect/pr63605.c: New testcase. 2014-10-28 Richard Biener PR middle-end/63665 * fold-const.c (fold_comparison): Properly guard simplifying against INT_MAX/INT_MIN with !TYPE_OVERFLOW_WRAPS. * gcc.dg/pr63665.c: New testcase. From-SVN: r218079 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 026f2f6afde1..2951d52cd006 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2014-11-26 Richard Biener + + Backport from mainline + 2014-10-08 Richard Biener + + PR tree-optimization/61969 + * tree-nrv.c (pass_nrv::execute): Properly test for automatic + variables. + + 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-10-10 Richard Biener + + PR tree-optimization/63379 + * tree-vect-slp.c (vect_get_constant_vectors): Do not compute + a neutral operand for min/max when it is not a reduction chain. + + 2014-11-07 Richard Biener + + PR tree-optimization/63605 + * fold-const.c (fold_binary_loc): Properly use element_precision + for types that may not be scalar. + + 2014-10-28 Richard Biener + + PR middle-end/63665 + * fold-const.c (fold_comparison): Properly guard simplifying + against INT_MAX/INT_MIN with !TYPE_OVERFLOW_WRAPS. + 2014-11-22 Oleg Endo Backport from mainline diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0cf3bfd9c6b5..9e7536a7b213 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8929,7 +8929,8 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* If the constant operation overflowed this can be simplified as a comparison against INT_MAX/INT_MIN. */ if (TREE_CODE (lhs) == INTEGER_CST - && TREE_OVERFLOW (lhs)) + && TREE_OVERFLOW (lhs) + && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))) { int const1_sgn = tree_int_cst_sgn (const1); enum tree_code code2 = code; @@ -13081,6 +13082,8 @@ fold_binary_loc (location_t loc, tree arg01 = TREE_OPERAND (arg0, 1); tree itype = TREE_TYPE (arg00); if (TREE_INT_CST_HIGH (arg01) == 0 + && !(TREE_CODE (itype) == COMPLEX_TYPE + || TREE_CODE (itype) == VECTOR_TYPE) && TREE_INT_CST_LOW (arg01) == (unsigned HOST_WIDE_INT) (TYPE_PRECISION (itype) - 1)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index df6a22dc4269..0ae6f0e17368 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,26 @@ +2014-11-26 Richard Biener + + Backport from mainline + 2014-08-15 Richard Biener + + PR tree-optimization/62031 + * gcc.dg/torture/pr62031.c: New testcase. + + 2014-10-10 Richard Biener + + PR tree-optimization/63379 + * gcc.dg/vect/pr63379.c: New testcase. + + 2014-11-07 Richard Biener + + PR tree-optimization/63605 + * gcc.dg/vect/pr63605.c: New testcase. + + 2014-10-28 Richard Biener + + PR middle-end/63665 + * gcc.dg/pr63665.c: New testcase. + 2014-11-19 Uros Bizjak PR target/63947 diff --git a/gcc/testsuite/gcc.dg/pr63665.c b/gcc/testsuite/gcc.dg/pr63665.c new file mode 100644 index 000000000000..046ecae7c1d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63665.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ +/* { dg-options "-O -fno-tree-ccp -fno-tree-fre -fno-tree-copy-prop -fwrapv" } */ + +static inline int +test5 (int x) +{ + int y = 0x80000000; + return x + y; +} + +int +main () +{ + if (test5 (0x80000000) != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr62031.c b/gcc/testsuite/gcc.dg/torture/pr62031.c new file mode 100644 index 000000000000..f0dcef44b1da --- /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/testsuite/gcc.dg/vect/pr63379.c b/gcc/testsuite/gcc.dg/vect/pr63379.c new file mode 100644 index 000000000000..f6e8fc6a4ce9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr63379.c @@ -0,0 +1,43 @@ +/* PR tree-optimization/63379 */ +/* { dg-do run } */ + +#include "tree-vect.h" + +extern void abort (void); + +typedef struct { + int x; + int y; +} Point; + +Point pt_array[25]; + +void __attribute__((noinline,noclone)) +generate_array(void) +{ + unsigned int i; + for (i = 0; i<25; i++) + { + pt_array[i].x = i; + pt_array[i].y = 1000+i; + } +} + +int main() +{ + check_vect (); + generate_array (); + Point min_pt = pt_array[0]; + Point *ptr, *ptr_end; + for (ptr = pt_array+1, ptr_end = pt_array+25; ptr != ptr_end; ++ptr) + { + min_pt.x = (min_pt.x < ptr->x) ? min_pt.x : ptr->x; + min_pt.y = (min_pt.y < ptr->y) ? min_pt.y : ptr->y; + } + + if (min_pt.x != 0 || min_pt.y != 1000) + abort (); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr63605.c b/gcc/testsuite/gcc.dg/vect/pr63605.c new file mode 100644 index 000000000000..5096c7239d8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr63605.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +extern void abort (void); + +int a, b[8] = { 2, 0, 0, 0, 0, 0, 0, 0 }, c[8]; + +int +main () +{ + int d; + check_vect (); + for (; a < 8; a++) + { + d = b[a] >> 1; + c[a] = d != 0; + } + if (c[0] != 1) + abort (); + return 0; +} diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index ebb7f306f7ff..8392e9568de2 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -919,7 +919,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); } } @@ -1326,14 +1325,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 @@ -1341,9 +1346,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 93a75f2ef79d..d56dc927ea60 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 () diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 58e7e80c8082..082c17871bfc 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -178,8 +178,7 @@ tree_nrv (void) same type and alignment as the function's result. */ if (TREE_CODE (found) != VAR_DECL || TREE_THIS_VOLATILE (found) - || DECL_CONTEXT (found) != current_function_decl - || TREE_STATIC (found) + || !auto_var_in_fn_p (found, current_function_decl) || TREE_ADDRESSABLE (found) || DECL_ALIGN (found) > DECL_ALIGN (result) || !useless_type_conversion_p (result_type, diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 7ea641a7f87c..d00a0d40b1fd 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2380,13 +2380,21 @@ vect_get_constant_vectors (tree op, slp_tree slp_node, neutral_op = build_int_cst (TREE_TYPE (op), -1); break; - case MAX_EXPR: - case MIN_EXPR: - def_stmt = SSA_NAME_DEF_STMT (op); - loop = (gimple_bb (stmt))->loop_father; - neutral_op = PHI_ARG_DEF_FROM_EDGE (def_stmt, - loop_preheader_edge (loop)); - break; + /* For MIN/MAX we don't have an easy neutral operand but + the initial values can be used fine here. Only for + a reduction chain we have to force a neutral element. */ + case MAX_EXPR: + case MIN_EXPR: + if (!GROUP_FIRST_ELEMENT (stmt_vinfo)) + neutral_op = NULL; + else + { + def_stmt = SSA_NAME_DEF_STMT (op); + loop = (gimple_bb (stmt))->loop_father; + neutral_op = PHI_ARG_DEF_FROM_EDGE (def_stmt, + loop_preheader_edge (loop)); + } + break; default: neutral_op = NULL;