Commit c16504f6 by Li Jia He Committed by Martin Liska

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
parent 5f487a34
2019-09-16 Li Jia He <helijia@linux.ibm.com> 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> Martin Liska <mliska@suse.cz>
* gimple-fold.c (and_comparisons_1): Add type as first * gimple-fold.c (and_comparisons_1): Add type as first
......
...@@ -1883,6 +1883,80 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1883,6 +1883,80 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ wide_int_to_tree (type, (wi::to_wide (@1) { wide_int_to_tree (type, (wi::to_wide (@1)
& (bitpos / BITS_PER_UNIT))); })))) & (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. */ /* We can't reassociate at all for saturating types. */
(if (!TYPE_SATURATING (type)) (if (!TYPE_SATURATING (type))
...@@ -5425,10 +5499,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -5425,10 +5499,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
on c, so could drop potentially-trapping arithmetic, but that's a valid on c, so could drop potentially-trapping arithmetic, but that's a valid
simplification if the result of the operation isn't needed. simplification if the result of the operation isn't needed.
Avoid speculatively generating a stand-alone vector comparison Avoid speculatively generating a stand-alone vector comparison
on targets that might not support them. Any target implementing on targets that might not support them. Any target implementing
conditional internal functions must support the same comparisons conditional internal functions must support the same comparisons
inside and outside a VEC_COND_EXPR. */ inside and outside a VEC_COND_EXPR. */
#if GIMPLE #if GIMPLE
(for uncond_op (UNCOND_BINARY) (for uncond_op (UNCOND_BINARY)
......
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> 2019-09-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/91756 PR tree-optimization/91756
......
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment