public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Li Jia He <helijia@linux.ibm.com>
To: Richard Biener <rguenther@suse.de>, Andrew Pinski <pinskia@gmail.com>
Cc: Jeff Law <law@redhat.com>, GCC Patches <gcc-patches@gcc.gnu.org>,
	       Segher Boessenkool <segher@kernel.crashing.org>,
	       wschmidt@linux.ibm.com
Subject: Re: [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned
Date: Tue, 02 Jul 2019 07:41:00 -0000	[thread overview]
Message-ID: <bc69c05f-d966-cab7-b79f-a188523f9258@linux.ibm.com> (raw)
In-Reply-To: <alpine.LSU.2.20.1907010920230.10704@zhemvz.fhfr.qr>

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



On 2019/7/1 3:30 PM, Richard Biener wrote:
> On Fri, 28 Jun 2019, Andrew Pinski wrote:
> 
>> On Thu, Jun 27, 2019 at 9:55 PM Li Jia He <helijia@linux.ibm.com> wrote:
>>>
>>>
>>>
>>> On 2019/6/27 11:48 PM, Jeff Law wrote:
>>>> On 6/27/19 12:11 AM, Li Jia He wrote:
>>>>> 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-06-27  Li Jia He  <helijia@linux.ibm.com>
>>>>>           Qi Feng  <ffengqi@linux.ibm.com>
>>>>>
>>>>>       PR middle-end/88784
>>>>>       * gimple-fold.c (and_comparisons_contain_equal_operands): New function.
>>>>>       (and_comparisons_1): Use and_comparisons_contain_equal_operands.
>>>>>       (or_comparisons_contain_equal_operands): New function.
>>>>>       (or_comparisons_1): Use or_comparisons_contain_equal_operands.
>>>> Would this be better done via match.pd?  ISTM this transformation would
>>>> be well suited for that framework.
>>>
>>> Hi, Jeff
>>>
>>> I did this because of the following test case:
>>> `
>>> _Bool comp(unsigned x, unsigned y)
>>> {
>>>     return x > y && x != 0;
>>> }
>>> `
>>> The gimple file dumped on the power platform is:
>>> `
>>> comp (unsigned int x, unsigned int y)
>>> {
>>>     _Bool D.2837;
>>>     int iftmp.0;
>>>
>>>     if (x > y) goto <D.2841>; else goto <D.2839>;
>>>     <D.2841>:
>>>     if (x != 0) goto <D.2842>; else goto <D.2839>;
>>>     <D.2842>:
>>>     iftmp.0 = 1;
>>>     goto <D.2840>;
>>>     <D.2839>:
>>>     iftmp.0 = 0;
>>>     <D.2840>:
>>>     D.2837 = (_Bool) iftmp.0;
>>>     return D.2837;
>>> }
>>> `
>>> However, the gimple file dumped on x86 is
>>> `
>>> comp (unsigned int x, unsigned int y)
>>> {
>>>     _Bool D.2837;
>>>
>>>     _1 = x > y;
>>>     _2 = x != 0;
>>>     _3 = _1 & _2;
>>>     _4 = (int) _3;
>>>     D.2837 = (_Bool) _4;
>>>     return D.2837;
>>> }
>>> `
>>>
>>> The reason for the inconsistency between these two behaviors is param
>>> logical-op-non-short-circuit.  If we add the pattern to the match.pd
>>> file, we can only optimize the situation in which the statement is in
>>> the same basic block (logical-op-non-short-circuit=1, x86).  But for
>>> a cross-basic block (logical-op-non-short-circuit=0, power), match.pd
>>> can't handle this situation.
>>>
>>> Another reason is that I found out maybe_fold_and_comparisons and
>>> maybe_fold_or_comparisons are not only called by ifcombine pass but
>>> also by reassoc pass. Using this method can basically unify param
>>> logical-op-non-short-circuit=0 or 1.
>>
>>
>> As mentioned before ifcombine pass should be using gimple-match
>> instead of fold_build.  Try converting ifcombine over to gimple-match
>> infrastructure and add these to match.pd.
> 
> Yes, I mentioned that in the PR.  The issue is that at the moment
> to combine x > y with x <= y you'd have to build GENERIC trees
> for both or temporary GIMPLE assign with a SSA def (and then feed
> that into the GENERIC or GIMPLE match.pd path).

Hi,

I did some experimentation using ‘temporary GIMPLE with a SSA def (and 
then feed that into the GIMPLE match.pd path’.  Could we consider the 
code in the attachment(I did a test and the code took effect)?

Thanks,
Lijia He

> 
> maybe_fold_and/or_comparisons handle two exploded binary expressions
> while the current match.pd entries handle at most one exploded one
> (the outermost then, either AND or OR).  But it would be definitely
> doable to auto-generate maybe_fold_and/or_comparisons from match.pd
> patterns which is what I'd ultimatively suggest to do (in some more
> generalized form maybe).  Either with a separate genmatch invocation
> or as part of the --gimple processing (not sure what is more feasible
> here).
> 
> I told Li Jia He that I don't expect him to do this work.
> 
> Note I didn't review the actual patch yet.
> 
> Thanks,
> Richard.
> 

[-- Attachment #2: match.diff --]
[-- Type: text/plain, Size: 5980 bytes --]

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index dfb31a02078..9974b491626 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5789,6 +5789,12 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
   return NULL_TREE;
 }
 
+static tree
+do_valueize (tree t)
+{
+  return t;
+}
+
 /* Try to simplify the AND of two comparisons, specified by
    (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
    If this can be simplified to a single expression (without requiring
@@ -5800,11 +5806,39 @@ tree
 maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
 			    enum tree_code code2, tree op2a, tree op2b)
 {
-  tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b);
+  tree t1 = fold_build2 (code1, boolean_type_node, op1a, op1b);
+  tree t2 = fold_build2 (code2, boolean_type_node, op2a, op2b);
+
+  tree new_lhs1 = make_ssa_name (TREE_TYPE (t1));
+  tree new_lhs2 = make_ssa_name (TREE_TYPE (t2));
+
+  gassign *gassign1 = gimple_build_assign (new_lhs1, t1);
+  gassign *gassign2 = gimple_build_assign (new_lhs2, t2);
+
+  tree t = gimple_simplify (TRUTH_AND_EXPR, boolean_type_node,
+			    gimple_assign_lhs (gassign1),
+			    gimple_assign_lhs (gassign2), NULL, do_valueize);
+
+  if (!t)
+    {
+      t = gimple_simplify (TRUTH_AND_EXPR, boolean_type_node,
+			   gimple_assign_lhs (gassign2),
+			   gimple_assign_lhs (gassign1), NULL, do_valueize);
+    }
+
   if (t)
-    return t;
-  else
-    return and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b);
+    {
+      gimple *def = SSA_NAME_DEF_STMT (t);
+
+      if (!is_gimple_assign (def)
+	  || TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
+	return NULL_TREE;
+
+      return fold_build2 (gimple_assign_rhs_code (def), boolean_type_node,
+			  gimple_assign_rhs1 (def), gimple_assign_rhs2 (def));
+    }
+
+  return NULL_TREE;
 }
 
 /* Helper function for or_comparisons_1:  try to simplify the OR of the
diff --git a/gcc/match.pd b/gcc/match.pd
index f8e35e96d22..21a147d0ff1 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1859,6 +1859,101 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     { wide_int_to_tree (type, (wi::to_wide (@1)
 			       & (bitpos / BITS_PER_UNIT))); }))))
 
+/* 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; })))
+
+/* x <=  y  &&  x == XXX_MIN  -->  x == XXX_MIN  */
+(for and (truth_and bit_and)
+ (simplify
+  (and:c (le:c @0 @1) (eq@3 @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_MAX  -->  x < y  */
+(for and (truth_and bit_and)
+ (simplify
+  (and:c (lt: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::max_value (TREE_TYPE (@2)))))
+    @3)))
+
+/* x <  y  &&  x == XXX_MAX  -->  false  */
+(for and (truth_and bit_and)
+ (simplify
+  (and:c (lt: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::max_value (TREE_TYPE (@2)))))
+    { boolean_false_node; })))
+
+/* x >=  y  &&  x == XXX_MAX  -->  x == XXX_MAX  */
+(for and (truth_and bit_and)
+ (simplify
+  (and:c (ge:c @0 @1) (eq@3 @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::max_value (TREE_TYPE (@2)))))
+    @3)))
+
+/* x >  y  ||  x != XXX_MIN   -->  x != XXX_MIN  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (gt:c @0 @1) (ne@3 @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   -->  true  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (le:c @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))))
+    { boolean_true_node; })))
+
+/* x <=  y  ||  x == XXX_MIN   -->  x <= y  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (le:c@3 @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))))
+    @3)))
+
+/* x <  y  ||  x != XXX_MAX   -->  x != XXX_MAX  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (lt:c @0 @1) (ne@3 @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::max_value (TREE_TYPE (@2))))
+    @3)))
+
+/* x >=  y  ||  x != XXX_MAX   -->  true  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (ge:c @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::max_value (TREE_TYPE (@2))))
+    { boolean_true_node; })))
+
+/* x >=  y  ||  x == XXX_MAX   -->  x >= y  */
+(for or (truth_or bit_ior)
+ (simplify
+  (or:c (ge:c@3 @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::max_value (TREE_TYPE (@2))))
+    @3)))
 
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))

  reply	other threads:[~2019-07-02  7:41 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-27  6:12 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 [this message]
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

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=bc69c05f-d966-cab7-b79f-a188523f9258@linux.ibm.com \
    --to=helijia@linux.ibm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=law@redhat.com \
    --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).