[PATCH] rs6000: Check -+0 and NaN for smax/smin generation

Jiufu Guo guojiufu@linux.ibm.com
Thu Mar 5 02:47:00 GMT 2020


Hi,

PR93709 mentioned regressions on maxlocval_4.f90 and minlocval_f.f90 which
relates to max of '-inf' and 'nan'. This regression occur on P9 which has
new instruction 'xsmaxcdp/xsmincdp'.
The similar issue also could be find on `a < b ? b : a` which is also
generated as `xsmaxcdp` under -O2 for P9. This instruction `xsmaxcdp`
more like C/C++ semantic (a>b?a:b). A testcase is added for this issue.

The following patch improve code to check -+0 and NaN before 'smax/smin' to
be generated for those cases.

Bootstrap/regtest on powerpc64le pass without regressions.
Is this OK for trunk and backport to GCC 9?

BR.
Jiufu

gcc/
2020-03-05  Jiufu Guo  <guojiufu@linux.ibm.com>

	PR target/93709
	* gcc/config/rs6000/rs6000.c (rs6000_emit_p9_fp_minmax): Check
	-fno-signed-zeros and -ffinite_math_only for smax/smin.

gcc/testsuite
2020-03-05  Jiufu Guo  <guojiufu@linux.ibm.com>

	PR target/93709
	* gcc.target/powerpc/p9-minmax-3.c: New test.

---
 gcc/config/rs6000/rs6000.c                     |  8 +++++++-
 gcc/testsuite/gcc.target/powerpc/p9-minmax-3.c | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/p9-minmax-3.c

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index f34e1ba70c6..951a6c32884 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14836,7 +14836,13 @@ rs6000_emit_p9_fp_minmax (rtx dest, rtx op, rtx true_cond, rtx false_cond)
   if (rtx_equal_p (op0, true_cond) && rtx_equal_p (op1, false_cond))
     ;
 
-  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0, false_cond))
+  /* Only when -fno-signed-zeros and -ffinite_math_only are in effect,
+     `op0 < op1 ? op1 : op0` works like `op1 > op0 ? op1 : op0` which 
+     could use smax;
+     `op0 > op1 ? op1 : op0` works like `op1 < op0 ? op1 : op0` which
+     could use smin.  */
+  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0, false_cond)
+	   && (flag_finite_math_only && !flag_signed_zeros))
     max_p = !max_p;
 
   else
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-minmax-3.c b/gcc/testsuite/gcc.target/powerpc/p9-minmax-3.c
new file mode 100644
index 00000000000..141603e05b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-minmax-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2 -mpower9-minmax" } */
+/* { dg-final { scan-assembler-not "xsmaxcdp"   } } */
+/* { dg-final { scan-assembler-not "xsmincdp"   } } */
+
+double
+dbl_max1 (double a, double b)
+{
+  return a < b ? b : a;
+}
+
+double
+dbl_min1 (double a, double b)
+{
+  return a > b ? b : a;
+}
-- 
2.17.1



More information about the Gcc-patches mailing list