From 09877e133f3ca9c11a4334707d780a7b1a018bca Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 21 Nov 2014 21:41:37 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 12 ++++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.c-torture/execute/pr64006.c | 26 +++++++++ gcc/tree-vrp.c | 82 +++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr64006.c 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 + + 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 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 + + PR tree-optimization/64006 + * gcc.c-torture/execute/pr64006.c: New test. + 2014-11-21 Lynn Boger * 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) -- 2.7.4