From: Jakub Jelinek Date: Thu, 7 Jul 2016 21:46:16 +0000 (+0200) Subject: backport: re PR tree-optimization/69802 (gcc ICE at -O1 and above on valid code... X-Git-Tag: releases/gcc-4.9.4~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e496f9eb6210765193b341e6301c67e16d09efb;p=thirdparty%2Fgcc.git backport: re PR tree-optimization/69802 (gcc ICE at -O1 and above on valid code on x86_64-linux-gnu with “seg fault”) Backported from mainline 2016-02-16 Jakub Jelinek PR tree-optimization/69802 * tree-ssa-reassoc.c (update_range_test): If op is SSA_NAME_IS_DEFAULT_DEF, give up unless tem is a positive op == 1 test of precision 1 integral op, otherwise handle that case as op itself. Fix up formatting. (optimize_range_tests_to_bit_test, optimize_range_tests): Fix up formatting. * gcc.dg/pr69802.c: New test. From-SVN: r238135 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b4d4dfe847e..5cb436212f0e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,16 @@ 2016-07-07 Jakub Jelinek Backported from mainline + 2016-02-16 Jakub Jelinek + + PR tree-optimization/69802 + * tree-ssa-reassoc.c (update_range_test): If op is + SSA_NAME_IS_DEFAULT_DEF, give up unless tem is a positive + op == 1 test of precision 1 integral op, otherwise handle + that case as op itself. Fix up formatting. + (optimize_range_tests_to_bit_test, optimize_range_tests): Fix + up formatting. + 2014-12-12 Richard Biener PR middle-end/64280 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fb63d67ac83d..c07963b222d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2016-07-07 Jakub Jelinek Backported from mainline + 2016-02-16 Jakub Jelinek + + PR tree-optimization/69802 + * gcc.dg/pr69802.c: New test. + 2016-02-15 Jakub Jelinek PR c++/69797 diff --git a/gcc/testsuite/gcc.dg/pr69802.c b/gcc/testsuite/gcc.dg/pr69802.c new file mode 100644 index 000000000000..27ee02f36b5d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69802.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/69802 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +struct S { unsigned f : 1; }; +int a, d; + +int +foo (void) +{ + unsigned b = 0; + struct S c; + d = ((1 && b) < c.f) & c.f; /* { dg-warning "is used uninitialized" } */ + return a; +} + +int +bar (_Bool c) +{ + unsigned b = 0; + d = ((1 && b) < c) & c; + return a; +} diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 60b4dae38a79..6bd52cca3d56 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -2091,10 +2091,33 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, tree tem = build_range_check (loc, optype, exp, in_p, low, high); enum warn_strict_overflow_code wc = WARN_STRICT_OVERFLOW_COMPARISON; gimple_stmt_iterator gsi; + unsigned int uid; if (tem == NULL_TREE) return false; + /* If op is default def SSA_NAME, there is no place to insert the + new comparison. Give up, unless we can use OP itself as the + range test. */ + if (op && SSA_NAME_IS_DEFAULT_DEF (op)) + { + if (op == range->exp + && ((TYPE_PRECISION (optype) == 1 && TYPE_UNSIGNED (optype)) + || TREE_CODE (optype) == BOOLEAN_TYPE) + && (op == tem + || (TREE_CODE (tem) == EQ_EXPR + && TREE_OPERAND (tem, 0) == op + && integer_onep (TREE_OPERAND (tem, 1)))) + && opcode != BIT_IOR_EXPR + && (opcode != ERROR_MARK || oe->rank != BIT_IOR_EXPR)) + { + stmt = NULL; + tem = op; + } + else + return false; + } + if (strict_overflow_p && issue_strict_overflow_warning (wc)) warning_at (loc, OPT_Wstrict_overflow, "assuming signed overflow does not occur " @@ -2128,11 +2151,22 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, tem = invert_truthvalue_loc (loc, tem); tem = fold_convert_loc (loc, optype, tem); - gsi = gsi_for_stmt (stmt); + if (stmt) + { + gsi = gsi_for_stmt (stmt); + uid = gimple_uid (stmt); + } + else + { + gsi = gsi_none (); + uid = 0; + } + if (stmt == NULL) + gcc_checking_assert (tem == op); /* In rare cases range->exp can be equal to lhs of stmt. In that case we have to insert after the stmt rather then before it. */ - if (op == range->exp) + else if (op == range->exp) tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, false, GSI_CONTINUE_LINKING); else @@ -2145,7 +2179,7 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, if (gimple_uid (gsi_stmt (gsi))) break; else - gimple_set_uid (gsi_stmt (gsi), gimple_uid (stmt)); + gimple_set_uid (gsi_stmt (gsi), uid); oe->op = tem; range->exp = exp;