powerpc: Fix ICE with fp conditional move (PR target/93073)
authorJakub Jelinek <jakub@redhat.com>
Tue, 21 Jan 2020 08:17:27 +0000 (09:17 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 21 Jan 2020 08:17:27 +0000 (09:17 +0100)
The following testcase ICEs, because for TFmode the particular subtraction
pattern (*subtf3) is not enabled with the given options.  Using
expand_simple_binop instead of emitting the subtraction by hand just moves
the ICE one insn later, NEG of ABS is not then recognized, etc., but
ultimately the problem is that when rs6000_emit_cmove is called for floating
point operand mode (and earlier condition ensures that in that case
compare_mode is also floating point), the expander makes sure the
operand mode is SFDF, but for the comparison mode nothing checks it, yet
there is just one *fsel* pattern with 2 separate SFDF iterators.

The following patch fixes it by giving up if compare_mode is not SFmode or
DFmode.

2020-01-21  Jakub Jelinek  <jakub@redhat.com>

PR target/93073
* config/rs6000/rs6000.c (rs6000_emit_cmove): If using fsel, punt for
compare_mode other than SFmode or DFmode.

* gcc.target/powerpc/pr93073.c: New test.

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr93073.c [new file with mode: 0644]

index 0581561f63ddcd1184e3ce5225ac0ab7da08249c..4f38f24317f0f9e9c7728c56748f9b8438de5041 100644 (file)
@@ -1,3 +1,9 @@
+2020-01-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/93073
+       * config/rs6000/rs6000.c (rs6000_emit_cmove): If using fsel, punt for
+       compare_mode other than SFmode or DFmode.
+
 2020-01-21  Kito Cheng  <kito.cheng@sifive.com>
 
        PR target/93304
index 127927d9583a418367f854e51a80ea5afc0150ec..9405816fa5daf9691e691187779cf2a3515c2ace 100644 (file)
@@ -14978,6 +14978,11 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
 
   /* At this point we know we can use fsel.  */
 
+  /* Don't allow compare_mode other than SFmode or DFmode, for others there
+     is no fsel instruction.  */
+  if (compare_mode != SFmode && compare_mode != DFmode)
+    return 0;
+
   /* Reduce the comparison to a comparison against zero.  */
   if (! is_against_zero)
     {
index a901cf978412a18f933b1f2c7107491de3e60b75..b5945f4cd1cac19e185322351ee2d8afa91a0367 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/93073
+       * gcc.target/powerpc/pr93073.c: New test.
+
 2020-01-20  Bin Cheng  <bin.cheng@linux.alibaba.com>
 
        * g++.dg/coroutines/co-return-warning-1.C: New test.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr93073.c b/gcc/testsuite/gcc.target/powerpc/pr93073.c
new file mode 100644 (file)
index 0000000..6a0a473
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/93073 */
+/* { dg-do compile { target powerpc_vsx_ok } } */
+/* { dg-options "-mvsx -O1 -ffinite-math-only -fno-trapping-math" } */
+
+void bar (void);
+
+void
+foo (long double x, double y, double z)
+{
+  for (;;)
+    {
+      double a = x > 0.0 ? y : z;
+      if (a == 0.0)
+       bar ();
+    }
+}