MATCH: Extend min_value/max_value to pointer types

Since we already had the infrastructure to optimize
`(x == 0) && (x > y)` to false for integer types,
this extends the same to pointer types as indirectly
requested by PR 96695.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

	PR tree-optimization/96695
	* match.pd (min_value, max_value): Extend to
	pointer types too.

gcc/testsuite/ChangeLog:

	PR tree-optimization/96695
	* gcc.dg/pr96695-1.c: New test.
	* gcc.dg/pr96695-10.c: New test.
	* gcc.dg/pr96695-11.c: New test.
	* gcc.dg/pr96695-12.c: New test.
	* gcc.dg/pr96695-2.c: New test.
	* gcc.dg/pr96695-3.c: New test.
	* gcc.dg/pr96695-4.c: New test.
	* gcc.dg/pr96695-5.c: New test.
	* gcc.dg/pr96695-6.c: New test.
	* gcc.dg/pr96695-7.c: New test.
	* gcc.dg/pr96695-8.c: New test.
	* gcc.dg/pr96695-9.c: New test.
This commit is contained in:
Andrew Pinski 2023-08-05 09:23:26 -07:00
parent 2a0b19f525
commit 58f1e185ff
13 changed files with 234 additions and 2 deletions

View file

@ -2733,12 +2733,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(match min_value
INTEGER_CST
(if (INTEGRAL_TYPE_P (type)
(if ((INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P(type))
&& wi::eq_p (wi::to_wide (t), wi::min_value (type)))))
(match max_value
INTEGER_CST
(if (INTEGRAL_TYPE_P (type)
(if ((INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P(type))
&& wi::eq_p (wi::to_wide (t), wi::max_value (type)))))
/* x > y && x != XXX_MIN --> x > y

View file

@ -0,0 +1,18 @@
/* { 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 != -1 --> x < y */
return x < y && x != (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */

View file

@ -0,0 +1,20 @@
/* { 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 != -1 --> true */
return x >= y || x != (unsigned*)-1;
}
/* { 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,18 @@
/* { 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 == -1 --> x >= y */
return x >= y || x == (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */

View file

@ -0,0 +1,18 @@
/* { 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 == -1 --> x >= y */
return x >= y || x == (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " == " "dce3" } } */

View file

@ -0,0 +1,18 @@
/* { 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 != -1 --> x < y */
return x < y && x != (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " != " "optimized" } } */

View file

@ -0,0 +1,20 @@
/* { 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 == -1 --> false */
return x < y && x == (unsigned*)-1;
}
/* { 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,21 @@
/* { 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 == -1 --> false */
return x < y && x == (unsigned*)-1;
}
/* { 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,19 @@
/* { 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 == -1 --> x == -1 */
return x >= y && x == (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */

View file

@ -0,0 +1,20 @@
/* { 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 == -1 --> x == -1 */
return x >= y && x == (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */

View file

@ -0,0 +1,19 @@
/* { 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 != -1 --> x != -1 */
return x < y || x != (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */

View file

@ -0,0 +1,19 @@
/* { 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 != -1 --> x != -1 */
return x < y || x != (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
/* { dg-final { scan-tree-dump-not " < " "optimized" } } */

View file

@ -0,0 +1,20 @@
/* { 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 != -1 --> true */
return x >= y || x != (unsigned*)-1;
}
/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */