public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
@ 2021-11-01  6:48 HAO CHEN GUI
  2021-11-02  0:21 ` David Edelsohn
  0 siblings, 1 reply; 29+ messages in thread
From: HAO CHEN GUI @ 2021-11-01  6:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool, David, Bill Schmidt

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

Hi,

  This patch disables gimple folding for VSX_BUILTIN_XVMINDP, VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP when fast-math is not set.  With the gimple folding is enabled, the four built-ins will be implemented by c-type instructions - xs[min|max]cdp on P9 and P10 if they can be converted to scalar comparisons.  While they are implemented by xv[min|max][s|d]p on P8 and P7 as P8 and P7 don't have corresponding scalar comparison instructions.  The patch binds these four built-ins to xv[min|max][s|d]p when fast-math is not set. The two new test cases illustrate it. 

  ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP are not implemented by vminfp or vmaxfp.

rs6000-builtin.def:BU_ALTIVEC_2 (VMAXFP,              "vmaxfp",         CONST, smaxv4sf3)

rs6000-builtin.def:BU_ALTIVEC_2 (VMINFP,              "vminfp",         CONST, sminv4sf3)

Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.


ChangeLog

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
        * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
        gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
        VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
        set.

gcc/testsuite/
        * gcc.target/powerpc/vec-minmax-1.c: New test.
        * gcc.target/powerpc/vec-minmax-2.c: Likewise.


patch.diff

diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 369 bytes --]

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
	gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
	VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
	set.

gcc/testsuite/
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

[-- Attachment #3: patch.diff.txt --]
[-- Type: text/plain, Size: 3240 bytes --]

diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-11-01  6:48 [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set HAO CHEN GUI
@ 2021-11-02  0:21 ` David Edelsohn
  2021-11-02  2:40   ` HAO CHEN GUI
  0 siblings, 1 reply; 29+ messages in thread
From: David Edelsohn @ 2021-11-02  0:21 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, Segher Boessenkool, Bill Schmidt

Hi, Hao

Neither the inlined patch nor the attached patch seem to contain the
change to rs6000-call.c.  I only see the new testcases.

Please resend the complete patch.

Thanks David

On Mon, Nov 1, 2021 at 2:48 AM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>
> Hi,
>
>   This patch disables gimple folding for VSX_BUILTIN_XVMINDP, VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP when fast-math is not set.  With the gimple folding is enabled, the four built-ins will be implemented by c-type instructions - xs[min|max]cdp on P9 and P10 if they can be converted to scalar comparisons.  While they are implemented by xv[min|max][s|d]p on P8 and P7 as P8 and P7 don't have corresponding scalar comparison instructions.  The patch binds these four built-ins to xv[min|max][s|d]p when fast-math is not set. The two new test cases illustrate it.
>
>   ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP are not implemented by vminfp or vmaxfp.
>
> rs6000-builtin.def:BU_ALTIVEC_2 (VMAXFP,              "vmaxfp",         CONST, smaxv4sf3)
>
> rs6000-builtin.def:BU_ALTIVEC_2 (VMINFP,              "vminfp",         CONST, sminv4sf3)
>
> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>
>
> ChangeLog
>
> 2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>
>
> gcc/
>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
>         gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
>         set.
>
> gcc/testsuite/
>         * gcc.target/powerpc/vec-minmax-1.c: New test.
>         * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>
>
> patch.diff
>
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> new file mode 100644
> index 00000000000..e238659c9be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> @@ -0,0 +1,52 @@
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> +
> +/* This test verifies that float or double vec_min/max are bound to
> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> new file mode 100644
> index 00000000000..149275d8709
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> @@ -0,0 +1,50 @@
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> +
> +/* This test verifies that float or double vec_min/max can be converted
> +   to scalar comparison when fast-math is set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-11-02  0:21 ` David Edelsohn
@ 2021-11-02  2:40   ` HAO CHEN GUI
  2021-11-02 13:12     ` David Edelsohn
  0 siblings, 1 reply; 29+ messages in thread
From: HAO CHEN GUI @ 2021-11-02  2:40 UTC (permalink / raw)
  To: David Edelsohn; +Cc: gcc-patches, Segher Boessenkool, Bill Schmidt

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

David,

    My patch file was broken. I am sorry for it.  Here is the correct one. Thanks a lot.

ChangeLog

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
        * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
        gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
        VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
        set.

gcc/testsuite/
        * gcc.target/powerpc/vec-minmax-1.c: New test.
        * gcc.target/powerpc/vec-minmax-2.c: Likewise.


patch.diff

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 7d485480225..a8e193a0089 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12333,6 +12333,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type))
+         return false;
+       gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12341,7 +12349,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12351,6 +12358,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type))
+         return false;
+       gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12359,7 +12374,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}


 

On 2/11/2021 上午 8:21, David Edelsohn wrote:
> Hi, Hao
>
> Neither the inlined patch nor the attached patch seem to contain the
> change to rs6000-call.c.  I only see the new testcases.
>
> Please resend the complete patch.
>
> Thanks David
>
> On Mon, Nov 1, 2021 at 2:48 AM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>> Hi,
>>
>>   This patch disables gimple folding for VSX_BUILTIN_XVMINDP, VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP when fast-math is not set.  With the gimple folding is enabled, the four built-ins will be implemented by c-type instructions - xs[min|max]cdp on P9 and P10 if they can be converted to scalar comparisons.  While they are implemented by xv[min|max][s|d]p on P8 and P7 as P8 and P7 don't have corresponding scalar comparison instructions.  The patch binds these four built-ins to xv[min|max][s|d]p when fast-math is not set. The two new test cases illustrate it.
>>
>>   ALTIVEC_BUILTIN_VMINFP and  ALTIVEC_BUILTIN_VMAXFP are not implemented by vminfp or vmaxfp.
>>
>> rs6000-builtin.def:BU_ALTIVEC_2 (VMAXFP,              "vmaxfp",         CONST, smaxv4sf3)
>>
>> rs6000-builtin.def:BU_ALTIVEC_2 (VMINFP,              "vminfp",         CONST, sminv4sf3)
>>
>> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>>
>>
>> ChangeLog
>>
>> 2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
>>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
>>         gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
>>         set.
>>
>> gcc/testsuite/
>>         * gcc.target/powerpc/vec-minmax-1.c: New test.
>>         * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>
>>
>> patch.diff
>>
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> new file mode 100644
>> index 00000000000..e238659c9be
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> @@ -0,0 +1,52 @@
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>> +
>> +/* This test verifies that float or double vec_min/max are bound to
>> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> new file mode 100644
>> index 00000000000..149275d8709
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> @@ -0,0 +1,50 @@
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>> +
>> +/* This test verifies that float or double vec_min/max can be converted
>> +   to scalar comparison when fast-math is set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}

[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 369 bytes --]

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
	gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
	VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
	set.

gcc/testsuite/
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

[-- Attachment #3: patch.diff.txt --]
[-- Type: text/plain, Size: 4975 bytes --]

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 7d485480225..a8e193a0089 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12333,6 +12333,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12341,7 +12349,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12351,6 +12358,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12359,7 +12374,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-11-02  2:40   ` HAO CHEN GUI
@ 2021-11-02 13:12     ` David Edelsohn
  2021-11-03  2:14       ` HAO CHEN GUI
  0 siblings, 1 reply; 29+ messages in thread
From: David Edelsohn @ 2021-11-02 13:12 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, Segher Boessenkool, Bill Schmidt

On Mon, Nov 1, 2021 at 10:40 PM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>
> David,
>
>     My patch file was broken. I am sorry for it.  Here is the correct one. Thanks a lot.
>
> ChangeLog
>
> 2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>
>
> gcc/
>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
>         gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
>         set.
>
> gcc/testsuite/
>         * gcc.target/powerpc/vec-minmax-1.c: New test.
>         * gcc.target/powerpc/vec-minmax-2.c: Likewise.

This is okay.

The default DejaGNU test action is compile, but it's a good idea to
include the dg-do line to be clear and document the intention.

Thanks, David

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-11-02 13:12     ` David Edelsohn
@ 2021-11-03  2:14       ` HAO CHEN GUI
  0 siblings, 0 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-11-03  2:14 UTC (permalink / raw)
  To: David Edelsohn; +Cc: gcc-patches, Segher Boessenkool, Bill Schmidt

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

David,

  Thanks for your comments. I refined it according to your advice.

ChangeLog

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
        * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
        gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
        VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
        set.

gcc/testsuite/
        * gcc.target/powerpc/vec-minmax-1.c: New test.
        * gcc.target/powerpc/vec-minmax-2.c: Likewise.


patch.diff

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 7d485480225..a8e193a0089 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12333,6 +12333,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type))
+         return false;
+       gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12341,7 +12349,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12351,6 +12358,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type))
+         return false;
+       gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12359,7 +12374,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..3f6e3760075
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..b27bebba846
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}



On 2/11/2021 下午 9:12, David Edelsohn wrote:
> On Mon, Nov 1, 2021 at 10:40 PM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>> David,
>>
>>     My patch file was broken. I am sorry for it.  Here is the correct one. Thanks a lot.
>>
>> ChangeLog
>>
>> 2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
>>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
>>         gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
>>         set.
>>
>> gcc/testsuite/
>>         * gcc.target/powerpc/vec-minmax-1.c: New test.
>>         * gcc.target/powerpc/vec-minmax-2.c: Likewise.
> This is okay.
>
> The default DejaGNU test action is compile, but it's a good idea to
> include the dg-do line to be clear and document the intention.
>
> Thanks, David

[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 369 bytes --]

2021-11-01 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Disable
	gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
	VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
	set.

gcc/testsuite/
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

[-- Attachment #3: patch.diff.txt --]
[-- Type: text/plain, Size: 5025 bytes --]

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 7d485480225..a8e193a0089 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12333,6 +12333,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12341,7 +12349,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12351,6 +12358,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12359,7 +12374,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..3f6e3760075
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..b27bebba846
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-20 16:19 ` Segher Boessenkool
@ 2021-10-21  6:25   ` HAO CHEN GUI
  0 siblings, 0 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-10-21  6:25 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, David, Bill Schmidt


On 21/10/2021 上午 12:19, Segher Boessenkool wrote:
> Hi!
>
> On Wed, Oct 20, 2021 at 05:04:56PM +0800, HAO CHEN GUI wrote:
>> This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
>>
>> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>>
>>   I refined the patch according to reviewers' advice. The attachments are 
>> the ChangeLog and patch diff in case the email body is messed up.
>>
>>
>> ChangeLog
>>
>> 2021-10-20 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
>>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>         Disable gimple fold for VSX_BUILTIN_XVMINDP, 
>> ALTIVEC_BUILTIN_VMINFP,
>>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math 
>> is not
>>         set.
> Content-Type: text/plain; charset=UTF-8; format=flowed
>
> Please don't use flowed.  It makes patches unreadable and unusable if
> you do (they will not apply anymore).
>
> Also, the left border should be one tab, not eight spaces, and the right
> border is at 80 chars (so there are 72 usable chars on a line).  Don't
> end a line in ":" if you don't overflow a line if you put text after it.
I found the settings of the format in my client configuration. Thanks for reminder.
>> --- a/gcc/config/rs6000/rs6000-call.c
>> +++ b/gcc/config/rs6000/rs6000-call.c
>> @@ -12159,6 +12159,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
>> *gsi)
>>        return true;
>>      /* flavors of vec_min.  */
>>      case VSX_BUILTIN_XVMINDP:
>> +    case ALTIVEC_BUILTIN_VMINFP:
>> +      {
>> +       lhs = gimple_call_lhs (stmt);
>> +       tree type = TREE_TYPE (lhs);
>> +       if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
>> +         return false;
>> +       gcc_fallthrough ();
>> +      }
> Both vminfp anf xvmindp (and xvminsp and xsmindp) return -0 or the
> minimum of +0 and -0, that is okay even with HONOR_SIGNED_ZEROS, I
> think?
Yes, the HONOR_SIGNED_ZEROS is unnecessary.
> x[sv]min[sd]p returns the number for the minimum of a NaN and a number,
> but vminfp returns a NaN.  Do you really want to make the xvmindp
> builtin handle less than it does currently?  And, what about vminfp?
> Did tht do the wrong thing before?
x[sv]min[sd]p meets the requirement of IEEE std 754-2008 while xsmincdp doesn't. This patch prevents the builtin to be converted to xsmincdp. 

If the two elements in the vectors are the same, the vector comparison is optimized to scalar comparison.
MAX_EXPR <va_3, vb_5>
at vector low pass,
MAX_EXPR <a_2(D), b_4(D)>

On P9, the scalar comparison is implemented by xs[min|max]cdp.It doesn't conform with IEEE std 754-2008.
The puzzle here is that both x[sv]min[sd]p and xs[min|max]cdp doesn't conform the latest IEEE standard 754-2019 which says "return a quiet NaN if either operand is a NaN". 


The builtin would never be implemented by vminfp, I think.

Gui Haochen

>
> There are no tests for any of that apparently.  Hrm.
>
>
> Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-20  9:04 HAO CHEN GUI
@ 2021-10-20 16:19 ` Segher Boessenkool
  2021-10-21  6:25   ` HAO CHEN GUI
  0 siblings, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-20 16:19 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, David, Bill Schmidt

Hi!

On Wed, Oct 20, 2021 at 05:04:56PM +0800, HAO CHEN GUI wrote:
> This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
> 
> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
> 
>   I refined the patch according to reviewers' advice. The attachments are 
> the ChangeLog and patch diff in case the email body is messed up.
> 
> 
> ChangeLog
> 
> 2021-10-20 Haochen Gui <guihaoc@linux.ibm.com>
> 
> gcc/
>         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>         Disable gimple fold for VSX_BUILTIN_XVMINDP, 
> ALTIVEC_BUILTIN_VMINFP,
>         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math 
> is not
>         set.

Content-Type: text/plain; charset=UTF-8; format=flowed

Please don't use flowed.  It makes patches unreadable and unusable if
you do (they will not apply anymore).

Also, the left border should be one tab, not eight spaces, and the right
border is at 80 chars (so there are 72 usable chars on a line).  Don't
end a line in ":" if you don't overflow a line if you put text after it.

> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
> *gsi)
>        return true;
>      /* flavors of vec_min.  */
>      case VSX_BUILTIN_XVMINDP:
> +    case ALTIVEC_BUILTIN_VMINFP:
> +      {
> +       lhs = gimple_call_lhs (stmt);
> +       tree type = TREE_TYPE (lhs);
> +       if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
> +         return false;
> +       gcc_fallthrough ();
> +      }

Both vminfp anf xvmindp (and xvminsp and xsmindp) return -0 or the
minimum of +0 and -0, that is okay even with HONOR_SIGNED_ZEROS, I
think?

x[sv]min[sd]p returns the number for the minimum of a NaN and a number,
but vminfp returns a NaN.  Do you really want to make the xvmindp
builtin handle less than it does currently?  And, what about vminfp?
Did tht do the wrong thing before?

There are no tests for any of that apparently.  Hrm.


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
@ 2021-10-20  9:04 HAO CHEN GUI
  2021-10-20 16:19 ` Segher Boessenkool
  0 siblings, 1 reply; 29+ messages in thread
From: HAO CHEN GUI @ 2021-10-20  9:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool, David, Bill Schmidt

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

Hi,

This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.

Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.

   I refined the patch according to reviewers' advice. The attachments are the ChangeLog and patch diff in case the email body is messed up.


ChangeLog

2021-10-20 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
         Disable gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
         set.

gcc/testsuite/
         * gcc.target/powerpc/vec-minmax-1.c: New test.
         * gcc.target/powerpc/vec-minmax-2.c: Likewise.


patch.diff

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..51c7ba447c3 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_min.  */
      case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
+         return false;
+       gcc_fallthrough ();
+      }
      case P8V_BUILTIN_VMINSD:
      case P8V_BUILTIN_VMINUD:
      case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12175,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
      case ALTIVEC_BUILTIN_VMINUB:
      case ALTIVEC_BUILTIN_VMINUH:
      case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12184,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_max.  */
      case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+       lhs = gimple_call_lhs (stmt);
+       tree type = TREE_TYPE (lhs);
+       if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
+         return false;
+       gcc_fallthrough ();
+      }
      case P8V_BUILTIN_VMAXSD:
      case P8V_BUILTIN_VMAXUD:
      case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12200,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
      case ALTIVEC_BUILTIN_VMAXUB:
      case ALTIVEC_BUILTIN_VMAXUH:
      case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}


[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 369 bytes --]

2021-10-20 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
	Disable gimple fold for VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
	VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP when fast-math is not
	set.

gcc/testsuite/
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

[-- Attachment #3: patch.diff.txt --]
[-- Type: text/plain, Size: 5033 bytes --]

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..51c7ba447c3 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12175,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12184,14 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12200,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..e238659c9be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..149275d8709
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-13  7:43   ` HAO CHEN GUI
  2021-10-13  8:29     ` Richard Biener
@ 2021-10-13 22:04     ` Joseph Myers
  1 sibling, 0 replies; 29+ messages in thread
From: Joseph Myers @ 2021-10-13 22:04 UTC (permalink / raw)
  To: HAO CHEN GUI
  Cc: Richard Biener, Bill Schmidt, gcc-patches, Segher Boessenkool

On Wed, 13 Oct 2021, HAO CHEN GUI via Gcc-patches wrote:

>   As to IEEE behavior, do you mean "Minimum and maximum operations" defined in
> IEEE-754 2019?  If so, I think VSX/altivec min/max instructions don't conform
> with it. It demands a quite NaN if either operand is a NaN while our
> instructions don't.
> 
> IEEE-754 2019 maximum(x, y) is xif x>y, yif y>x, and a quiet NaN if either
> operand is a NaN, according to 6.2. For this operation, +0 compares greater
> than −0. Otherwise (i.e., when x=y and signs are the same) it is either xor
> y. Actions for xvmaxdp

We don't have any built-in functions (or I think other internal 
operations) for the IEEE 754-2019 operations (C2X function names fmaximum, 
fminimum, fmaximum_num, fminimum_num, plus per-type suffixes) either, 
though as I noted when adding those functions to glibc, having such 
built-in functions would make sense (specifically, so that RISC-V can 
expand calls to fmaximum_num and fminimum_num inline when building for F 
or D extension version 2.2 and later).  The built-in functions we have for 
fmax and fmin correspond to the IEEE 754-2008 operations (as implemented 
by the AArch64 fmaxnm / fminnm instructions, for example).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-12  8:57 HAO CHEN GUI
  2021-10-12  9:57 ` Richard Biener
@ 2021-10-13 18:28 ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-13 18:28 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, Bill Schmidt

On Tue, Oct 12, 2021 at 04:57:43PM +0800, HAO CHEN GUI wrote:
> b/gcc/config/rs6000/rs6000-call.c
> index b4e13af4dc6..90527734ceb 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
> *gsi)
>        return true;
>      /* flavors of vec_min.  */
>      case VSX_BUILTIN_XVMINDP:
> +    case ALTIVEC_BUILTIN_VMINFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +       return false;
> +      /* Fall through to MIN_EXPR.  */
> +      gcc_fallthrough ();
>      case P8V_BUILTIN_VMINSD:
>      case P8V_BUILTIN_VMINUD:
>      case ALTIVEC_BUILTIN_VMINSB:

"Fall though to code for MIN_EXPR"?  It suggests it is a label, as
written now.  Or don't have this comment at all, maybe?

> +/* { dg-do compile { target { powerpc*-*-* } } } */

Leave out the target clause?  Testcases in gcc.target/powerpc/ are not
run when this is not satisfied anyway, testing it twice is just more
noise.


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-13  8:29     ` Richard Biener
  2021-10-13  9:15       ` HAO CHEN GUI
@ 2021-10-13 18:19       ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-13 18:19 UTC (permalink / raw)
  To: Richard Biener; +Cc: HAO CHEN GUI, gcc-patches, Bill Schmidt

On Wed, Oct 13, 2021 at 10:29:26AM +0200, Richard Biener wrote:
> On Wed, Oct 13, 2021 at 9:43 AM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
> >    As to IEEE behavior, do you mean "Minimum and maximum operations" defined in IEEE-754 2019?  If so, I think VSX/altivec min/max instructions don't conform with it. It demands a quite NaN if either operand is a NaN while our instructions don't.
> >
> > IEEE-754 2019 maximum(x, y) is xif x>y, yif y>x, and a quiet NaN if either operand is a NaN, according to 6.2. For this operation, +0 compares greater than −0. Otherwise (i.e., when x=y and signs are the same) it is either xor y. Actions for xvmaxdp
> 
> Hmm, then I do not understand the reason for the patch - people using
> the intrinsics cannot expect IEEE semantics then.
> So you are concerned that people don't get the 1:1 machine instruction
> but eventually the IEEE conforming MIN/MAX_EXPR?

I do not know about Gimple MIN_EXPR (it is not documented?), but the
RTL "smin" is meaningless in the presence of NaNs or signed zeros.  This
is documented (in rtl.texi):

"""
@findex smin
@findex smax
@cindex signed minimum
@cindex signed maximum
@item (smin:@var{m} @var{x} @var{y})
@itemx (smax:@var{m} @var{x} @var{y})
Represents the smaller (for @code{smin}) or larger (for @code{smax}) of
@var{x} and @var{y}, interpreted as signed values in mode @var{m}.
When used with floating point, if both operands are zeros, or if either
operand is @code{NaN}, then it is unspecified which of the two operands
is returned as the result.
"""

(not exactly meaningless, okay, but not usable for almost anything).

> But that can then still happen with -ffast-math so I wonder what's the point.

That :-)


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
@ 2021-10-13 15:02 David Edelsohn
  0 siblings, 0 replies; 29+ messages in thread
From: David Edelsohn @ 2021-10-13 15:02 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: GCC Patches, Segher Boessenkool, Bill Schmidt

2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
     * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
     Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
     VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.

Please write something more than "modify".  The ChangeLog should be
more like the email subject line for this patch.

gcc/testsuite/
     * gcc.target/powerpc/vec-minmax-1.c: New test.
     * gcc.target/powerpc/vec-minmax-2.c: Likewise.

Please ensure that the indentation is correct for the case statements;
it was unclear from the text pasted into the email.

Okay with those clarifications.

Thanks, David

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-13  8:29     ` Richard Biener
@ 2021-10-13  9:15       ` HAO CHEN GUI
  2021-10-13 18:19       ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-10-13  9:15 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Bill Schmidt, Segher Boessenkool


On 13/10/2021 下午 4:29, Richard Biener wrote:
> On Wed, Oct 13, 2021 at 9:43 AM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>> Richard,
>>
>>     Thanks so much for your comments.
>>
>>     As far as I know, VSX/altivec min/max instructions don't conform with C-Sytle Min/Max Macro. The fold converts it to MIN/MAX_EXPR then it has a chance to be implemented by scalar min/max instructions which conform with C-Sytle Min/Max Macro. That's why I made this patch.
>>
>>     As to IEEE behavior, do you mean "Minimum and maximum operations" defined in IEEE-754 2019?  If so, I think VSX/altivec min/max instructions don't conform with it. It demands a quite NaN if either operand is a NaN while our instructions don't.
>>
>> IEEE-754 2019 maximum(x, y) is xif x>y, yif y>x, and a quiet NaN if either operand is a NaN, according to 6.2. For this operation, +0 compares greater than −0. Otherwise (i.e., when x=y and signs are the same) it is either xor y. Actions for xvmaxdp
> Hmm, then I do not understand the reason for the patch - people using
> the intrinsics cannot expect IEEE semantics then.
> So you are concerned that people don't get the 1:1 machine instruction
> but eventually the IEEE conforming MIN/MAX_EXPR?
> But that can then still happen with -ffast-math so I wonder what's the point.
>
> Richard.

The reason for the patch is to keep compatibility between different Power servers.  The old servers don't have C-style Min/Max instructions and all are implemented by VSX/altivec min/max instructions. So I just want to keep the compatibility. For fast-math, the C-style Min/Max should be acceptable, I think.

The IEEE standard changed. VSX/altivec min/max instructions conform with IEEE 754-2008 (the old standard), but not with IEEE 754-2019 (the last one).

As of 2019, the formerly required/minNum, maxNum, minNumMag, and maxNumMag/in IEEE 754-2008 are now deleted due to their non-associativity. Instead, two sets of new/minimum and maximum operations/are recommended.

754-2008

maxNum(x, y) is the canonicalized number yif x< y, xif y< x, the canonicalized number if one
operand is a number and the other a quiet NaN. Otherwise it is either xor y, canonicalized (this
means results might differ among implementations). When either xor yis a signalingNaN, then the
result is according to 6.2.

Thanks again.

Gui Haochen

>
>> On 12/10/2021 下午 5:57, Richard Biener wrote:
>>> On Tue, Oct 12, 2021 at 10:59 AM HAO CHEN GUI via Gcc-patches
>>> <gcc-patches@gcc.gnu.org> wrote:
>>>> Hi,
>>>>
>>>>       This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
>>>>
>>>> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>>>>
>>>>       I re-send the patch as previous one is messed up in email thread. Sorry for that.
>>> If the VSX/altivec min/max instructions conform to IEEE behavior then
>>> you could instead fold
>>> to .F{MIN,MAX} internal functions and define the f{min,max} optabs.
>>>
>>> Otherwise the patch looks correct to me - MIN_EXPR and MAX_EXPR are
>>> not IEEE conforming.
>>> Note a better check would be to use HONOR_NANS/HONOR_SIGNED_ZEROS on
>>> the argument type
>>> (that also works for the integer types with the obvious answer).
>>>
>>> Richard.
>>>
>>>> ChangeLog
>>>>
>>>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>>>
>>>> gcc/
>>>>            * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>>>            Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>>>            VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>>>
>>>> gcc/testsuite/
>>>>            * gcc.target/powerpc/vec-minmax-1.c: New test.
>>>>            * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>>>
>>>>
>>>> patch.diff
>>>>
>>>> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
>>>> index b4e13af4dc6..90527734ceb 100644
>>>> --- a/gcc/config/rs6000/rs6000-call.c
>>>> +++ b/gcc/config/rs6000/rs6000-call.c
>>>> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>>>           return true;
>>>>         /* flavors of vec_min.  */
>>>>         case VSX_BUILTIN_XVMINDP:
>>>> +    case ALTIVEC_BUILTIN_VMINFP:
>>>> +      if (!flag_finite_math_only || flag_signed_zeros)
>>>> +       return false;
>>>> +      /* Fall through to MIN_EXPR.  */
>>>> +      gcc_fallthrough ();
>>>>         case P8V_BUILTIN_VMINSD:
>>>>         case P8V_BUILTIN_VMINUD:
>>>>         case ALTIVEC_BUILTIN_VMINSB:
>>>> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>>>         case ALTIVEC_BUILTIN_VMINUB:
>>>>         case ALTIVEC_BUILTIN_VMINUH:
>>>>         case ALTIVEC_BUILTIN_VMINUW:
>>>> -    case ALTIVEC_BUILTIN_VMINFP:
>>>>           arg0 = gimple_call_arg (stmt, 0);
>>>>           arg1 = gimple_call_arg (stmt, 1);
>>>>           lhs = gimple_call_lhs (stmt);
>>>> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>>>           return true;
>>>>         /* flavors of vec_max.  */
>>>>         case VSX_BUILTIN_XVMAXDP:
>>>> +    case ALTIVEC_BUILTIN_VMAXFP:
>>>> +      if (!flag_finite_math_only || flag_signed_zeros)
>>>> +       return false;
>>>> +      /* Fall through to MAX_EXPR.  */
>>>> +      gcc_fallthrough ();
>>>>         case P8V_BUILTIN_VMAXSD:
>>>>         case P8V_BUILTIN_VMAXUD:
>>>>         case ALTIVEC_BUILTIN_VMAXSB:
>>>> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>>>         case ALTIVEC_BUILTIN_VMAXUB:
>>>>         case ALTIVEC_BUILTIN_VMAXUH:
>>>>         case ALTIVEC_BUILTIN_VMAXUW:
>>>> -    case ALTIVEC_BUILTIN_VMAXFP:
>>>>           arg0 = gimple_call_arg (stmt, 0);
>>>>           arg1 = gimple_call_arg (stmt, 1);
>>>>           lhs = gimple_call_lhs (stmt);
>>>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>>> new file mode 100644
>>>> index 00000000000..547798fd65c
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>>> @@ -0,0 +1,53 @@
>>>> +/* { dg-do compile { target { powerpc*-*-* } } } */
>>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>>>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>>>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>>>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>>>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>>>> +
>>>> +/* This test verifies that float or double vec_min/max are bound to
>>>> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
>>>> +
>>>> +
>>>> +#include <altivec.h>
>>>> +
>>>> +#ifdef _BIG_ENDIAN
>>>> +   const int PREF_D = 0;
>>>> +#else
>>>> +   const int PREF_D = 1;
>>>> +#endif
>>>> +
>>>> +double vmaxd (double a, double b)
>>>> +{
>>>> +  vector double va = vec_promote (a, PREF_D);
>>>> +  vector double vb = vec_promote (b, PREF_D);
>>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>>> +}
>>>> +
>>>> +double vmind (double a, double b)
>>>> +{
>>>> +  vector double va = vec_promote (a, PREF_D);
>>>> +  vector double vb = vec_promote (b, PREF_D);
>>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>>> +}
>>>> +
>>>> +#ifdef _BIG_ENDIAN
>>>> +   const int PREF_F = 0;
>>>> +#else
>>>> +   const int PREF_F = 3;
>>>> +#endif
>>>> +
>>>> +float vmaxf (float a, float b)
>>>> +{
>>>> +  vector float va = vec_promote (a, PREF_F);
>>>> +  vector float vb = vec_promote (b, PREF_F);
>>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>>> +}
>>>> +
>>>> +float vminf (float a, float b)
>>>> +{
>>>> +  vector float va = vec_promote (a, PREF_F);
>>>> +  vector float vb = vec_promote (b, PREF_F);
>>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>>> +}
>>>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>>> new file mode 100644
>>>> index 00000000000..4c6f4365830
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>>> @@ -0,0 +1,51 @@
>>>> +/* { dg-do compile { target { powerpc*-*-* } } } */
>>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>>>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>>>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>>>> +
>>>> +/* This test verifies that float or double vec_min/max can be converted
>>>> +   to scalar comparison when fast-math is set.  */
>>>> +
>>>> +
>>>> +#include <altivec.h>
>>>> +
>>>> +#ifdef _BIG_ENDIAN
>>>> +   const int PREF_D = 0;
>>>> +#else
>>>> +   const int PREF_D = 1;
>>>> +#endif
>>>> +
>>>> +double vmaxd (double a, double b)
>>>> +{
>>>> +  vector double va = vec_promote (a, PREF_D);
>>>> +  vector double vb = vec_promote (b, PREF_D);
>>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>>> +}
>>>> +
>>>> +double vmind (double a, double b)
>>>> +{
>>>> +  vector double va = vec_promote (a, PREF_D);
>>>> +  vector double vb = vec_promote (b, PREF_D);
>>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>>> +}
>>>> +
>>>> +#ifdef _BIG_ENDIAN
>>>> +   const int PREF_F = 0;
>>>> +#else
>>>> +   const int PREF_F = 3;
>>>> +#endif
>>>> +
>>>> +float vmaxf (float a, float b)
>>>> +{
>>>> +  vector float va = vec_promote (a, PREF_F);
>>>> +  vector float vb = vec_promote (b, PREF_F);
>>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>>> +}
>>>> +
>>>> +float vminf (float a, float b)
>>>> +{
>>>> +  vector float va = vec_promote (a, PREF_F);
>>>> +  vector float vb = vec_promote (b, PREF_F);
>>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>>> +}
>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-13  7:43   ` HAO CHEN GUI
@ 2021-10-13  8:29     ` Richard Biener
  2021-10-13  9:15       ` HAO CHEN GUI
  2021-10-13 18:19       ` Segher Boessenkool
  2021-10-13 22:04     ` Joseph Myers
  1 sibling, 2 replies; 29+ messages in thread
From: Richard Biener @ 2021-10-13  8:29 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, Bill Schmidt, Segher Boessenkool

On Wed, Oct 13, 2021 at 9:43 AM HAO CHEN GUI <guihaoc@linux.ibm.com> wrote:
>
> Richard,
>
>    Thanks so much for your comments.
>
>    As far as I know, VSX/altivec min/max instructions don't conform with C-Sytle Min/Max Macro. The fold converts it to MIN/MAX_EXPR then it has a chance to be implemented by scalar min/max instructions which conform with C-Sytle Min/Max Macro. That's why I made this patch.
>
>    As to IEEE behavior, do you mean "Minimum and maximum operations" defined in IEEE-754 2019?  If so, I think VSX/altivec min/max instructions don't conform with it. It demands a quite NaN if either operand is a NaN while our instructions don't.
>
> IEEE-754 2019 maximum(x, y) is xif x>y, yif y>x, and a quiet NaN if either operand is a NaN, according to 6.2. For this operation, +0 compares greater than −0. Otherwise (i.e., when x=y and signs are the same) it is either xor y. Actions for xvmaxdp

Hmm, then I do not understand the reason for the patch - people using
the intrinsics cannot expect IEEE semantics then.
So you are concerned that people don't get the 1:1 machine instruction
but eventually the IEEE conforming MIN/MAX_EXPR?
But that can then still happen with -ffast-math so I wonder what's the point.

Richard.

> On 12/10/2021 下午 5:57, Richard Biener wrote:
> > On Tue, Oct 12, 2021 at 10:59 AM HAO CHEN GUI via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> >> Hi,
> >>
> >>      This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
> >>
> >> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
> >>
> >>      I re-send the patch as previous one is messed up in email thread. Sorry for that.
> > If the VSX/altivec min/max instructions conform to IEEE behavior then
> > you could instead fold
> > to .F{MIN,MAX} internal functions and define the f{min,max} optabs.
> >
> > Otherwise the patch looks correct to me - MIN_EXPR and MAX_EXPR are
> > not IEEE conforming.
> > Note a better check would be to use HONOR_NANS/HONOR_SIGNED_ZEROS on
> > the argument type
> > (that also works for the integer types with the obvious answer).
> >
> > Richard.
> >
> >> ChangeLog
> >>
> >> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
> >>
> >> gcc/
> >>           * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
> >>           Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
> >>           VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
> >>
> >> gcc/testsuite/
> >>           * gcc.target/powerpc/vec-minmax-1.c: New test.
> >>           * gcc.target/powerpc/vec-minmax-2.c: Likewise.
> >>
> >>
> >> patch.diff
> >>
> >> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
> >> index b4e13af4dc6..90527734ceb 100644
> >> --- a/gcc/config/rs6000/rs6000-call.c
> >> +++ b/gcc/config/rs6000/rs6000-call.c
> >> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> >>          return true;
> >>        /* flavors of vec_min.  */
> >>        case VSX_BUILTIN_XVMINDP:
> >> +    case ALTIVEC_BUILTIN_VMINFP:
> >> +      if (!flag_finite_math_only || flag_signed_zeros)
> >> +       return false;
> >> +      /* Fall through to MIN_EXPR.  */
> >> +      gcc_fallthrough ();
> >>        case P8V_BUILTIN_VMINSD:
> >>        case P8V_BUILTIN_VMINUD:
> >>        case ALTIVEC_BUILTIN_VMINSB:
> >> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> >>        case ALTIVEC_BUILTIN_VMINUB:
> >>        case ALTIVEC_BUILTIN_VMINUH:
> >>        case ALTIVEC_BUILTIN_VMINUW:
> >> -    case ALTIVEC_BUILTIN_VMINFP:
> >>          arg0 = gimple_call_arg (stmt, 0);
> >>          arg1 = gimple_call_arg (stmt, 1);
> >>          lhs = gimple_call_lhs (stmt);
> >> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> >>          return true;
> >>        /* flavors of vec_max.  */
> >>        case VSX_BUILTIN_XVMAXDP:
> >> +    case ALTIVEC_BUILTIN_VMAXFP:
> >> +      if (!flag_finite_math_only || flag_signed_zeros)
> >> +       return false;
> >> +      /* Fall through to MAX_EXPR.  */
> >> +      gcc_fallthrough ();
> >>        case P8V_BUILTIN_VMAXSD:
> >>        case P8V_BUILTIN_VMAXUD:
> >>        case ALTIVEC_BUILTIN_VMAXSB:
> >> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> >>        case ALTIVEC_BUILTIN_VMAXUB:
> >>        case ALTIVEC_BUILTIN_VMAXUH:
> >>        case ALTIVEC_BUILTIN_VMAXUW:
> >> -    case ALTIVEC_BUILTIN_VMAXFP:
> >>          arg0 = gimple_call_arg (stmt, 0);
> >>          arg1 = gimple_call_arg (stmt, 1);
> >>          lhs = gimple_call_lhs (stmt);
> >> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> >> new file mode 100644
> >> index 00000000000..547798fd65c
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> >> @@ -0,0 +1,53 @@
> >> +/* { dg-do compile { target { powerpc*-*-* } } } */
> >> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> >> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> >> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> >> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> >> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> >> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> >> +
> >> +/* This test verifies that float or double vec_min/max are bound to
> >> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> >> +
> >> +
> >> +#include <altivec.h>
> >> +
> >> +#ifdef _BIG_ENDIAN
> >> +   const int PREF_D = 0;
> >> +#else
> >> +   const int PREF_D = 1;
> >> +#endif
> >> +
> >> +double vmaxd (double a, double b)
> >> +{
> >> +  vector double va = vec_promote (a, PREF_D);
> >> +  vector double vb = vec_promote (b, PREF_D);
> >> +  return vec_extract (vec_max (va, vb), PREF_D);
> >> +}
> >> +
> >> +double vmind (double a, double b)
> >> +{
> >> +  vector double va = vec_promote (a, PREF_D);
> >> +  vector double vb = vec_promote (b, PREF_D);
> >> +  return vec_extract (vec_min (va, vb), PREF_D);
> >> +}
> >> +
> >> +#ifdef _BIG_ENDIAN
> >> +   const int PREF_F = 0;
> >> +#else
> >> +   const int PREF_F = 3;
> >> +#endif
> >> +
> >> +float vmaxf (float a, float b)
> >> +{
> >> +  vector float va = vec_promote (a, PREF_F);
> >> +  vector float vb = vec_promote (b, PREF_F);
> >> +  return vec_extract (vec_max (va, vb), PREF_F);
> >> +}
> >> +
> >> +float vminf (float a, float b)
> >> +{
> >> +  vector float va = vec_promote (a, PREF_F);
> >> +  vector float vb = vec_promote (b, PREF_F);
> >> +  return vec_extract (vec_min (va, vb), PREF_F);
> >> +}
> >> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> >> new file mode 100644
> >> index 00000000000..4c6f4365830
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> >> @@ -0,0 +1,51 @@
> >> +/* { dg-do compile { target { powerpc*-*-* } } } */
> >> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> >> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> >> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> >> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> >> +
> >> +/* This test verifies that float or double vec_min/max can be converted
> >> +   to scalar comparison when fast-math is set.  */
> >> +
> >> +
> >> +#include <altivec.h>
> >> +
> >> +#ifdef _BIG_ENDIAN
> >> +   const int PREF_D = 0;
> >> +#else
> >> +   const int PREF_D = 1;
> >> +#endif
> >> +
> >> +double vmaxd (double a, double b)
> >> +{
> >> +  vector double va = vec_promote (a, PREF_D);
> >> +  vector double vb = vec_promote (b, PREF_D);
> >> +  return vec_extract (vec_max (va, vb), PREF_D);
> >> +}
> >> +
> >> +double vmind (double a, double b)
> >> +{
> >> +  vector double va = vec_promote (a, PREF_D);
> >> +  vector double vb = vec_promote (b, PREF_D);
> >> +  return vec_extract (vec_min (va, vb), PREF_D);
> >> +}
> >> +
> >> +#ifdef _BIG_ENDIAN
> >> +   const int PREF_F = 0;
> >> +#else
> >> +   const int PREF_F = 3;
> >> +#endif
> >> +
> >> +float vmaxf (float a, float b)
> >> +{
> >> +  vector float va = vec_promote (a, PREF_F);
> >> +  vector float vb = vec_promote (b, PREF_F);
> >> +  return vec_extract (vec_max (va, vb), PREF_F);
> >> +}
> >> +
> >> +float vminf (float a, float b)
> >> +{
> >> +  vector float va = vec_promote (a, PREF_F);
> >> +  vector float vb = vec_promote (b, PREF_F);
> >> +  return vec_extract (vec_min (va, vb), PREF_F);
> >> +}
> >>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-12  9:57 ` Richard Biener
@ 2021-10-13  7:43   ` HAO CHEN GUI
  2021-10-13  8:29     ` Richard Biener
  2021-10-13 22:04     ` Joseph Myers
  0 siblings, 2 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-10-13  7:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Bill Schmidt, Segher Boessenkool

Richard,

   Thanks so much for your comments.

   As far as I know, VSX/altivec min/max instructions don't conform with C-Sytle Min/Max Macro. The fold converts it to MIN/MAX_EXPR then it has a chance to be implemented by scalar min/max instructions which conform with C-Sytle Min/Max Macro. That's why I made this patch.

   As to IEEE behavior, do you mean "Minimum and maximum operations" defined in IEEE-754 2019?  If so, I think VSX/altivec min/max instructions don't conform with it. It demands a quite NaN if either operand is a NaN while our instructions don't.

IEEE-754 2019 maximum(x, y) is xif x>y, yif y>x, and a quiet NaN if either operand is a NaN, according to 6.2. For this operation, +0 compares greater than −0. Otherwise (i.e., when x=y and signs are the same) it is either xor y. Actions for xvmaxdp

On 12/10/2021 下午 5:57, Richard Biener wrote:
> On Tue, Oct 12, 2021 at 10:59 AM HAO CHEN GUI via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>> Hi,
>>
>>      This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
>>
>> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>>
>>      I re-send the patch as previous one is messed up in email thread. Sorry for that.
> If the VSX/altivec min/max instructions conform to IEEE behavior then
> you could instead fold
> to .F{MIN,MAX} internal functions and define the f{min,max} optabs.
>
> Otherwise the patch looks correct to me - MIN_EXPR and MAX_EXPR are
> not IEEE conforming.
> Note a better check would be to use HONOR_NANS/HONOR_SIGNED_ZEROS on
> the argument type
> (that also works for the integer types with the obvious answer).
>
> Richard.
>
>> ChangeLog
>>
>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
>>           * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>           Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>           VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>
>> gcc/testsuite/
>>           * gcc.target/powerpc/vec-minmax-1.c: New test.
>>           * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>
>>
>> patch.diff
>>
>> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
>> index b4e13af4dc6..90527734ceb 100644
>> --- a/gcc/config/rs6000/rs6000-call.c
>> +++ b/gcc/config/rs6000/rs6000-call.c
>> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>          return true;
>>        /* flavors of vec_min.  */
>>        case VSX_BUILTIN_XVMINDP:
>> +    case ALTIVEC_BUILTIN_VMINFP:
>> +      if (!flag_finite_math_only || flag_signed_zeros)
>> +       return false;
>> +      /* Fall through to MIN_EXPR.  */
>> +      gcc_fallthrough ();
>>        case P8V_BUILTIN_VMINSD:
>>        case P8V_BUILTIN_VMINUD:
>>        case ALTIVEC_BUILTIN_VMINSB:
>> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>        case ALTIVEC_BUILTIN_VMINUB:
>>        case ALTIVEC_BUILTIN_VMINUH:
>>        case ALTIVEC_BUILTIN_VMINUW:
>> -    case ALTIVEC_BUILTIN_VMINFP:
>>          arg0 = gimple_call_arg (stmt, 0);
>>          arg1 = gimple_call_arg (stmt, 1);
>>          lhs = gimple_call_lhs (stmt);
>> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>          return true;
>>        /* flavors of vec_max.  */
>>        case VSX_BUILTIN_XVMAXDP:
>> +    case ALTIVEC_BUILTIN_VMAXFP:
>> +      if (!flag_finite_math_only || flag_signed_zeros)
>> +       return false;
>> +      /* Fall through to MAX_EXPR.  */
>> +      gcc_fallthrough ();
>>        case P8V_BUILTIN_VMAXSD:
>>        case P8V_BUILTIN_VMAXUD:
>>        case ALTIVEC_BUILTIN_VMAXSB:
>> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>>        case ALTIVEC_BUILTIN_VMAXUB:
>>        case ALTIVEC_BUILTIN_VMAXUH:
>>        case ALTIVEC_BUILTIN_VMAXUW:
>> -    case ALTIVEC_BUILTIN_VMAXFP:
>>          arg0 = gimple_call_arg (stmt, 0);
>>          arg1 = gimple_call_arg (stmt, 1);
>>          lhs = gimple_call_lhs (stmt);
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> new file mode 100644
>> index 00000000000..547798fd65c
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> @@ -0,0 +1,53 @@
>> +/* { dg-do compile { target { powerpc*-*-* } } } */
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>> +
>> +/* This test verifies that float or double vec_min/max are bound to
>> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> new file mode 100644
>> index 00000000000..4c6f4365830
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> @@ -0,0 +1,51 @@
>> +/* { dg-do compile { target { powerpc*-*-* } } } */
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>> +
>> +/* This test verifies that float or double vec_min/max can be converted
>> +   to scalar comparison when fast-math is set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-12  8:57 HAO CHEN GUI
@ 2021-10-12  9:57 ` Richard Biener
  2021-10-13  7:43   ` HAO CHEN GUI
  2021-10-13 18:28 ` Segher Boessenkool
  1 sibling, 1 reply; 29+ messages in thread
From: Richard Biener @ 2021-10-12  9:57 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, Bill Schmidt, Segher Boessenkool

On Tue, Oct 12, 2021 at 10:59 AM HAO CHEN GUI via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi,
>
>     This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.
>
> Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.
>
>     I re-send the patch as previous one is messed up in email thread. Sorry for that.

If the VSX/altivec min/max instructions conform to IEEE behavior then
you could instead fold
to .F{MIN,MAX} internal functions and define the f{min,max} optabs.

Otherwise the patch looks correct to me - MIN_EXPR and MAX_EXPR are
not IEEE conforming.
Note a better check would be to use HONOR_NANS/HONOR_SIGNED_ZEROS on
the argument type
(that also works for the integer types with the obvious answer).

Richard.

> ChangeLog
>
> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>
> gcc/
>          * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>          Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>          VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>
> gcc/testsuite/
>          * gcc.target/powerpc/vec-minmax-1.c: New test.
>          * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>
>
> patch.diff
>
> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
> index b4e13af4dc6..90527734ceb 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>         return true;
>       /* flavors of vec_min.  */
>       case VSX_BUILTIN_XVMINDP:
> +    case ALTIVEC_BUILTIN_VMINFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +       return false;
> +      /* Fall through to MIN_EXPR.  */
> +      gcc_fallthrough ();
>       case P8V_BUILTIN_VMINSD:
>       case P8V_BUILTIN_VMINUD:
>       case ALTIVEC_BUILTIN_VMINSB:
> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>       case ALTIVEC_BUILTIN_VMINUB:
>       case ALTIVEC_BUILTIN_VMINUH:
>       case ALTIVEC_BUILTIN_VMINUW:
> -    case ALTIVEC_BUILTIN_VMINFP:
>         arg0 = gimple_call_arg (stmt, 0);
>         arg1 = gimple_call_arg (stmt, 1);
>         lhs = gimple_call_lhs (stmt);
> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>         return true;
>       /* flavors of vec_max.  */
>       case VSX_BUILTIN_XVMAXDP:
> +    case ALTIVEC_BUILTIN_VMAXFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +       return false;
> +      /* Fall through to MAX_EXPR.  */
> +      gcc_fallthrough ();
>       case P8V_BUILTIN_VMAXSD:
>       case P8V_BUILTIN_VMAXUD:
>       case ALTIVEC_BUILTIN_VMAXSB:
> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
>       case ALTIVEC_BUILTIN_VMAXUB:
>       case ALTIVEC_BUILTIN_VMAXUH:
>       case ALTIVEC_BUILTIN_VMAXUW:
> -    case ALTIVEC_BUILTIN_VMAXFP:
>         arg0 = gimple_call_arg (stmt, 0);
>         arg1 = gimple_call_arg (stmt, 1);
>         lhs = gimple_call_lhs (stmt);
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> new file mode 100644
> index 00000000000..547798fd65c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile { target { powerpc*-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> +
> +/* This test verifies that float or double vec_min/max are bound to
> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> new file mode 100644
> index 00000000000..4c6f4365830
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> @@ -0,0 +1,51 @@
> +/* { dg-do compile { target { powerpc*-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> +
> +/* This test verifies that float or double vec_min/max can be converted
> +   to scalar comparison when fast-math is set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
@ 2021-10-12  8:57 HAO CHEN GUI
  2021-10-12  9:57 ` Richard Biener
  2021-10-13 18:28 ` Segher Boessenkool
  0 siblings, 2 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-10-12  8:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool, Bill Schmidt

Hi,

    This patch disables gimple folding for float or double vec_min/max when fast-math is not set. It makes vec_min/max conform with the guide.

Bootstrapped and tested on powerpc64le-linux with no regressions. Is this okay for trunk? Any recommendations? Thanks a lot.

    I re-send the patch as previous one is messed up in email thread. Sorry for that.

ChangeLog

2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
         * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
         Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
         VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.

gcc/testsuite/
         * gcc.target/powerpc/vec-minmax-1.c: New test.
         * gcc.target/powerpc/vec-minmax-2.c: Likewise.


patch.diff

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..90527734ceb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_min.  */
      case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+       return false;
+      /* Fall through to MIN_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMINSD:
      case P8V_BUILTIN_VMINUD:
      case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
      case ALTIVEC_BUILTIN_VMINUB:
      case ALTIVEC_BUILTIN_VMINUH:
      case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_max.  */
      case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+       return false;
+      /* Fall through to MAX_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMAXSD:
      case P8V_BUILTIN_VMAXUD:
      case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
      case ALTIVEC_BUILTIN_VMAXUB:
      case ALTIVEC_BUILTIN_VMAXUH:
      case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..547798fd65c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..4c6f4365830
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-10-11 15:55           ` Segher Boessenkool
@ 2021-10-11 16:07             ` Segher Boessenkool
  0 siblings, 0 replies; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-11 16:07 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, guihaoc, wschmidt

On Mon, Oct 11, 2021 at 10:55:36AM -0500, Segher Boessenkool wrote:
> On Thu, Aug 26, 2021 at 09:19:30AM +0800, HAO CHEN GUI wrote:
> > gcc/
> > ?????? * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
> > ?????? Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
> > ?????? VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
> 
> Something mangles your email, giving all those question marks.  It is
> hard to review like this.

These were non-breaking spaces (u+00a0).  Probably caused by
format=flowed, the grest destroyer of patches.


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-26  1:19         ` HAO CHEN GUI
  2021-09-06  6:01           ` HAO CHEN GUI
@ 2021-10-11 15:55           ` Segher Boessenkool
  2021-10-11 16:07             ` Segher Boessenkool
  1 sibling, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-11 15:55 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: wschmidt, gcc-patches, guihaoc

Hi!

On Thu, Aug 26, 2021 at 09:19:30AM +0800, HAO CHEN GUI wrote:
> gcc/
> ?????? * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
> ?????? Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
> ?????? VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.

Something mangles your email, giving all those question marks.  It is
hard to review like this.

Don't send patches as replies in threads please.  It is impossible to
keep track of such things.

> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin 
> (gimple_stmt_iterator *gsi)
> ???????????? return true;
> ???????? /* flavors of vec_min.?? */
> ???????? case VSX_BUILTIN_XVMINDP:
> +?????? case ALTIVEC_BUILTIN_VMINFP:
> +?????????? if (!flag_finite_math_only || flag_signed_zeros)
> +?????? return false;
> +?????????? /* Fall through to MIN_EXPR.?? */
> +?????????? gcc_fallthrough ();
> ???????? case P8V_BUILTIN_VMINSD:
> ???????? case P8V_BUILTIN_VMINUD:
> ???????? case ALTIVEC_BUILTIN_VMINSB:

Yeah I would rather not review this like this :-)


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-26  1:19         ` HAO CHEN GUI
@ 2021-09-06  6:01           ` HAO CHEN GUI
  2021-10-11 15:55           ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-09-06  6:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Bill Schmidt, Segher Boessenkool

Hi,

      Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2021-August/578162.html

Thanks

On 26/8/2021 上午 9:19, HAO CHEN GUI wrote:
> Hi Bill,
>
>    Thanks for your comments.
>
> Hi Segher,
>
>    Here is the ChangeLog and patch diff. Thanks.
>
> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>
> gcc/
>     * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>     Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>     VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>
> gcc/testsuite/
>     * gcc.target/powerpc/vec-minmax-1.c: New test.
>     * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>
> diff --git a/gcc/config/rs6000/rs6000-call.c 
> b/gcc/config/rs6000/rs6000-call.c
> index b4e13af4dc6..90527734ceb 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin 
> (gimple_stmt_iterator *gsi)
>        return true;
>      /* flavors of vec_min.  */
>      case VSX_BUILTIN_XVMINDP:
> +    case ALTIVEC_BUILTIN_VMINFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +    return false;
> +      /* Fall through to MIN_EXPR.  */
> +      gcc_fallthrough ();
>      case P8V_BUILTIN_VMINSD:
>      case P8V_BUILTIN_VMINUD:
>      case ALTIVEC_BUILTIN_VMINSB:
> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin 
> (gimple_stmt_iterator *gsi)
>      case ALTIVEC_BUILTIN_VMINUB:
>      case ALTIVEC_BUILTIN_VMINUH:
>      case ALTIVEC_BUILTIN_VMINUW:
> -    case ALTIVEC_BUILTIN_VMINFP:
>        arg0 = gimple_call_arg (stmt, 0);
>        arg1 = gimple_call_arg (stmt, 1);
>        lhs = gimple_call_lhs (stmt);
> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin 
> (gimple_stmt_iterator *gsi)
>        return true;
>      /* flavors of vec_max.  */
>      case VSX_BUILTIN_XVMAXDP:
> +    case ALTIVEC_BUILTIN_VMAXFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +    return false;
> +      /* Fall through to MAX_EXPR.  */
> +      gcc_fallthrough ();
>      case P8V_BUILTIN_VMAXSD:
>      case P8V_BUILTIN_VMAXUD:
>      case ALTIVEC_BUILTIN_VMAXSB:
> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin 
> (gimple_stmt_iterator *gsi)
>      case ALTIVEC_BUILTIN_VMAXUB:
>      case ALTIVEC_BUILTIN_VMAXUH:
>      case ALTIVEC_BUILTIN_VMAXUW:
> -    case ALTIVEC_BUILTIN_VMAXFP:
>        arg0 = gimple_call_arg (stmt, 0);
>        arg1 = gimple_call_arg (stmt, 1);
>        lhs = gimple_call_lhs (stmt);
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> new file mode 100644
> index 00000000000..547798fd65c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile { target { powerpc*-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> +
> +/* This test verifies that float or double vec_min/max are bound to
> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> new file mode 100644
> index 00000000000..4c6f4365830
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> @@ -0,0 +1,51 @@
> +/* { dg-do compile { target { powerpc*-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> +
> +/* This test verifies that float or double vec_min/max can be converted
> +   to scalar comparison when fast-math is set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
>
> On 25/8/2021 下午 8:34, Bill Schmidt wrote:
>> Hi Haochen,
>>
>> Thanks for the updates!  This looks good to me; please await Segher's 
>> response.
>>
>> Bill
>>
>> On 8/25/21 2:06 AM, HAO CHEN GUI wrote:
>>> Hi,
>>>
>>>       I refined the patch according to Bill's advice. I pasted the
>>> ChangeLog and diff file here. If it doesn't work, please let me know.
>>> Thanks.
>>>
>>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>>
>>> gcc/
>>>       * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>>       Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>>       VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>>
>>> gcc/testsuite/
>>>       * gcc.target/powerpc/vec-minmax-1.c: New test.
>>>       * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>>
>>> diff --git a/gcc/config/rs6000/rs6000-call.c
>>> b/gcc/config/rs6000/rs6000-call.c
>>> index b4e13af4dc6..90527734ceb 100644
>>> --- a/gcc/config/rs6000/rs6000-call.c
>>> +++ b/gcc/config/rs6000/rs6000-call.c
>>> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin
>>> (gimple_stmt_iterator *gsi)
>>>          return true;
>>>        /* flavors of vec_min.  */
>>>        case VSX_BUILTIN_XVMINDP:
>>> +    case ALTIVEC_BUILTIN_VMINFP:
>>> +      if (!flag_finite_math_only || flag_signed_zeros)
>>> +    return false;
>>> +      /* Fall through to MIN_EXPR.  */
>>> +      gcc_fallthrough ();
>>>        case P8V_BUILTIN_VMINSD:
>>>        case P8V_BUILTIN_VMINUD:
>>>        case ALTIVEC_BUILTIN_VMINSB:
>>> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin 
>>> (gimple_stmt_iterator
>>> *gsi)
>>>        case ALTIVEC_BUILTIN_VMINUB:
>>>        case ALTIVEC_BUILTIN_VMINUH:
>>>        case ALTIVEC_BUILTIN_VMINUW:
>>> -    case ALTIVEC_BUILTIN_VMINFP:
>>>          arg0 = gimple_call_arg (stmt, 0);
>>>          arg1 = gimple_call_arg (stmt, 1);
>>>          lhs = gimple_call_lhs (stmt);
>>> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin
>>> (gimple_stmt_iterator *gsi)
>>>          return true;
>>>        /* flavors of vec_max.  */
>>>        case VSX_BUILTIN_XVMAXDP:
>>> +    case ALTIVEC_BUILTIN_VMAXFP:
>>> +      if (!flag_finite_math_only || flag_signed_zeros)
>>> +    return false;
>>> +      /* Fall through to MAX_EXPR.  */
>>> +      gcc_fallthrough ();
>>>        case P8V_BUILTIN_VMAXSD:
>>>        case P8V_BUILTIN_VMAXUD:
>>>        case ALTIVEC_BUILTIN_VMAXSB:
>>> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin 
>>> (gimple_stmt_iterator
>>> *gsi)
>>>        case ALTIVEC_BUILTIN_VMAXUB:
>>>        case ALTIVEC_BUILTIN_VMAXUH:
>>>        case ALTIVEC_BUILTIN_VMAXUW:
>>> -    case ALTIVEC_BUILTIN_VMAXFP:
>>>          arg0 = gimple_call_arg (stmt, 0);
>>>          arg1 = gimple_call_arg (stmt, 1);
>>>          lhs = gimple_call_lhs (stmt);
>>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>> new file mode 100644
>>> index 00000000000..da92f059aea
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>> @@ -0,0 +1,53 @@
>>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>>> +
>>> +/* This test verifies that float or double vec_min/max are bound to
>>> +   xv[min|max][d|s]p instructions when fast-math is not set. */
>>> +
>>> +
>>> +#include <altivec.h>
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_D = 0;
>>> +#else
>>> +   const int PREF_D = 1;
>>> +#endif
>>> +
>>> +double vmaxd (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>> +}
>>> +
>>> +double vmind (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>> +}
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_F = 0;
>>> +#else
>>> +   const int PREF_F = 3;
>>> +#endif
>>> +
>>> +float vmaxf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>> +}
>>> +
>>> +float vminf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>> +}
>>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>> new file mode 100644
>>> index 00000000000..d318b933181
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>> @@ -0,0 +1,51 @@
>>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>>> +
>>> +/* This test verifies that float or double vec_min/max can be 
>>> converted
>>> +   to scalar comparison when fast-math is set.  */
>>> +
>>> +
>>> +#include <altivec.h>
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_D = 0;
>>> +#else
>>> +   const int PREF_D = 1;
>>> +#endif
>>> +
>>> +double vmaxd (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>> +}
>>> +
>>> +double vmind (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>> +}
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_F = 0;
>>> +#else
>>> +   const int PREF_F = 3;
>>> +#endif
>>> +
>>> +float vmaxf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>> +}
>>> +
>>> +float vminf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>> +}
>>>
>>> On 25/8/2021 上午 6:40, Segher Boessenkool wrote:
>>>> Hi!
>>>>
>>>> On Tue, Aug 24, 2021 at 03:04:26PM -0500, Bill Schmidt wrote:
>>>>> On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
>>>>> Thanks for this patch!  In the future, if you can put your 
>>>>> ChangeLog and
>>>>> patch inline in your post, it makes it easier to review. 
>>>>> (Otherwise we
>>>>> have to manually copy it into our response and manipulate it to look
>>>>> quoted, etc.)
>>>> It is encoded even, making it impossible to easily apply the patch, 
>>>> etc.
>>>>
>>>>>> diff --git a/gcc/config/rs6000/rs6000-call.c
>>>>>> b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb
>>>>>> 100644 --- a/gcc/config/rs6000/rs6000-call.c +++
>>>>>> b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@
>>>>>> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return 
>>>>>> true; /*
>>>>>> flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case
>>>> format=flawed :-(
>>>>
>>>>
>>>> Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-25 12:34       ` Bill Schmidt
@ 2021-08-26  1:19         ` HAO CHEN GUI
  2021-09-06  6:01           ` HAO CHEN GUI
  2021-10-11 15:55           ` Segher Boessenkool
  0 siblings, 2 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-08-26  1:19 UTC (permalink / raw)
  To: wschmidt, Segher Boessenkool; +Cc: gcc-patches, guihaoc

Hi Bill,

    Thanks for your comments.

Hi Segher,

    Here is the ChangeLog and patch diff. Thanks.

2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
     * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
     Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
     VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.

gcc/testsuite/
     * gcc.target/powerpc/vec-minmax-1.c: New test.
     * gcc.target/powerpc/vec-minmax-2.c: Likewise.

diff --git a/gcc/config/rs6000/rs6000-call.c 
b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..90527734ceb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin 
(gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_min.  */
      case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+    return false;
