Fix PR88784, middle end is missing some optimizations about unsigned

2019-09-16  Li Jia He  <helijia@linux.ibm.com>
	    Qi Feng  <ffengqi@linux.ibm.com>

	PR middle-end/88784
	* match.pd (x >  y  &&  x != XXX_MIN): Optimize into 'x > y'.
	(x >  y  &&  x == XXX_MIN): Optimize into 'false'.
	(x <= y  &&  x == XXX_MIN): Optimize into 'x == XXX_MIN'.
	(x <  y  &&  x != XXX_MAX): Optimize into 'x < y'.
	(x <  y  &&  x == XXX_MAX): Optimize into 'false'.
	(x >= y  &&  x == XXX_MAX): Optimize into 'x == XXX_MAX'.
	(x >  y  ||  x != XXX_MIN): Optimize into 'x != XXX_MIN'.
	(x <= y  ||  x != XXX_MIN): Optimize into 'true'.
	(x <= y  ||  x == XXX_MIN): Optimize into 'x <= y'.
	(x <  y  ||  x != XXX_MAX): Optimize into 'x != XXX_MAX'.
	(x >= y  ||  x != XXX_MAX): Optimize into 'true'.
	(x >= y  ||  x == XXX_MAX): Optimize into 'x >= y'.
2019-09-16  Li Jia He  <helijia@linux.ibm.com>
	    Qi Feng  <ffengqi@linux.ibm.com>

	PR middle-end/88784
	* gcc.dg/pr88784-1.c: New testcase.
	* gcc.dg/pr88784-2.c: New testcase.
	* gcc.dg/pr88784-3.c: New testcase.
	* gcc.dg/pr88784-4.c: New testcase.
	* gcc.dg/pr88784-5.c: New testcase.
	* gcc.dg/pr88784-6.c: New testcase.
	* gcc.dg/pr88784-7.c: New testcase.
	* gcc.dg/pr88784-8.c: New testcase.
	* gcc.dg/pr88784-9.c: New testcase.
	* gcc.dg/pr88784-10.c: New testcase.
	* gcc.dg/pr88784-11.c: New testcase.
	* gcc.dg/pr88784-12.c: New testcase.

Co-Authored-By: Qi Feng <ffengqi@linux.ibm.com>

From-SVN: r275749
This commit is contained in:
Li Jia He 2019-09-16 14:22:16 +00:00 committed by Martin Liska
parent 5f487a349d
commit c16504f6ea
15 changed files with 484 additions and 4 deletions

View File

@ -1,3 +1,20 @@
2019-09-16 Li Jia He <helijia@linux.ibm.com>
Qi Feng <ffengqi@linux.ibm.com>
PR middle-end/88784
* match.pd (x > y && x != XXX_MIN): Optimize into 'x > y'.
(x > y && x == XXX_MIN): Optimize into 'false'.
(x <= y && x == XXX_MIN): Optimize into 'x == XXX_MIN'.
(x < y && x != XXX_MAX): Optimize into 'x < y'.
(x < y && x == XXX_MAX): Optimize into 'false'.
(x >= y && x == XXX_MAX): Optimize into 'x == XXX_MAX'.
(x > y || x != XXX_MIN): Optimize into 'x != XXX_MIN'.
(x <= y || x != XXX_MIN): Optimize into 'true'.
(x <= y || x == XXX_MIN): Optimize into 'x <= y'.
(x < y || x != XXX_MAX): Optimize into 'x != XXX_MAX'.
(x >= y || x != XXX_MAX): Optimize into 'true'.
(x >= y || x == XXX_MAX): Optimize into 'x >= y'.
2019-09-16 Li Jia He <helijia@linux.ibm.com>
Martin Liska <mliska@suse.cz>

View File

