public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Martin Liška" <mliska@suse.cz>
To: Richard Biener <rguenther@suse.de>
Cc: Li Jia He <helijia@linux.ibm.com>,
	Andrew Pinski <pinskia@gmail.com>, Jeff Law <law@redhat.com>,
	GCC Patches <gcc-patches@gcc.gnu.org>,
	Segher Boessenkool <segher@kernel.crashing.org>,
	wschmidt@linux.ibm.com, Martin Liska <mliska@suse.de>
Subject: Re: [PATCH 2/2] Fix PR88784, middle end is missing some optimizations about unsigned
Date: Wed, 11 Sep 2019 13:56:00 -0000	[thread overview]
Message-ID: <3f38240a-60a2-9594-7608-c1b69aa7e63c@suse.cz> (raw)
In-Reply-To: <nycvar.YFH.7.76.1909111505070.5566@zhemvz.fhfr.qr>

[-- Attachment #1: Type: text/plain, Size: 3695 bytes --]

On 9/11/19 3:08 PM, Richard Biener wrote:
> On Fri, 6 Sep 2019, Martin Liška wrote:
> 
>> On 9/5/19 3:17 PM, Richard Biener wrote:
>>> On Tue, 16 Jul 2019, Li Jia He wrote:
>>>
>>>> Hi,
>>>>
>>>>   I made some changes based on the recommendations. Would you like to
>>>>   help me to see it again ? Sorry, it took so long time to provide the
>>>>   patch.
>>>>
>>>>   Note: 1. I keep the code for and_comparisons_1 and or_comparisons_1.
>>>> 	The reason is that I did not found a good way to handle the
>>>> 	optimization of '((x CODE1 y) AND (x CODE2 y))' in match.pd.
>>>> 	Maybe I missing some important information about match.pd.
>>>> 	2. The gimple_resimplify2 function is not used.  Since stmt1,
>>>> 	stmt2, lhs1 and lhs2 are allocated on the stack, Is there a
>>>> 	question with the value on the stack as the return value ?
>>>> 	I may have misunderstood Richard's intention.
>>>
>>> And now for the match.pd patch.
>>>
>>> +/* x >  y  &&  x != XXX_MIN  -->  x > y  */
>>> +(for and (truth_and bit_and)
>>> + (simplify
>>> +  (and:c (gt:c@3 @0 @1) (ne @0 INTEGER_CST@2))
>>> +  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P 
>>> (TREE_TYPE(@1))
>>> +       && (wi::eq_p (wi::to_wide (@2), wi::min_value (TREE_TYPE (@2)))))
>>> +    @3)))
>>> +
>>> +/* x >  y  &&  x == XXX_MIN  -->  false  */
>>> +(for and (truth_and bit_and)
>>> + (simplify
>>> +  (and:c (gt:c @0 @1) (eq @0 INTEGER_CST@2))
>>> +  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P 
>>> (TREE_TYPE(@1))
>>> +       && (wi::eq_p (wi::to_wide (@2), wi::min_value (TREE_TYPE (@2)))))
>>> +    { boolean_false_node; })))
>>>
>>> you could merge those two via
>>>
>>>  (for eqne (eq ne)
>>>   (for and (....
>>>    (simplify
>>>     (and:c (gt:c @0 @1) (eqne @0 INTEGER_CST@2))
>>>     (if (...)
>>>      (switch
>>>       (if (eqne == NE_EXPR)
>>>        @3)
>>>       (if (eqne == EQ_EXPR)
>>>        { constant_boolean_node (false, type); }))))
>>>
>>> notice using constant_boolean_node (false, type); instead of
>>> boolean_false_node.  I suspect more unification is possible.
>>>
>>> Also you could do
>>>
>>> (match min_value
>>>  INTEGER_CST
>>>  (if (INTEGRAL_TYPE_P (type)
>>>       && wi::eq_p (wi::to_wide (t), wi::min_value (type)))))
>>>
>>> and then write
>>>
>>>  (simplify
>>>   (and:c (gt:c @0 @1) (eq @0 min_value))
>>>   (...
>>>
>>> Your
>>>
>>> (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P
>>> (TREE_TYPE(@1))
>>>
>>> is redundant, it's enough to check either @0 or @1 given they
>>> have to be compatible for the gt operation.  Note you probably
>>> want to use
>>>
>>>   (and:c (gt:c @0 @1) (eq @@0 min_value))
>>>
>>> and verify that types_match (@1, @0) because when @0 are a constant
>>> (and (eq @0 min_value) is not folded which can happen) then they
>>> might have different types and thus you could have
>>> (SHORT_MAX > intvar) && (SHORT_MAX == SHORT_MAX)
>>>
>>> That said, the patterns can be quite a bit simplified I think.
>>>
>>> Richard.
>>>
>>
>> Likewise, I applied the suggested simplification.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
> 
> +/* { dg-options "-O2 -fdump-tree-ifcombine --param 
> logical-op-non-short-circuit=0" } */
> +
> +#include <limits.h>
> +
> +_Bool and1(unsigned x, unsigned y)
> +{
> +  /* x > y && x != 0 --> x > y */
> +  return x > y && x != 0;
> +}
> ...
> +/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */
> 
> since you iterate over bit_and and truth_and GENERIC folding should
> already simplify this, no?
> 
> I suggest to remove the truth_and/or iteration.

Done in updated patch.

Martin

> 
> Otherwise looks OK now.
> 
> Richard.
> 


[-- Attachment #2: 0002-Fix-PR88784-middle-end-is-missing-some-optimizations.patch --]
[-- Type: text/x-patch, Size: 18329 bytes --]

From acb5e62c2babf749b60c5475925ac6afb059e459 Mon Sep 17 00:00:00 2001
From: Li Jia He <helijia@linux.ibm.com>
Date: Mon, 15 Jul 2019 03:50:34 -0500
Subject: [PATCH 2/5] Fix PR88784, middle end is missing some optimizations
 about unsigned

Hi,

According to the optimizable case described by Qi Feng on
issue 88784, we can combine the cases into the following:

1. x >  y  &&  x != XXX_MIN  -->   x > y
2. x >  y  &&  x == XXX_MIN  -->   false
3. x <= y  &&  x == XXX_MIN  -->   x == XXX_MIN

4. x <  y  &&  x != XXX_MAX  -->   x < y
5. x <  y  &&  x == XXX_MAX  -->   false
6. x >= y  &&  x == XXX_MAX  -->   x == XXX_MAX

7. x >  y  ||  x != XXX_MIN  -->   x != XXX_MIN
8. x <= y  ||  x != XXX_MIN  -->   true
9. x <= y  ||  x == XXX_MIN  -->   x <= y

10. x <  y  ||  x != XXX_MAX  -->   x != UXXX_MAX
11. x >= y  ||  x != XXX_MAX  -->   true
12. x >= y  ||  x == XXX_MAX  -->   x >= y

Note: XXX_MIN represents the minimum value of type x.
      XXX_MAX represents the maximum value of type x.

Here we don't need to care about whether the operation is
signed or unsigned.  For example, in the below equation:

'x >  y  &&  x != XXX_MIN  -->   x > y'

If the x type is signed int and XXX_MIN is INT_MIN, we can
optimize it to 'x > y'.  However, if the type of x is unsigned
int and XXX_MIN is 0, we can still optimize it to 'x > y'.

The regression testing for the patch was done on GCC mainline on

    powerpc64le-unknown-linux-gnu (Power 9 LE)

with no regressions.  Is it OK for trunk ?

Thanks,
Lijia He

gcc/ChangeLog

2019-07-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'.

gcc/testsuite/ChangeLog

2019-07-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.
---
 gcc/match.pd                      | 82 +++++++++++++++++++++++++++++--
 gcc/testsuite/gcc.dg/pr88784-1.c  | 30 +++++++++++
 gcc/testsuite/gcc.dg/pr88784-10.c | 32 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-11.c | 30 +++++++++++
 gcc/testsuite/gcc.dg/pr88784-12.c | 30 +++++++++++
 gcc/testsuite/gcc.dg/pr88784-2.c  | 30 +++++++++++
 gcc/testsuite/gcc.dg/pr88784-3.c  | 32 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-4.c  | 32 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-5.c  | 31 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-6.c  | 31 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-7.c  | 31 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-8.c  | 31 ++++++++++++
 gcc/testsuite/gcc.dg/pr88784-9.c  | 32 ++++++++++++
 13 files changed, 450 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-1.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-10.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-11.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-12.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-3.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-4.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-5.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-6.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-7.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-8.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-9.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 5690cf3d349..2ca88000cad 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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)
diff --git a/gcc/testsuite/gcc.dg/pr88784-1.c b/gcc/testsuite/gcc.dg/pr88784-1.c
new file mode 100644
index 00000000000..b8daae0b330
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-1.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-10.c b/gcc/testsuite/gcc.dg/pr88784-10.c
new file mode 100644
index 00000000000..958d7656556
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-10.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-11.c b/gcc/testsuite/gcc.dg/pr88784-11.c
new file mode 100644
index 00000000000..c4b05082443
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-11.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-12.c b/gcc/testsuite/gcc.dg/pr88784-12.c
new file mode 100644
index 00000000000..5b60b3883f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-12.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-2.c b/gcc/testsuite/gcc.dg/pr88784-2.c
new file mode 100644
index 00000000000..ed360018b0f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-2.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-3.c b/gcc/testsuite/gcc.dg/pr88784-3.c
new file mode 100644
index 00000000000..8c48e1b8943
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-3.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-4.c b/gcc/testsuite/gcc.dg/pr88784-4.c
new file mode 100644
index 00000000000..a9aa74cb9c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-4.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-5.c b/gcc/testsuite/gcc.dg/pr88784-5.c
new file mode 100644
index 00000000000..b147abbcfaf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-5.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-6.c b/gcc/testsuite/gcc.dg/pr88784-6.c
new file mode 100644
index 00000000000..6d5bd7b0c74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-6.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-7.c b/gcc/testsuite/gcc.dg/pr88784-7.c
new file mode 100644
index 00000000000..6577ff9e14d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-7.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-8.c b/gcc/testsuite/gcc.dg/pr88784-8.c
new file mode 100644
index 00000000000..6bb56a91561
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-8.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-9.c b/gcc/testsuite/gcc.dg/pr88784-9.c
new file mode 100644
index 00000000000..27e3281c555
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-9.c
@@ -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" } } */
-- 
2.23.0


      reply	other threads:[~2019-09-11 13:56 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-27  6:12 [PATCH][middle-end/88784] Middle " Li Jia He
2019-06-27 15:48 ` Jeff Law
2019-06-28  4:55   ` Li Jia He
2019-06-28 17:02     ` Andrew Pinski
2019-07-01  7:31       ` Richard Biener
2019-07-02  7:41         ` Li Jia He
2019-07-02  8:09           ` Richard Biener
2019-07-02  8:51             ` Richard Biener
2019-07-16  6:54               ` Li Jia He
2019-08-30 11:16                 ` Martin Liška
2019-09-05 13:01                 ` Richard Biener
2019-09-05 18:47                   ` Martin Liška
2019-09-06  8:01                     ` Richard Biener
2019-09-06  8:04                       ` Martin Liška
2019-09-06 10:13                   ` [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd Martin Liška
2019-09-09 12:23                     ` Martin Liška
2019-09-09 13:10                       ` Richard Biener
2019-09-09 13:40                         ` Martin Liška
2019-09-09 13:42                           ` Richard Biener
2019-09-09 13:45                             ` Martin Liška
2019-09-09 13:55                               ` Richard Biener
2019-09-10  7:40                                 ` Martin Liška
     [not found]                                   ` <ba4ec7b3-0d0d-ca7b-b2d9-2f34478a23f4@linux.ibm.com>
2019-09-11  8:51                                     ` Martin Liška
2019-09-11 11:16                                   ` Martin Liška
2019-09-11 12:23                                     ` Richard Biener
2019-09-11 13:55                                       ` Martin Liška
2019-09-09 13:10                       ` Marc Glisse
2019-09-09 13:30                         ` Martin Liška
2019-09-09 13:39                           ` Richard Biener
2019-09-09 12:24                     ` [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd Martin Liška
2019-09-11 11:19                       ` Martin Liška
2019-09-11 13:57                         ` Martin Liška
2019-09-16  9:05                           ` Richard Biener
2019-09-09 12:24                     ` [PATCH 3/5] Rewrite part of and_comparisons_1 " Martin Liška
2019-09-09 13:41                       ` Martin Liška
2019-09-10  7:41                         ` Martin Liška
2019-09-10 11:19                           ` Marc Glisse
2019-09-11  8:27                             ` Martin Liška
2019-09-11 11:18                               ` Martin Liška
2019-09-11 12:44                                 ` Richard Biener
2019-09-11 13:19                                   ` Martin Liška
2019-09-11 13:57                                     ` Martin Liška
2019-09-16  9:04                                       ` Richard Biener
2019-09-16 13:47                                         ` Martin Liška
2019-09-10  8:52                         ` Bernhard Reutner-Fischer
2019-09-11  8:11                           ` Martin Liška
2019-09-09 12:25                     ` [PATCH 5/5] Rewrite second part of or_comparisons_1 " Martin Liška
2019-09-11 11:19                       ` Martin Liška
2019-09-11 13:57                         ` Martin Liška
2019-09-16  9:07                           ` Richard Biener
2019-09-16 14:23                             ` Martin Liška
2019-09-05 13:17                 ` [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned Richard Biener
2019-09-05 18:47                   ` Martin Liška
2019-09-06 10:14                   ` [PATCH 2/2] Fix PR88784, middle " Martin Liška
2019-09-11 13:08                     ` Richard Biener
2019-09-11 13:56                       ` Martin Liška [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3f38240a-60a2-9594-7608-c1b69aa7e63c@suse.cz \
    --to=mliska@suse.cz \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=helijia@linux.ibm.com \
    --cc=law@redhat.com \
    --cc=mliska@suse.de \
    --cc=pinskia@gmail.com \
    --cc=rguenther@suse.de \
    --cc=segher@kernel.crashing.org \
    --cc=wschmidt@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).