+      /* Fall through to MIN_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMINSD:
      case P8V_BUILTIN_VMINUD:
      case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
*gsi)
      case ALTIVEC_BUILTIN_VMINUB:
      case ALTIVEC_BUILTIN_VMINUH:
      case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin 
(gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_max.  */
      case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+    return false;
+      /* Fall through to MAX_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMAXSD:
      case P8V_BUILTIN_VMAXUD:
      case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
*gsi)
      case ALTIVEC_BUILTIN_VMAXUB:
      case ALTIVEC_BUILTIN_VMAXUH:
      case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c 
b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..547798fd65c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c 
b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..4c6f4365830
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

On 25/8/2021 下午 8:34, Bill Schmidt wrote:
> Hi Haochen,
>
> Thanks for the updates!  This looks good to me; please await Segher's 
> response.
>
> Bill
>
> On 8/25/21 2:06 AM, HAO CHEN GUI wrote:
>> Hi,
>>
>>       I refined the patch according to Bill's advice. I pasted the
>> ChangeLog and diff file here. If it doesn't work, please let me know.
>> Thanks.
>>
>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
>>       * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>       Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>       VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>
>> gcc/testsuite/
>>       * gcc.target/powerpc/vec-minmax-1.c: New test.
>>       * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>
>> diff --git a/gcc/config/rs6000/rs6000-call.c
>> b/gcc/config/rs6000/rs6000-call.c
>> index b4e13af4dc6..90527734ceb 100644
>> --- a/gcc/config/rs6000/rs6000-call.c
>> +++ b/gcc/config/rs6000/rs6000-call.c
>> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin
>> (gimple_stmt_iterator *gsi)
>>          return true;
>>        /* flavors of vec_min.  */
>>        case VSX_BUILTIN_XVMINDP:
>> +    case ALTIVEC_BUILTIN_VMINFP:
>> +      if (!flag_finite_math_only || flag_signed_zeros)
>> +    return false;
>> +      /* Fall through to MIN_EXPR.  */
>> +      gcc_fallthrough ();
>>        case P8V_BUILTIN_VMINSD:
>>        case P8V_BUILTIN_VMINUD:
>>        case ALTIVEC_BUILTIN_VMINSB:
>> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator
>> *gsi)
>>        case ALTIVEC_BUILTIN_VMINUB:
>>        case ALTIVEC_BUILTIN_VMINUH:
>>        case ALTIVEC_BUILTIN_VMINUW:
>> -    case ALTIVEC_BUILTIN_VMINFP:
>>          arg0 = gimple_call_arg (stmt, 0);
>>          arg1 = gimple_call_arg (stmt, 1);
>>          lhs = gimple_call_lhs (stmt);
>> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin
>> (gimple_stmt_iterator *gsi)
>>          return true;
>>        /* flavors of vec_max.  */
>>        case VSX_BUILTIN_XVMAXDP:
>> +    case ALTIVEC_BUILTIN_VMAXFP:
>> +      if (!flag_finite_math_only || flag_signed_zeros)
>> +    return false;
>> +      /* Fall through to MAX_EXPR.  */
>> +      gcc_fallthrough ();
>>        case P8V_BUILTIN_VMAXSD:
>>        case P8V_BUILTIN_VMAXUD:
>>        case ALTIVEC_BUILTIN_VMAXSB:
>> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator
>> *gsi)
>>        case ALTIVEC_BUILTIN_VMAXUB:
>>        case ALTIVEC_BUILTIN_VMAXUH:
>>        case ALTIVEC_BUILTIN_VMAXUW:
>> -    case ALTIVEC_BUILTIN_VMAXFP:
>>          arg0 = gimple_call_arg (stmt, 0);
>>          arg1 = gimple_call_arg (stmt, 1);
>>          lhs = gimple_call_lhs (stmt);
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> new file mode 100644
>> index 00000000000..da92f059aea
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> @@ -0,0 +1,53 @@
>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>> +
>> +/* This test verifies that float or double vec_min/max are bound to
>> +   xv[min|max][d|s]p instructions when fast-math is not set. */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> new file mode 100644
>> index 00000000000..d318b933181
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> @@ -0,0 +1,51 @@
>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>> +
>> +/* This test verifies that float or double vec_min/max can be converted
>> +   to scalar comparison when fast-math is set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>>
>> On 25/8/2021 上午 6:40, Segher Boessenkool wrote:
>>> Hi!
>>>
>>> On Tue, Aug 24, 2021 at 03:04:26PM -0500, Bill Schmidt wrote:
>>>> On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
>>>> Thanks for this patch!  In the future, if you can put your 
>>>> ChangeLog and
>>>> patch inline in your post, it makes it easier to review. (Otherwise we
>>>> have to manually copy it into our response and manipulate it to look
>>>> quoted, etc.)
>>> It is encoded even, making it impossible to easily apply the patch, 
>>> etc.
>>>
>>>>> diff --git a/gcc/config/rs6000/rs6000-call.c
>>>>> b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb
>>>>> 100644 --- a/gcc/config/rs6000/rs6000-call.c +++
>>>>> b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@
>>>>> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return 
>>>>> true; /*
>>>>> flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case
>>> format=flawed :-(
>>>
>>>
>>> Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-25  7:06     ` HAO CHEN GUI
  2021-08-25  7:50       ` Kewen.Lin
@ 2021-08-25 12:34       ` Bill Schmidt
  2021-08-26  1:19         ` HAO CHEN GUI
  1 sibling, 1 reply; 29+ messages in thread
From: Bill Schmidt @ 2021-08-25 12:34 UTC (permalink / raw)
  To: HAO CHEN GUI, Segher Boessenkool; +Cc: gcc-patches, guihaoc

Hi Haochen,

Thanks for the updates!  This looks good to me; please await Segher's 
response.

Bill

On 8/25/21 2:06 AM, HAO CHEN GUI wrote:
> Hi,
>
>       I refined the patch according to Bill's advice. I pasted the
> ChangeLog and diff file here. If it doesn't work, please let me know.
> Thanks.
>
> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>
> gcc/
>       * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>       Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>       VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>
> gcc/testsuite/
>       * gcc.target/powerpc/vec-minmax-1.c: New test.
>       * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>
> diff --git a/gcc/config/rs6000/rs6000-call.c
> b/gcc/config/rs6000/rs6000-call.c
> index b4e13af4dc6..90527734ceb 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin
> (gimple_stmt_iterator *gsi)
>          return true;
>        /* flavors of vec_min.  */
>        case VSX_BUILTIN_XVMINDP:
> +    case ALTIVEC_BUILTIN_VMINFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +    return false;
> +      /* Fall through to MIN_EXPR.  */
> +      gcc_fallthrough ();
>        case P8V_BUILTIN_VMINSD:
>        case P8V_BUILTIN_VMINUD:
>        case ALTIVEC_BUILTIN_VMINSB:
> @@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator
> *gsi)
>        case ALTIVEC_BUILTIN_VMINUB:
>        case ALTIVEC_BUILTIN_VMINUH:
>        case ALTIVEC_BUILTIN_VMINUW:
> -    case ALTIVEC_BUILTIN_VMINFP:
>          arg0 = gimple_call_arg (stmt, 0);
>          arg1 = gimple_call_arg (stmt, 1);
>          lhs = gimple_call_lhs (stmt);
> @@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin
> (gimple_stmt_iterator *gsi)
>          return true;
>        /* flavors of vec_max.  */
>        case VSX_BUILTIN_XVMAXDP:
> +    case ALTIVEC_BUILTIN_VMAXFP:
> +      if (!flag_finite_math_only || flag_signed_zeros)
> +    return false;
> +      /* Fall through to MAX_EXPR.  */
> +      gcc_fallthrough ();
>        case P8V_BUILTIN_VMAXSD:
>        case P8V_BUILTIN_VMAXUD:
>        case ALTIVEC_BUILTIN_VMAXSB:
> @@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator
> *gsi)
>        case ALTIVEC_BUILTIN_VMAXUB:
>        case ALTIVEC_BUILTIN_VMAXUH:
>        case ALTIVEC_BUILTIN_VMAXUW:
> -    case ALTIVEC_BUILTIN_VMAXFP:
>          arg0 = gimple_call_arg (stmt, 0);
>          arg1 = gimple_call_arg (stmt, 1);
>          lhs = gimple_call_lhs (stmt);
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> new file mode 100644
> index 00000000000..da92f059aea
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile { target { powerpc64le-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> +
> +/* This test verifies that float or double vec_min/max are bound to
> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> new file mode 100644
> index 00000000000..d318b933181
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> @@ -0,0 +1,51 @@
> +/* { dg-do compile { target { powerpc64le-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> +
> +/* This test verifies that float or double vec_min/max can be converted
> +   to scalar comparison when fast-math is set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
>
> On 25/8/2021 上午 6:40, Segher Boessenkool wrote:
>> Hi!
>>
>> On Tue, Aug 24, 2021 at 03:04:26PM -0500, Bill Schmidt wrote:
>>> On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
>>> Thanks for this patch!  In the future, if you can put your ChangeLog and
>>> patch inline in your post, it makes it easier to review.  (Otherwise we
>>> have to manually copy it into our response and manipulate it to look
>>> quoted, etc.)
>> It is encoded even, making it impossible to easily apply the patch, etc.
>>
>>>> diff --git a/gcc/config/rs6000/rs6000-call.c
>>>> b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb
>>>> 100644 --- a/gcc/config/rs6000/rs6000-call.c +++
>>>> b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@
>>>> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return true; /*
>>>> flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case
>> format=flawed :-(
>>
>>
>> Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-25  8:17         ` HAO CHEN GUI
@ 2021-08-25  8:44           ` HAO CHEN GUI
  0 siblings, 0 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-08-25  8:44 UTC (permalink / raw)
  To: Kewen.Lin; +Cc: Bill Schmidt, gcc-patches, Segher Boessenkool


On 25/8/2021 下午 4:17, HAO CHEN GUI via Gcc-patches wrote:
> Hi Kewen,
>
>   Thanks for your advice.
>
> On 25/8/2021 下午 3:50, Kewen.Lin wrote:
>> Hi Haochen,
>>
>> on 2021/8/25 下午3:06, HAO CHEN GUI via Gcc-patches wrote:
>>> Hi,
>>>
>>>      I refined the patch according to Bill's advice. I pasted the 
>>> ChangeLog and diff file here. If it doesn't work, please let me 
>>> know. Thanks.
>>>
>>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>>
>>> gcc/
>> IIUC, this patch is for PR93127, one line for PR is missing here.
> The patch does comes from the PR, but it doesn't work as the PR 
> requires. So I am not sure if I should add the PR number.
>>
>>>      * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>>      Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>>      VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>>
>>> gcc/testsuite/
>> Same, need a PR line.
>>
>>>      * gcc.target/powerpc/vec-minmax-1.c: New test.
>>>      * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>>
>> Maybe it's better to use pr93127-{1,2}.c for case names?
>>
>> ...
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>>> @@ -0,0 +1,53 @@
>>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>> I guess this "powerpc64le" isn't intentional?  The test case
>> has the macro to distinguish endianess, I assume we want this
>> to be compiled on BE?  If so, we just put the line below instead?
> It should be tested on BE as well. I will replace it with 
> 'powerpc*-*-* && lp64'.
It should be 'powerpc*-*-*'. Thanks again!
>>
>> /* { dg-do compile } */
>>
>> And it needs extra testing on BE as well.  :)
>>
>> Thanks for fixing this!
>>
>> BR,
>> Kewen
>>
>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>>> +
>>> +/* This test verifies that float or double vec_min/max are bound to
>>> +   xv[min|max][d|s]p instructions when fast-math is not set. */
>>> +
>>> +
>>> +#include <altivec.h>
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_D = 0;
>>> +#else
>>> +   const int PREF_D = 1;
>>> +#endif
>>> +
>>> +double vmaxd (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>> +}
>>> +
>>> +double vmind (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>> +}
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_F = 0;
>>> +#else
>>> +   const int PREF_F = 3;
>>> +#endif
>>> +
>>> +float vmaxf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>> +}
>>> +
>>> +float vminf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>> +}
>>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c 
>>> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>> new file mode 100644
>>> index 00000000000..d318b933181
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>>> @@ -0,0 +1,51 @@
>>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>>> +
>>> +/* This test verifies that float or double vec_min/max can be 
>>> converted
>>> +   to scalar comparison when fast-math is set.  */
>>> +
>>> +
>>> +#include <altivec.h>
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_D = 0;
>>> +#else
>>> +   const int PREF_D = 1;
>>> +#endif
>>> +
>>> +double vmaxd (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_max (va, vb), PREF_D);
>>> +}
>>> +
>>> +double vmind (double a, double b)
>>> +{
>>> +  vector double va = vec_promote (a, PREF_D);
>>> +  vector double vb = vec_promote (b, PREF_D);
>>> +  return vec_extract (vec_min (va, vb), PREF_D);
>>> +}
>>> +
>>> +#ifdef _BIG_ENDIAN
>>> +   const int PREF_F = 0;
>>> +#else
>>> +   const int PREF_F = 3;
>>> +#endif
>>> +
>>> +float vmaxf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_max (va, vb), PREF_F);
>>> +}
>>> +
>>> +float vminf (float a, float b)
>>> +{
>>> +  vector float va = vec_promote (a, PREF_F);
>>> +  vector float vb = vec_promote (b, PREF_F);
>>> +  return vec_extract (vec_min (va, vb), PREF_F);
>>> +}
>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-25  7:50       ` Kewen.Lin
@ 2021-08-25  8:17         ` HAO CHEN GUI
  2021-08-25  8:44           ` HAO CHEN GUI
  0 siblings, 1 reply; 29+ messages in thread
From: HAO CHEN GUI @ 2021-08-25  8:17 UTC (permalink / raw)
  To: Kewen.Lin; +Cc: guihaoc, gcc-patches, Segher Boessenkool, Bill Schmidt

Hi Kewen,

   Thanks for your advice.

On 25/8/2021 下午 3:50, Kewen.Lin wrote:
> Hi Haochen,
>
> on 2021/8/25 下午3:06, HAO CHEN GUI via Gcc-patches wrote:
>> Hi,
>>
>>      I refined the patch according to Bill's advice. I pasted the ChangeLog and diff file here. If it doesn't work, please let me know. Thanks.
>>
>> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
>>
>> gcc/
> IIUC, this patch is for PR93127, one line for PR is missing here.
The patch does comes from the PR, but it doesn't work as the PR 
requires. So I am not sure if I should add the PR number.
>
>>      * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>>      Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>>      VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
>>
>> gcc/testsuite/
> Same, need a PR line.
>
>>      * gcc.target/powerpc/vec-minmax-1.c: New test.
>>      * gcc.target/powerpc/vec-minmax-2.c: Likewise.
>>
> Maybe it's better to use pr93127-{1,2}.c for case names?
>
> ...
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
>> @@ -0,0 +1,53 @@
>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
> I guess this "powerpc64le" isn't intentional?  The test case
> has the macro to distinguish endianess, I assume we want this
> to be compiled on BE?  If so, we just put the line below instead?
It should be tested on BE as well. I will replace it with 'powerpc*-*-* 
&& lp64'.
>
> /* { dg-do compile } */
>
> And it needs extra testing on BE as well.  :)
>
> Thanks for fixing this!
>
> BR,
> Kewen
>
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
>> +
>> +/* This test verifies that float or double vec_min/max are bound to
>> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> new file mode 100644
>> index 00000000000..d318b933181
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
>> @@ -0,0 +1,51 @@
>> +/* { dg-do compile { target { powerpc64le-*-* } } } */
>> +/* { dg-require-effective-target powerpc_p9vector_ok } */
>> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
>> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
>> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
>> +
>> +/* This test verifies that float or double vec_min/max can be converted
>> +   to scalar comparison when fast-math is set.  */
>> +
>> +
>> +#include <altivec.h>
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_D = 0;
>> +#else
>> +   const int PREF_D = 1;
>> +#endif
>> +
>> +double vmaxd (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_max (va, vb), PREF_D);
>> +}
>> +
>> +double vmind (double a, double b)
>> +{
>> +  vector double va = vec_promote (a, PREF_D);
>> +  vector double vb = vec_promote (b, PREF_D);
>> +  return vec_extract (vec_min (va, vb), PREF_D);
>> +}
>> +
>> +#ifdef _BIG_ENDIAN
>> +   const int PREF_F = 0;
>> +#else
>> +   const int PREF_F = 3;
>> +#endif
>> +
>> +float vmaxf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_max (va, vb), PREF_F);
>> +}
>> +
>> +float vminf (float a, float b)
>> +{
>> +  vector float va = vec_promote (a, PREF_F);
>> +  vector float vb = vec_promote (b, PREF_F);
>> +  return vec_extract (vec_min (va, vb), PREF_F);
>> +}
>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-25  7:06     ` HAO CHEN GUI
@ 2021-08-25  7:50       ` Kewen.Lin
  2021-08-25  8:17         ` HAO CHEN GUI
  2021-08-25 12:34       ` Bill Schmidt
  1 sibling, 1 reply; 29+ messages in thread
From: Kewen.Lin @ 2021-08-25  7:50 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: guihaoc, gcc-patches, Segher Boessenkool, Bill Schmidt

Hi Haochen,

on 2021/8/25 下午3:06, HAO CHEN GUI via Gcc-patches wrote:
> Hi,
> 
>     I refined the patch according to Bill's advice. I pasted the ChangeLog and diff file here. If it doesn't work, please let me know. Thanks.
> 
> 2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>
> 
> gcc/

IIUC, this patch is for PR93127, one line for PR is missing here.

>     * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
>     Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
>     VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.
> 
> gcc/testsuite/

Same, need a PR line.

>     * gcc.target/powerpc/vec-minmax-1.c: New test.
>     * gcc.target/powerpc/vec-minmax-2.c: Likewise.
> 

Maybe it's better to use pr93127-{1,2}.c for case names?

...
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile { target { powerpc64le-*-* } } } */

I guess this "powerpc64le" isn't intentional?  The test case
has the macro to distinguish endianess, I assume we want this
to be compiled on BE?  If so, we just put the line below instead?

/* { dg-do compile } */

And it needs extra testing on BE as well.  :)

Thanks for fixing this!

BR,
Kewen

> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
> +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
> +
> +/* This test verifies that float or double vec_min/max are bound to
> +   xv[min|max][d|s]p instructions when fast-math is not set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> new file mode 100644
> index 00000000000..d318b933181
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
> @@ -0,0 +1,51 @@
> +/* { dg-do compile { target { powerpc64le-*-* } } } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
> +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
> +
> +/* This test verifies that float or double vec_min/max can be converted
> +   to scalar comparison when fast-math is set.  */
> +
> +
> +#include <altivec.h>
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_D = 0;
> +#else
> +   const int PREF_D = 1;
> +#endif
> +
> +double vmaxd (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_max (va, vb), PREF_D);
> +}
> +
> +double vmind (double a, double b)
> +{
> +  vector double va = vec_promote (a, PREF_D);
> +  vector double vb = vec_promote (b, PREF_D);
> +  return vec_extract (vec_min (va, vb), PREF_D);
> +}
> +
> +#ifdef _BIG_ENDIAN
> +   const int PREF_F = 0;
> +#else
> +   const int PREF_F = 3;
> +#endif
> +
> +float vmaxf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_max (va, vb), PREF_F);
> +}
> +
> +float vminf (float a, float b)
> +{
> +  vector float va = vec_promote (a, PREF_F);
> +  vector float vb = vec_promote (b, PREF_F);
> +  return vec_extract (vec_min (va, vb), PREF_F);
> +}
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-24 22:40   ` Segher Boessenkool
@ 2021-08-25  7:06     ` HAO CHEN GUI
  2021-08-25  7:50       ` Kewen.Lin
  2021-08-25 12:34       ` Bill Schmidt
  0 siblings, 2 replies; 29+ messages in thread
From: HAO CHEN GUI @ 2021-08-25  7:06 UTC (permalink / raw)
  To: Segher Boessenkool, Bill Schmidt; +Cc: gcc-patches, guihaoc

Hi,

     I refined the patch according to Bill's advice. I pasted the 
ChangeLog and diff file here. If it doesn't work, please let me know. 
Thanks.

2021-08-25 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
     * config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin):
     Modify the VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP,
     VSX_BUILTIN_XVMAXDP, ALTIVEC_BUILTIN_VMAXFP expansions.

gcc/testsuite/
     * gcc.target/powerpc/vec-minmax-1.c: New test.
     * gcc.target/powerpc/vec-minmax-2.c: Likewise.

diff --git a/gcc/config/rs6000/rs6000-call.c 
b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..90527734ceb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin 
(gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_min.  */
      case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+    return false;
+      /* Fall through to MIN_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMINSD:
      case P8V_BUILTIN_VMINUD:
      case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
*gsi)
      case ALTIVEC_BUILTIN_VMINUB:
      case ALTIVEC_BUILTIN_VMINUH:
      case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin 
(gimple_stmt_iterator *gsi)
        return true;
      /* flavors of vec_max.  */
      case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+    return false;
+      /* Fall through to MAX_EXPR.  */
+      gcc_fallthrough ();
      case P8V_BUILTIN_VMAXSD:
      case P8V_BUILTIN_VMAXUD:
      case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator 
*gsi)
      case ALTIVEC_BUILTIN_VMAXUB:
      case ALTIVEC_BUILTIN_VMAXUH:
      case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c 
b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..da92f059aea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c 
b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..d318b933181
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

On 25/8/2021 上午 6:40, Segher Boessenkool wrote:
> Hi!
>
> On Tue, Aug 24, 2021 at 03:04:26PM -0500, Bill Schmidt wrote:
>> On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
>> Thanks for this patch!  In the future, if you can put your ChangeLog and
>> patch inline in your post, it makes it easier to review.  (Otherwise we
>> have to manually copy it into our response and manipulate it to look
>> quoted, etc.)
> It is encoded even, making it impossible to easily apply the patch, etc.
>
>>> diff --git a/gcc/config/rs6000/rs6000-call.c
>>> b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb
>>> 100644 --- a/gcc/config/rs6000/rs6000-call.c +++
>>> b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@
>>> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return true; /*
>>> flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case
> format=flawed :-(
>
>
> Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-24 20:04 ` Bill Schmidt
@ 2021-08-24 22:40   ` Segher Boessenkool
  2021-08-25  7:06     ` HAO CHEN GUI
  0 siblings, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-08-24 22:40 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: HAO CHEN GUI, gcc-patches

