summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-08-01 08:43:45 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-08-01 08:43:45 +0000
commit1c6e4932ee0cd58c3f3671549af55df7a35c8786 (patch)
treeeb10776d2a5bca963431b450de52d960a47d4eab
parent50db208bc62d8d8c29aa9769ac7647bbdb1d8e23 (diff)
downloadgcc-1c6e4932ee0cd58c3f3671549af55df7a35c8786.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@250761 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr81588.c45
-rw-r--r--gcc/testsuite/gcc.dg/pr81588.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr81588.c15
-rw-r--r--gcc/tree-ssa-reassoc.c32
6 files changed, 126 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d3d5d7241b6..d1403195e63 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ 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.
+
2017-07-31 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Backport from mainline
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0659b699920..ace54311caa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/81588
+ * gcc.dg/tree-ssa/pr81588.c: New test.
+ * gcc.dg/pr81588.c: New test.
+ * gcc.c-torture/execute/pr81588.c: New test.
+
2017-07-31 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/81604
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr81588.c b/gcc/testsuite/gcc.c-torture/execute/pr81588.c
new file mode 100644
index 00000000000..b8f84b3e18c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr81588.c
@@ -0,0 +1,45 @@
+/* PR tree-optimization/81588 */
+
+__attribute__((noinline, noclone)) int
+bar (int x)
+{
+ __asm volatile ("" : : "g" (x) : "memory");
+}
+
+__attribute__((noinline, noclone)) int
+foo (unsigned x, long long y)
+{
+ if (y < 0)
+ return 0;
+ if (y < (long long) (4 * x))
+ {
+ bar (y);
+ return 1;
+ }
+ return 0;
+}
+
+int
+main ()
+{
+ volatile unsigned x = 10;
+ volatile long long y = -10000;
+ if (foo (x, y) != 0)
+ __builtin_abort ();
+ y = -1;
+ if (foo (x, y) != 0)
+ __builtin_abort ();
+ y = 0;
+ if (foo (x, y) != 1)
+ __builtin_abort ();
+ y = 39;
+ if (foo (x, y) != 1)
+ __builtin_abort ();
+ y = 40;
+ if (foo (x, y) != 0)
+ __builtin_abort ();
+ y = 10000;
+ if (foo (x, y) != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr81588.c b/gcc/testsuite/gcc.dg/pr81588.c
new file mode 100644
index 00000000000..4e83607f2a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr81588.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/81588 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+long long int a = 5011877430933453486LL, c = 1;
+unsigned short b = 24847;
+
+#include "tree-ssa/pr81588.c"
+
+int
+main ()
+{
+ foo ();
+ if (c != 0)
+ __builtin_abort ();
+ a = 24846;
+ c = 1;
+ foo ();
+ if (c != 1)
+ __builtin_abort ();
+ a = -5;
+ foo ();
+ if (c != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr81588.c b/gcc/testsuite/gcc.dg/tree-ssa/pr81588.c
new file mode 100644
index 00000000000..2709abd89a1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr81588.c
@@ -0,0 +1,15 @@
+/* PR tree-optimization/81588 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-reassoc1-details" } */
+
+extern long long int a, c;
+extern unsigned short b;
+
+/* { dg-final { scan-tree-dump-times "Optimizing range test \[^\n\r]* and comparison" 1 "reassoc1" } } */
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+ if ((b > a) != (1 + (a < 0)))
+ c = 0;
+}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index cca41d3209c..e57a343c532 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2941,17 +2941,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);
@@ -2998,8 +3007,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);
@@ -3026,7 +3041,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
@@ -3048,7 +3062,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)