aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-11-21 21:41:37 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-11-21 21:41:37 +0100
commit09877e133f3ca9c11a4334707d780a7b1a018bca (patch)
tree77c4e0749d73de62a9cf49723dd7c628028194a5 /gcc
parenteb23df59649fc1e64937f9fd630cdc3e89fa6181 (diff)
downloadgcc-09877e133f3ca9c11a4334707d780a7b1a018bca.zip
gcc-09877e133f3ca9c11a4334707d780a7b1a018bca.tar.gz
gcc-09877e133f3ca9c11a4334707d780a7b1a018bca.tar.bz2
re PR tree-optimization/64006 (__builtin_mul_overflow fails to signal overflow)
PR tree-optimization/64006 * tree-vrp.c (stmt_interesting_for_vrp): Return true for {ADD,SUB,MUL}_OVERFLOW internal calls. (vrp_visit_assignment_or_call): For {ADD,SUB,MUL}_OVERFLOW internal calls, check if any REALPART_EXPR/IMAGPART_EXPR immediate uses would change their value ranges and return SSA_PROP_INTERESTING if so, or SSA_PROP_NOT_INTERESTING if there are some REALPART_EXPR/IMAGPART_EXPR immediate uses interesting for vrp. * gcc.c-torture/execute/pr64006.c: New test. From-SVN: r217945
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr64006.c26
-rw-r--r--gcc/tree-vrp.c82
4 files changed, 125 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9fb7f7a..1254751 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2014-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/64006
+ * tree-vrp.c (stmt_interesting_for_vrp): Return true
+ for {ADD,SUB,MUL}_OVERFLOW internal calls.
+ (vrp_visit_assignment_or_call): For {ADD,SUB,MUL}_OVERFLOW
+ internal calls, check if any REALPART_EXPR/IMAGPART_EXPR
+ immediate uses would change their value ranges and return
+ SSA_PROP_INTERESTING if so, or SSA_PROP_NOT_INTERESTING
+ if there are some REALPART_EXPR/IMAGPART_EXPR immediate uses
+ interesting for vrp.
+
2014-11-21 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/63965
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fd91a5c..cfb8c5f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/64006
+ * gcc.c-torture/execute/pr64006.c: New test.
+
2014-11-21 Lynn Boger <laboger@linux.vnet.ibm.com>
* go.test/go-test.exp (go-set-goarch): Add case for ppc64le goarch
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64006.c b/gcc/testsuite/gcc.c-torture/execute/pr64006.c
new file mode 100644
index 0000000..ddf9207
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr64006.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/64006 */
+
+int v;
+
+long __attribute__ ((noinline, noclone))
+test (long *x, int y)
+{
+ int i;
+ long s = 1;
+ for (i = 0; i < y; i++)
+ if (__builtin_mul_overflow (s, x[i], &s))
+ v++;
+ return s;
+}
+
+int
+main ()
+{
+ long d[7] = { 975, 975, 975, 975, 975, 975, 975 };
+ long r = test (d, 7);
+ if (sizeof (long) * __CHAR_BIT__ == 64 && v != 1)
+ __builtin_abort ();
+ else if (sizeof (long) * __CHAR_BIT__ == 32 && v != 4)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a75138f..27ec29b 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -6949,6 +6949,20 @@ stmt_interesting_for_vrp (gimple stmt)
&& (is_gimple_call (stmt)
|| !gimple_vuse (stmt)))
return true;
+ else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+ switch (gimple_call_internal_fn (stmt))
+ {
+ case IFN_ADD_OVERFLOW:
+ case IFN_SUB_OVERFLOW:
+ case IFN_MUL_OVERFLOW:
+ /* These internal calls return _Complex integer type,
+ but are interesting to VRP nevertheless. */
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ return true;
+ break;
+ default:
+ break;
+ }
}
else if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)
@@ -7101,6 +7115,74 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
return SSA_PROP_NOT_INTERESTING;
}
+ else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+ switch (gimple_call_internal_fn (stmt))
+ {
+ case IFN_ADD_OVERFLOW:
+ case IFN_SUB_OVERFLOW:
+ case IFN_MUL_OVERFLOW:
+ /* These internal calls return _Complex integer type,
+ which VRP does not track, but the immediate uses
+ thereof might be interesting. */
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ {
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ enum ssa_prop_result res = SSA_PROP_VARYING;
+
+ set_value_range_to_varying (get_value_range (lhs));
+
+ FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
+ {
+ gimple use_stmt = USE_STMT (use_p);
+ if (!is_gimple_assign (use_stmt))
+ continue;
+ enum tree_code rhs_code = gimple_assign_rhs_code (use_stmt);
+ if (rhs_code != REALPART_EXPR && rhs_code != IMAGPART_EXPR)
+ continue;
+ tree rhs1 = gimple_assign_rhs1 (use_stmt);
+ tree use_lhs = gimple_assign_lhs (use_stmt);
+ if (TREE_CODE (rhs1) != rhs_code
+ || TREE_OPERAND (rhs1, 0) != lhs
+ || TREE_CODE (use_lhs) != SSA_NAME
+ || !stmt_interesting_for_vrp (use_stmt)
+ || (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
+ || !TYPE_MIN_VALUE (TREE_TYPE (use_lhs))
+ || !TYPE_MAX_VALUE (TREE_TYPE (use_lhs))))
+ continue;
+
+ /* If there is a change in the value range for any of the
+ REALPART_EXPR/IMAGPART_EXPR immediate uses, return
+ SSA_PROP_INTERESTING. If there are any REALPART_EXPR
+ or IMAGPART_EXPR immediate uses, but none of them have
+ a change in their value ranges, return
+ SSA_PROP_NOT_INTERESTING. If there are no
+ {REAL,IMAG}PART_EXPR uses at all,
+ return SSA_PROP_VARYING. */
+ value_range_t new_vr = VR_INITIALIZER;
+ extract_range_basic (&new_vr, use_stmt);
+ value_range_t *old_vr = get_value_range (use_lhs);
+ if (old_vr->type != new_vr.type
+ || !vrp_operand_equal_p (old_vr->min, new_vr.min)
+ || !vrp_operand_equal_p (old_vr->max, new_vr.max)
+ || !vrp_bitmap_equal_p (old_vr->equiv, new_vr.equiv))
+ res = SSA_PROP_INTERESTING;
+ else
+ res = SSA_PROP_NOT_INTERESTING;
+ BITMAP_FREE (new_vr.equiv);
+ if (res == SSA_PROP_INTERESTING)
+ {
+ *output_p = lhs;
+ return res;
+ }
+ }
+
+ return res;
+ }
+ break;
+ default:
+ break;
+ }
/* Every other statement produces no useful ranges. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)