Hi!

On Tue, Aug 24, 2021 at 03:04:26PM -0500, Bill Schmidt wrote:
> On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
> Thanks for this patch!  In the future, if you can put your ChangeLog and 
> patch inline in your post, it makes it easier to review.  (Otherwise we 
> have to manually copy it into our response and manipulate it to look 
> quoted, etc.)

It is encoded even, making it impossible to easily apply the patch, etc.

> >diff --git a/gcc/config/rs6000/rs6000-call.c 
> >b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb 
> >100644 --- a/gcc/config/rs6000/rs6000-call.c +++ 
> >b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@ 
> >rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return true; /* 
> >flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case 

format=flawed :-(


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
  2021-08-24  8:52 HAO CHEN GUI
@ 2021-08-24 20:04 ` Bill Schmidt
  2021-08-24 22:40   ` Segher Boessenkool
  0 siblings, 1 reply; 29+ messages in thread
From: Bill Schmidt @ 2021-08-24 20:04 UTC (permalink / raw)
  To: HAO CHEN GUI, gcc-patches; +Cc: Segher Boessenkool

Hi Hao Chen,

On 8/24/21 3:52 AM, HAO CHEN GUI wrote:
> Hi
>
>      The patch disables gimple fold for float or double vec_min/max
> builtin when fast-math is not set. Two test cases are added to verify
> the patch.
>
>      The attachments are the patch diff and change log file.
>
>      Bootstrapped and tested on powerpc64le-linux with no regressions. Is
> this okay for trunk? Any recommendations? Thanks a lot.
>
Thanks for this patch!  In the future, if you can put your ChangeLog and 
patch inline in your post, it makes it easier to review.  (Otherwise we 
have to manually copy it into our response and manipulate it to look 
quoted, etc.)

Your ChangeLog isn't formatted correctly.  It should look like this:

2021-08-24  Hao Chen Gui  <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin): Modify the
	VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP, VSX_BUILTIN_XVMAXDP, and
	ALTIVEC_BUILTIN_VMAXFP expansions.

gcc/testsuite/
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

You forgot the committer/timestamp line and the ChangeLog location 
lines.  (The headers like "gcc/" ensure that the automated processing 
will record your entries in the ChangeLog at the correct location in the 
source tree.)  Note also that the colon ":" always follows the ending 
parenthesis when there's a function name listed.  Please review 
https://gcc.gnu.org/codingconventions.html#ChangeLogs.

> diff --git a/gcc/config/rs6000/rs6000-call.c 
> b/gcc/config/rs6000/rs6000-call.c index b4e13af4dc6..90527734ceb 
> 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ 
> b/gcc/config/rs6000/rs6000-call.c @@ -12159,6 +12159,11 @@ 
> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return true; /* 
> flavors of vec_min. */ case VSX_BUILTIN_XVMINDP: + case 
> ALTIVEC_BUILTIN_VMINFP: + if (!flag_finite_math_only || 
> flag_signed_zeros) + return false; + /* Fall through to MIN_EXPR. */ + 
> gcc_fallthrough (); case P8V_BUILTIN_VMINSD: case P8V_BUILTIN_VMINUD: 
> case ALTIVEC_BUILTIN_VMINSB: @@ -12167,7 +12172,6 @@ 
> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) case 
> ALTIVEC_BUILTIN_VMINUB: case ALTIVEC_BUILTIN_VMINUH: case 
> ALTIVEC_BUILTIN_VMINUW: - case ALTIVEC_BUILTIN_VMINFP: arg0 = 
> gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = 
> gimple_call_lhs (stmt); @@ -12177,6 +12181,11 @@ 
> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) return true; /* 
> flavors of vec_max. */ case VSX_BUILTIN_XVMAXDP: + case 
> ALTIVEC_BUILTIN_VMAXFP: + if (!flag_finite_math_only || 
> flag_signed_zeros) + return false; + /* Fall through to MAX_EXPR. */ + 
> gcc_fallthrough (); case P8V_BUILTIN_VMAXSD: case P8V_BUILTIN_VMAXUD: 
> case ALTIVEC_BUILTIN_VMAXSB: @@ -12185,7 +12194,6 @@ 
> rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) case 
> ALTIVEC_BUILTIN_VMAXUB: case ALTIVEC_BUILTIN_VMAXUH: case 
> ALTIVEC_BUILTIN_VMAXUW: - case ALTIVEC_BUILTIN_VMAXFP: arg0 = 
> gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = 
> gimple_call_lhs (stmt); diff --git 
> a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c new file mode 100644 
> index 00000000000..9782d1b9308 --- /dev/null +++ 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c @@ -0,0 +1,51 @@ +/* 
> { dg-do compile { target { powerpc64le-*-* } } } */ +/* { 
> dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options 
> "-O2 -mdejagnu-cpu=power9" } */ +/* { dg-final { scan-assembler-times 
> {\mxvmax[ds]p\M} 2 } } */ +/* { dg-final { scan-assembler-times 
> {\mxvmin[ds]p\M} 2 } } */ 

