> -----Original Message-----
> From: Hu, Lin1
> Sent: Tuesday, September 3, 2024 2:05 PM
> To: Jakub Jelinek <ja...@redhat.com>; Andrew Pinski <pins...@gmail.com>;
> Liu, Hongtao <hongtao....@intel.com>
> Cc: Jiang, Haochen <haochen.ji...@intel.com>; Richard Biener
> <rguent...@suse.de>; gcc-patches@gcc.gnu.org; ubiz...@gmail.com
> Subject: RE: [PATCH 2/8] i386: Optimize ordered and nonequal
> 
> > -----Original Message-----
> > From: Jakub Jelinek <ja...@redhat.com>
> > Sent: Tuesday, September 3, 2024 2:56 AM
> > To: Andrew Pinski <pins...@gmail.com>
> > Cc: Jiang, Haochen <haochen.ji...@intel.com>; Richard Biener
> > <rguent...@suse.de>; gcc-patches@gcc.gnu.org; Liu, Hongtao
> > <hongtao....@intel.com>; ubiz...@gmail.com; Hu, Lin1
> > <lin1...@intel.com>
> > Subject: Re: [PATCH 2/8] i386: Optimize ordered and nonequal
> >
> > On Mon, Sep 02, 2024 at 11:25:36AM -0700, Andrew Pinski wrote:
> > > On Mon, Sep 2, 2024 at 11:20 AM Jakub Jelinek <ja...@redhat.com> wrote:
> > > >
> > > > On Mon, Aug 26, 2024 at 02:42:31PM +0800, Haochen Jiang wrote:
> > > > >       * match.pd: Optimize (and ordered non-equal) to
> > > > >       (not (or unordered  equal))
> > > > >
> > > > > gcc/testsuite/ChangeLog:
> > > > >
> > > > >       * gcc.target/i386/optimize_one.c: New test.
> > > >
> > > > The testcase FAILs on i686-linux, because it uses -mfpmath=sse
> > > > without enabling -msse2.
> > > >
> > > > I've committed the following fix as obvious to fix that.
> > > >
> > > > > --- a/gcc/match.pd
> > > > > +++ b/gcc/match.pd
> > > > > @@ -6636,6 +6636,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > > > >   (ltgt @0 @0)
> > > > >   (if (!flag_trapping_math || !tree_expr_maybe_nan_p (@0))
> > > > >    { constant_boolean_node (false, type); }))
> > > > > +(simplify
> > > > > + (bit_and (ordered @0 @1) (ne @0 @1))  (bit_not (uneq @0 @1)))
> > > >
> > > > I wonder whether there shouldn't be some :c (e.g. on bit_and and
> > > > maybe ne too), because ordered is commutative and so is ne and so
> > > > is bit_and, and perhaps you want to match also (bit_and (ne @0 @1)
> > > > (ordered @1 @0)) etc.  What about negation of this (bit_ior
> > > > (unordered @0
> > @1) (eq @0 @1))?
> > >
> > > The :c is needed for bit_and for sure. BUT should not needed for
> > > ordered/ne though because the canonicalization of the operations
> > > should have the operands in the same order as `a ordered b` is the
> > > same as `b ordered a`.
> >
> > Maybe.  Also, isn't (bit_not (uneq @0 @1)) (ltgt @0 @1) ?
> >
> >     Jakub
> 
> I add some tests like:
>   6 int is_ordered_and_nonequal_sh_1 (float a, float b)
>   7 {
>   8   return !__builtin_isunordered (a, b) && (a != b);
>   9 }
>  10
>  11 int is_ordered_and_nonequal_sh_2 (float a, float b)
>  12 {
>  13   return !__builtin_isunordered (a, b) && (b != a);
>  14 }
>  15
>  16 int is_ordered_and_nonequal_sh_3 (float a, float b)
>  17 {
>  18   return (b != a) && !__builtin_isunordered (a, b);
>  19 }
>  20
>  21 int is_ordered_and_nonequal_sh_4 (float a, float b)
>  22 {
>  23   return !__builtin_isunordered (a, b) && !(a == b);
>  24 }
>  25
>  26 int is_ordered_and_nonequal_sh_5 (float a, float b)
>  27 {
>  28   return !__builtin_isunordered (a, b) && !(b == a);
>  29 }
>  30
>  31 int is_ordered_and_nonequal_sh_6 (float a, float b)
>  32 {
>  33   return !(b == a) && !__builtin_isunordered (a, b);
>  34 }
>  35
>  36 int is_unordered_or_equal_sh_1 (float a, float b)
>  37 {
>  38   return __builtin_isunordered (a, b) || (a == b);
>  39 }
>  40
>  41 int is_unordered_or_equal_sh_2 (float a, float b)
>  42 {
>  43   return __builtin_isunordered (a, b) || (b == a);
>  44 }
>  45
>  46 int is_unordered_or_equal_sh_3 (float a, float b)
>  47 {
>  48   return (a == b) || __builtin_isunordered (b, a);
>  49 }
>  50
>  51 int is_ordered_and_ltgt_sh_1 (float a, float b)
>  52 {
>  53   return !__builtin_isunordered (a, b) && ((a < b) || (a > b));
>  54 }
>  55
>  56 int is_ordered_and_ltgt_sh_2 (float a, float b)
>  57 {
>  58   return !__builtin_isunordered (a, b) && ((b > a) || (a > b));
>  59 }
>  60
>  61 int is_ordered_and_ltgt_sh_3 (float a, float b)
>  62 {
>  63   return ((b > a) || (a > b)) && !__builtin_isunordered (a, b);
>  64 }
> 
> From the result, I get some conclusions or quesitions:
> 1. We need to add :c to bit_and.
> 2. We need to add (ltgt @0 @1).
> But, in 006t.gimple !__builtin_isunordered (a, b) && ((b > a) || (a > b)) 
> will be
> 126
> 127   if (a ord b) goto <D.2813>; else goto <D.2811>;
> 128   <D.2813>:
> 129   if (b <> a) goto <D.2814>; else goto <D.2811>;
> 130   <D.2814>:
> 131   iftmp.1 = 1;
> GCC don't use bit_and like other testcases, looks like I can't just add a 
> simplify in
> match.pd, do you have any idea to solve this question in the frontend (maybe
> frontend)?
> 3. After add these testcases, I consider to change the testcase's name to opt-
> ucomi-1.c.

I made some mistakes for the previous comments. Some of the tests are not 
directly related to what we are discussing. I've written a patch like this
diff --git a/gcc/match.pd b/gcc/match.pd
index 4298e89dad6..621306213e4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6652,8 +6652,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!flag_trapping_math || !tree_expr_maybe_nan_p (@0))
   { constant_boolean_node (false, type); }))
 (simplify
- (bit_and (ordered @0 @1) (ne @0 @1))
- (bit_not (uneq @0 @1)))
+ (bit_and:c (ordered @0 @1) (ne @0 @1))
+ (ltgt @0 @1))

 /* x == ~x -> false */
 /* x != ~x -> true */
diff --git a/gcc/testsuite/gcc.target/i386/opt-comi-1.c 
b/gcc/testsuite/gcc.target/i386/opt-comi-1.c
new file mode 100644
index 00000000000..fc7b8632004
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/opt-comi-1.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfpmath=sse -msse2" } */
+/* { dg-final { scan-assembler-times "comiss" 9 } } */
+/* { dg-final { scan-assembler-times "set" 9 } } */
+
+int is_ordered_and_nonequal_sh_1 (float a, float b)
+{
+  return !__builtin_isunordered (a, b) && (a != b);
+}
+
+int is_ordered_and_nonequal_sh_2 (float a, float b)
+{
+  return !__builtin_isunordered (a, b) && (b != a);
+}
+
+int is_ordered_and_nonequal_sh_3 (float a, float b)
+{
+  return (b != a) && !__builtin_isunordered (a, b);
+}
+
+int is_ordered_and_nonequal_sh_4 (float a, float b)
+{
+  return !__builtin_isunordered (a, b) && !(a == b);
+}
+
+int is_ordered_and_nonequal_sh_5 (float a, float b)
+{
+  return !__builtin_isunordered (a, b) && !(b == a);
+}
+
+int is_ordered_and_nonequal_sh_6 (float a, float b)
+{
+  return !(b == a) && !__builtin_isunordered (a, b);
+}
+
+int is_ordered_or_nonequal_sh_7 (float a, float b)
+{
+  return !(__builtin_isunordered (a, b) || (a == b));
+}
+
+int is_ordered_or_nonequal_sh_8 (float a, float b)
+{
+  return !(__builtin_isunordered (a, b) || (b == a));
+}
will send it out after I test it out. 

Reply via email to