diff options
author | Martin Sebor <msebor@redhat.com> | 2017-08-25 00:25:57 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2017-08-24 18:25:57 -0600 |
commit | 6512c0f187d84dd046380aa53673dc5ae20795e3 (patch) | |
tree | e3ef97482f1a8fea582b082f55375e0e11f7481e /gcc/gimple-fold.c | |
parent | f9dd01fabf16c866ac582141b03194cadb0f10f0 (diff) | |
download | gcc-6512c0f187d84dd046380aa53673dc5ae20795e3.zip gcc-6512c0f187d84dd046380aa53673dc5ae20795e3.tar.gz gcc-6512c0f187d84dd046380aa53673dc5ae20795e3.tar.bz2 |
PR middle-end/81908 - FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
gcc/ChangeLog:
PR middle-end/81908
* gimple-fold.c (size_must_be_zero_p): New function.
(gimple_fold_builtin_memory_op): Call it.
gcc/testsuite/ChangeLog:
PR middle-end/81908
* gcc.dg/tree-ssa/builtins-folding-gimple-2.c: New test.
* gcc.dg/tree-ssa/builtins-folding-gimple-3.c: New test.
* gcc.dg/tree-ssa/pr81908.c: New test.
From-SVN: r251347
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r-- | gcc/gimple-fold.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 251446c..bf39f28 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -628,6 +628,36 @@ var_decl_component_p (tree var) return SSA_VAR_P (inner); } +/* If the SIZE argument representing the size of an object is in a range + of values of which exactly one is valid (and that is zero), return + true, otherwise false. */ + +static bool +size_must_be_zero_p (tree size) +{ + if (integer_zerop (size)) + return true; + + if (TREE_CODE (size) != SSA_NAME) + return false; + + wide_int min, max; + enum value_range_type rtype = get_range_info (size, &min, &max); + if (rtype != VR_ANTI_RANGE) + return false; + + tree type = TREE_TYPE (size); + int prec = TYPE_PRECISION (type); + + wide_int wone = wi::one (prec); + + /* Compute the value of SSIZE_MAX, the largest positive value that + can be stored in ssize_t, the signed counterpart of size_t. */ + wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1; + + return wi::eq_p (min, wone) && wi::geu_p (max, ssize_max); +} + /* Fold function call to builtin mem{{,p}cpy,move}. Return false if no simplification can be made. If ENDP is 0, return DEST (like memcpy). @@ -646,8 +676,9 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, tree destvar, srcvar; location_t loc = gimple_location (stmt); - /* If the LEN parameter is zero, return DEST. */ - if (integer_zerop (len)) + /* If the LEN parameter is a constant zero or in range where + the only valid value is zero, return DEST. */ + if (size_must_be_zero_p (len)) { gimple *repl; if (gimple_call_lhs (stmt)) |