This is pedantic, but...  You want exactly one each of xvmaxdp, xvmaxsp, xvmindp, and xvminsp,
so please replace this with four lines with { scan-assembler-times {...} 1 }.  Thanks. :-)

Otherwise this looks fine to me.  I can't approve, but recommend the maintainers approve with
that changed.

Thanks!
Bill
> + +/* This test verifies that float or double vec_min/max are bound to 
> + xv[min|max][d|s]p instructions when fast-math is not set. */ + + 
> +#include <altivec.h> + +#ifdef _BIG_ENDIAN + const int PREF_D = 0; 
> +#else + const int PREF_D = 1; +#endif + +double vmaxd (double a, 
> double b) +{ + vector double va = vec_promote (a, PREF_D); + vector 
> double vb = vec_promote (b, PREF_D); + return vec_extract (vec_max 
> (va, vb), PREF_D); +} + +double vmind (double a, double b) +{ + vector 
> double va = vec_promote (a, PREF_D); + vector double vb = vec_promote 
> (b, PREF_D); + return vec_extract (vec_min (va, vb), PREF_D); +} + 
> +#ifdef _BIG_ENDIAN + const int PREF_F = 0; +#else + const int PREF_F 
> = 3; +#endif + +float vmaxf (float a, float b) +{ + vector float va = 
> vec_promote (a, PREF_F); + vector float vb = vec_promote (b, PREF_F); 
> + return vec_extract (vec_max (va, vb), PREF_F); +} + +float vminf 
> (float a, float b) +{ + vector float va = vec_promote (a, PREF_F); + 
> vector float vb = vec_promote (b, PREF_F); + return vec_extract 
> (vec_min (va, vb), PREF_F); +} diff --git 
> a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c new file mode 100644 
> index 00000000000..d318b933181 --- /dev/null +++ 
> b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c @@ -0,0 +1,51 @@ +/* 
> { dg-do compile { target { powerpc64le-*-* } } } */ +/* { 
> dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options 
> "-O2 -mdejagnu-cpu=power9 -ffast-math" } */ +/* { dg-final { 
> scan-assembler-times {\mxsmaxcdp\M} 2 } } */ +/* { dg-final { 
> scan-assembler-times {\mxsmincdp\M} 2 } } */ + +/* This test verifies 
> that float or double vec_min/max can be converted + to scalar 
> comparison when fast-math is set. */ + + +#include <altivec.h> + 
> +#ifdef _BIG_ENDIAN + const int PREF_D = 0; +#else + const int PREF_D 
> = 1; +#endif + +double vmaxd (double a, double b) +{ + vector double 
> va = vec_promote (a, PREF_D); + vector double vb = vec_promote (b, 
> PREF_D); + return vec_extract (vec_max (va, vb), PREF_D); +} + +double 
> vmind (double a, double b) +{ + vector double va = vec_promote (a, 
> PREF_D); + vector double vb = vec_promote (b, PREF_D); + return 
> vec_extract (vec_min (va, vb), PREF_D); +} + +#ifdef _BIG_ENDIAN + 
> const int PREF_F = 0; +#else + const int PREF_F = 3; +#endif + +float 
> vmaxf (float a, float b) +{ + vector float va = vec_promote (a, 
> PREF_F); + vector float vb = vec_promote (b, PREF_F); + return 
> vec_extract (vec_max (va, vb), PREF_F); +} + +float vminf (float a, 
> float b) +{ + vector float va = vec_promote (a, PREF_F); + vector 
> float vb = vec_promote (b, PREF_F); + return vec_extract (vec_min (va, 
> vb), PREF_F); +} 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set
@ 2021-08-24  8:52 HAO CHEN GUI
  2021-08-24 20:04 ` Bill Schmidt
  0 siblings, 1 reply; 29+ messages in thread
From: HAO CHEN GUI @ 2021-08-24  8:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool, Bill Schmidt

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

Hi

    The patch disables gimple fold for float or double vec_min/max 
builtin when fast-math is not set. Two test cases are added to verify 
the patch.

    The attachments are the patch diff and change log file.

    Bootstrapped and tested on powerpc64le-linux with no regressions. Is 
this okay for trunk? Any recommendations? Thanks a lot.


[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 273 bytes --]

	* config/rs6000/rs6000-call.c (rs6000_gimple_fold_builtin)
	<VSX_BUILTIN_XVMINDP, ALTIVEC_BUILTIN_VMINFP, VSX_BUILTIN_XVMAXDP,
	ALTIVEC_BUILTIN_VMAXFP>: Modify the expansions.
	* gcc.target/powerpc/vec-minmax-1.c: New test.
	* gcc.target/powerpc/vec-minmax-2.c: Likewise.

[-- Attachment #3: patch.diff --]
[-- Type: text/plain, Size: 4957 bytes --]

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b4e13af4dc6..90527734ceb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12159,6 +12159,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_min.  */
     case VSX_BUILTIN_XVMINDP:
+    case ALTIVEC_BUILTIN_VMINFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+	return false;
+      /* Fall through to MIN_EXPR.  */
+      gcc_fallthrough ();
     case P8V_BUILTIN_VMINSD:
     case P8V_BUILTIN_VMINUD:
     case ALTIVEC_BUILTIN_VMINSB:
@@ -12167,7 +12172,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMINUB:
     case ALTIVEC_BUILTIN_VMINUH:
     case ALTIVEC_BUILTIN_VMINUW:
-    case ALTIVEC_BUILTIN_VMINFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
@@ -12177,6 +12181,11 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return true;
     /* flavors of vec_max.  */
     case VSX_BUILTIN_XVMAXDP:
+    case ALTIVEC_BUILTIN_VMAXFP:
+      if (!flag_finite_math_only || flag_signed_zeros)
+	return false;
+      /* Fall through to MAX_EXPR.  */
+      gcc_fallthrough ();
     case P8V_BUILTIN_VMAXSD:
     case P8V_BUILTIN_VMAXUD:
     case ALTIVEC_BUILTIN_VMAXSB:
@@ -12185,7 +12194,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VMAXUB:
     case ALTIVEC_BUILTIN_VMAXUH:
     case ALTIVEC_BUILTIN_VMAXUW:
-    case ALTIVEC_BUILTIN_VMAXFP:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
new file mode 100644
index 00000000000..9782d1b9308
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-1.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mxvmax[ds]p\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxvmin[ds]p\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max are bound to
+   xv[min|max][d|s]p instructions when fast-math is not set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
new file mode 100644
index 00000000000..d318b933181
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-minmax-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -ffast-math" } */
+/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxsmincdp\M} 2 } } */
+
+/* This test verifies that float or double vec_min/max can be converted
+   to scalar comparison when fast-math is set.  */
+
+
+#include <altivec.h>
+
+#ifdef _BIG_ENDIAN
+   const int PREF_D = 0;
+#else
+   const int PREF_D = 1;
+#endif
+
+double vmaxd (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_max (va, vb), PREF_D);
+}
+
+double vmind (double a, double b)
+{
+  vector double va = vec_promote (a, PREF_D);
+  vector double vb = vec_promote (b, PREF_D);
+  return vec_extract (vec_min (va, vb), PREF_D);
+}
+
+#ifdef _BIG_ENDIAN
+   const int PREF_F = 0;
+#else
+   const int PREF_F = 3;
+#endif
+
+float vmaxf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_max (va, vb), PREF_F);
+}
+
+float vminf (float a, float b)
+{
+  vector float va = vec_promote (a, PREF_F);
+  vector float vb = vec_promote (b, PREF_F);
+  return vec_extract (vec_min (va, vb), PREF_F);
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2021-11-03  2:14 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-01  6:48 [PATCH, rs6000] Disable gimple fold for float or double vec_minmax when fast-math is not set HAO CHEN GUI
2021-11-02  0:21 ` David Edelsohn
2021-11-02  2:40   ` HAO CHEN GUI
2021-11-02 13:12     ` David Edelsohn
2021-11-03  2:14       ` HAO CHEN GUI
  -- strict thread matches above, loose matches on Subject: below --
2021-10-20  9:04 HAO CHEN GUI
2021-10-20 16:19 ` Segher Boessenkool
2021-10-21  6:25   ` HAO CHEN GUI
2021-10-13 15:02 David Edelsohn
2021-10-12  8:57 HAO CHEN GUI
2021-10-12  9:57 ` Richard Biener
2021-10-13  7:43   ` HAO CHEN GUI
2021-10-13  8:29     ` Richard Biener
2021-10-13  9:15       ` HAO CHEN GUI
2021-10-13 18:19       ` Segher Boessenkool
2021-10-13 22:04     ` Joseph Myers
2021-10-13 18:28 ` Segher Boessenkool
2021-08-24  8:52 HAO CHEN GUI
2021-08-24 20:04 ` Bill Schmidt
2021-08-24 22:40   ` Segher Boessenkool
2021-08-25  7:06     ` HAO CHEN GUI
2021-08-25  7:50       ` Kewen.Lin
2021-08-25  8:17         ` HAO CHEN GUI
2021-08-25  8:44           ` HAO CHEN GUI
2021-08-25 12:34       ` Bill Schmidt
2021-08-26  1:19         ` HAO CHEN GUI
2021-09-06  6:01           ` HAO CHEN GUI
2021-10-11 15:55           ` Segher Boessenkool
2021-10-11 16:07             ` Segher Boessenkool

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).