From da98e3b126ee9976c24a1e64b99219b3444b4873 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 1 Aug 2017 10:32:37 +0200 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 8 +++++ gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gcc.c-torture/execute/pr81588.c | 45 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr81588.c | 26 ++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr81588.c | 15 +++++++++ gcc/tree-ssa-reassoc.c | 32 +++++++++++++------ 6 files changed, 124 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr81588.c create mode 100644 gcc/testsuite/gcc.dg/pr81588.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr81588.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c811099..ee6fcd5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2017-08-01 Jakub Jelinek + 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 rank is BIT_IOR_EXPR. + PR target/80846 * optabs.def (vec_extract_optab, vec_init_optab): Change from a direct optab to conversion optab. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8ae9ef5..5d05b3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-08-01 Jakub Jelinek + + 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-08-01 Richard Biener PR tree-optimization/81297 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 0000000..b8f84b3 --- /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 0000000..4e83607 --- /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 0000000..2709abd --- /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 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) -- 2.7.4