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
This commit is contained in:
parent
ff03930a11
commit
da98e3b126
@ -1,5 +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.
|
||||
|
||||
PR target/80846
|
||||
* optabs.def (vec_extract_optab, vec_init_optab): Change from
|
||||
a direct optab to conversion optab.
|
||||
|
@ -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-08-01 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/81297
|
||||
|
45
gcc/testsuite/gcc.c-torture/execute/pr81588.c
Normal file
45
gcc/testsuite/gcc.c-torture/execute/pr81588.c
Normal 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;
|
||||
}
|
26
gcc/testsuite/gcc.dg/pr81588.c
Normal file
26
gcc/testsuite/gcc.dg/pr81588.c
Normal 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;
|
||||
}
|
15
gcc/testsuite/gcc.dg/tree-ssa/pr81588.c
Normal file
15
gcc/testsuite/gcc.dg/tree-ssa/pr81588.c
Normal 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;
|
||||
}
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user