@ -1883,6 +1883,80 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ wide_int_to_tree (type, (wi::to_wide (@1)
& (bitpos / BITS_PER_UNIT))); }))))
(match min_value
INTEGER_CST
(if (INTEGRAL_TYPE_P (type)
&& wi::eq_p (wi::to_wide (t), wi::min_value (type)))))
(match max_value
INTEGER_CST
(if (INTEGRAL_TYPE_P (type)
&& wi::eq_p (wi::to_wide (t), wi::max_value (type)))))
/* x > y && x != XXX_MIN --> x > y
x > y && x == XXX_MIN --> false . */
(for eqne (eq ne)
(simplify
(bit_and:c (gt:c@2 @0 @1) (eqne @0 min_value))
(switch
(if (eqne == EQ_EXPR)
{ constant_boolean_node (false, type); })
(if (eqne == NE_EXPR)
@2)
)))
/* x < y && x != XXX_MAX --> x < y
x < y && x == XXX_MAX --> false. */
(for eqne (eq ne)
(simplify
(bit_and:c (lt:c@2 @0 @1) (eqne @0 max_value))
(switch
(if (eqne == EQ_EXPR)
{ constant_boolean_node (false, type); })
(if (eqne == NE_EXPR)
@2)
)))
/* x <= y && x == XXX_MIN --> x == XXX_MIN. */
(simplify
(bit_and:c (le:c @0 @1) (eq@2 @0 min_value))
@2)
/* x >= y && x == XXX_MAX --> x == XXX_MAX. */
(simplify
(bit_and:c (ge:c @0 @1) (eq@2 @0 max_value))
@2)
/* x > y || x != XXX_MIN --> x != XXX_MIN. */
(simplify
(bit_ior:c (gt:c @0 @1) (ne@2 @0 min_value))
@2)
/* x <= y || x != XXX_MIN --> true. */
(simplify
(bit_ior:c (le:c @0 @1) (ne @0 min_value))
{ constant_boolean_node (true, type); })
/* x <= y || x == XXX_MIN --> x <= y. */
(simplify
(bit_ior:c (le:c@2 @0 @1) (eq @0 min_value))
@2)
/* x < y || x != XXX_MAX --> x != XXX_MAX. */
(simplify
(bit_ior:c (lt:c @0 @1) (ne@2 @0 max_value))
@2)
/* x >= y || x != XXX_MAX --> true
x >= y || x == XXX_MAX --> x >= y. */
(for eqne (eq ne)
(simplify
(bit_ior:c (ge:c@2 @0 @1) (eqne @0 max_value))
(switch
(if (eqne == EQ_EXPR)
@2)
(if (eqne == NE_EXPR)
{ constant_boolean_node (true, type); }))))
/* We can't reassociate at all for saturating types. */
(if (!TYPE_SATURATING (type))
@ -5425,10 +5499,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
on c, so could drop potentially-trapping arithmetic, but that's a valid
simplification if the result of the operation isn't needed.
Avoid speculatively generating a stand-alone vector comparison
on targets that might not support them. Any target implementing
conditional internal functions must support the same comparisons
inside and outside a VEC_COND_EXPR. */
Avoid speculatively generating a stand-alone vector comparison
on targets that might not support them. Any target implementing
conditional internal functions must support the same comparisons
inside and outside a VEC_COND_EXPR. */
#if GIMPLE
(for uncond_op (UNCOND_BINARY)

View File

@ -1,3 +1,20 @@
2019-09-16 Li Jia He <helijia@linux.ibm.com>
Qi Feng <ffengqi@linux.ibm.com>
PR middle-end/88784
* gcc.dg/pr88784-1.c: New testcase.
* gcc.dg/pr88784-2.c: New testcase.
* gcc.dg/pr88784-3.c: New testcase.
* gcc.dg/pr88784-4.c: New testcase.
* gcc.dg/pr88784-5.c: New testcase.
* gcc.dg/pr88784-6.c: New testcase.
* gcc.dg/pr88784-7.c: New testcase.
* gcc.dg/pr88784-8.c: New testcase.
* gcc.dg/pr88784-9.c: New testcase.
* gcc.dg/pr88784-10.c: New testcase.
* gcc.dg/pr88784-11.c: New testcase.
* gcc.dg/pr88784-12.c: New testcase.
2019-09-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/91756

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x > y && x != 0 --> x > y */
return x > y && x != 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x < y && x != UINT_MAX --> x < y */
return x < y && x != UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x > y && x != INT_MIN --> x > y */
return x > y && x != INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x < y && x != INT_MAX --> x < y */
return x < y && x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x <= y || x != 0 --> true */
return x <= y || x != 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x >= y || x != UINT_MAX --> true */
return x >= y || x != UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x <= y || x != INT_MIN --> true */
return x <= y || x != INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x >= y || x != INT_MAX --> true */
return x >= y || x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x <= y || x == 0 --> x <= y */
return x <= y || x == 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x >= y || x == UINT_MAX --> x >= y */
return x >= y || x == UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x <= y || x == INT_MIN --> x <= y */
return x <= y || x == INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x >= y || x == INT_MAX --> x >= y */
return x >= y || x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-dce3" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x <= y || x == 0 --> x <= y */
return x <= y || x == 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x >= y || x == UINT_MAX --> x >= y */
return x >= y || x == UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x <= y || x == INT_MIN --> x <= y */
return x <= y || x == INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x >= y || x == INT_MAX --> x >= y */
return x >= y || x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " == " "dce3" } } */

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x > y && x != 0 --> x > y */
return x > y && x != 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x < y && x != UINT_MAX --> x < y */
return x < y && x != UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x > y && x != INT_MIN --> x > y */
return x > y && x != INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x < y && x != INT_MAX --> x < y */
return x < y && x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " != " "optimized" } } */

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x > y && x == 0 --> false */
return x > y && x == 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x < y && x == UINT_MAX --> false */
return x < y && x == UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x > y && x == INT_MIN --> false */
return x > y && x == INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x < y && x == INT_MAX --> false */
return x < y && x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x > y && x == 0 --> false */
return x > y && x == 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x < y && x == UINT_MAX --> false */
return x < y && x == UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x > y && x == INT_MIN --> false */
return x > y && x == INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x < y && x == INT_MAX --> false */
return x < y && x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
/* { dg-final { scan-tree-dump-not " < " "optimized" } } */

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x <= y && x == 0 --> x == 0 */
return x <= y && x == 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x >= y && x == UINT_MAX --> x == UINT_MAX */
return x >= y && x == UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x <= y && x == INT_MIN --> x == INT_MIN */
return x <= y && x == INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x >= y && x == INT_MAX --> x == INT_MAX */
return x >= y && x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
#include <limits.h>
_Bool and1(unsigned x, unsigned y)
{
/* x <= y && x == 0 --> x == 0 */
return x <= y && x == 0;
}
_Bool and2(unsigned x, unsigned y)
{
/* x >= y && x == UINT_MAX --> x == UINT_MAX */
return x >= y && x == UINT_MAX;
}
_Bool and3(signed x, signed y)
{
/* x <= y && x == INT_MIN --> x == INT_MIN */
return x <= y && x == INT_MIN;
}
_Bool and4(signed x, signed y)
{
/* x >= y && x == INT_MAX --> x == INT_MAX */
return x >= y && x == INT_MAX;
}
/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x > y || x != 0 --> x != 0 */
return x > y || x != 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x < y || x != UINT_MAX --> x != UINT_MAX */
return x < y || x != UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x > y || x != INT_MIN --> x != INT_MIN */
return x > y || x != INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x < y || x != INT_MAX --> x != INT_MAX */
return x < y || x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x > y || x != 0 --> x != 0 */
return x > y || x != 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x < y || x != UINT_MAX --> x != UINT_MAX */
return x < y || x != UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x > y || x != INT_MIN --> x != INT_MIN */
return x > y || x != INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x < y || x != INT_MAX --> x != INT_MAX */
return x < y || x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
/* { dg-final { scan-tree-dump-not " < " "optimized" } } */

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
#include <limits.h>
_Bool or1(unsigned x, unsigned y)
{
/* x <= y || x != 0 --> true */
return x <= y || x != 0;
}
_Bool or2(unsigned x, unsigned y)
{
/* x >= y || x != UINT_MAX --> true */
return x >= y || x != UINT_MAX;
}
_Bool or3(signed x, signed y)
{
/* x <= y || x != INT_MIN --> true */
return x <= y || x != INT_MIN;
}
_Bool or4(signed x, signed y)
{
/* x >= y || x != INT_MAX --> true */
return x >= y || x != INT_MAX;
}
/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */