aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2017-08-25 00:25:57 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2017-08-24 18:25:57 -0600
commit6512c0f187d84dd046380aa53673dc5ae20795e3 (patch)
treee3ef97482f1a8fea582b082f55375e0e11f7481e /gcc/gimple-fold.c
parentf9dd01fabf16c866ac582141b03194cadb0f10f0 (diff)
downloadgcc-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.c35
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))