aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-reassoc.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-08-01 10:32:37 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-08-01 10:32:37 +0200
commitda98e3b126ee9976c24a1e64b99219b3444b4873 (patch)
tree96a9392946ef93061a405cb399b0b97f0c17b674 /gcc/tree-ssa-reassoc.c
parentff03930a11f3a996e512ed3613eedc1b50ac5b30 (diff)
downloadgcc-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.c32
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)