diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-08-01 10:32:37 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-08-01 10:32:37 +0200 |
commit | da98e3b126ee9976c24a1e64b99219b3444b4873 (patch) | |
tree | 96a9392946ef93061a405cb399b0b97f0c17b674 /gcc/tree-ssa-reassoc.c | |
parent | ff03930a11f3a996e512ed3613eedc1b50ac5b30 (diff) | |
download | gcc-da98e3b126ee9976c24a1e64b99219b3444b4873.zip gcc-da98e3b126ee9976c24a1e64b99219b3444b4873.tar.gz gcc-da98e3b126ee9976c24a1e64b99219b3444b4873.tar.bz2 |
re PR tree-optimization/81588 (Wrong code at -O2)
PR tree-optimization/81588
* tree-ssa-reassoc.c (optimize_range_tests_var_bound): If
ranges[i].in_p, invert comparison code ccode. For >/>=,
swap rhs1 and rhs2 and comparison code unconditionally,
for </<= don't do that. Don't swap rhs1/rhs2 again if
ranges[i].in_p, instead invert comparison code ccode if
opcode or oe->rank is BIT_IOR_EXPR.
* gcc.dg/tree-ssa/pr81588.c: New test.
* gcc.dg/pr81588.c: New test.
* gcc.c-torture/execute/pr81588.c: New test.
From-SVN: r250760
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 7c3007f..b4fe488 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -2958,17 +2958,26 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length, { case GT_EXPR: case GE_EXPR: - if (!ranges[i].in_p) - std::swap (rhs1, rhs2); + case LT_EXPR: + case LE_EXPR: + break; + default: + continue; + } + if (ranges[i].in_p) + ccode = invert_tree_comparison (ccode, false); + switch (ccode) + { + case GT_EXPR: + case GE_EXPR: + std::swap (rhs1, rhs2); ccode = swap_tree_comparison (ccode); break; case LT_EXPR: case LE_EXPR: - if (ranges[i].in_p) - std::swap (rhs1, rhs2); break; default: - continue; + gcc_unreachable (); } int *idx = map->get (rhs1); @@ -3015,8 +3024,14 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length, fprintf (dump_file, "\n"); } - if (ranges[i].in_p) - std::swap (rhs1, rhs2); + operand_entry *oe = (*ops)[ranges[i].idx]; + ranges[i].in_p = 0; + if (opcode == BIT_IOR_EXPR + || (opcode == ERROR_MARK && oe->rank == BIT_IOR_EXPR)) + { + ranges[i].in_p = 1; + ccode = invert_tree_comparison (ccode, false); + } unsigned int uid = gimple_uid (stmt); gimple_stmt_iterator gsi = gsi_for_stmt (stmt); @@ -3043,7 +3058,6 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length, } else { - operand_entry *oe = (*ops)[ranges[i].idx]; tree ctype = oe->op ? TREE_TYPE (oe->op) : boolean_type_node; if (!INTEGRAL_TYPE_P (ctype) || (TREE_CODE (ctype) != BOOLEAN_TYPE @@ -3065,7 +3079,7 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length, ranges[i].high = ranges[i].low; } ranges[i].strict_overflow_p = false; - operand_entry *oe = (*ops)[ranges[*idx].idx]; + oe = (*ops)[ranges[*idx].idx]; /* Now change all the other range test immediate uses, so that those tests will be optimized away. */ if (opcode == ERROR_MARK) |