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: r250761
This commit is contained in:
Jakub Jelinek 2017-08-01 10:43:45 +02:00 committed by Jakub Jelinek
parent 6277010eca
commit fb700fcbf0
6 changed files with 126 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)