re PR target/78900 (ICE in gcc.target/powerpc/signbit-3.c)
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Wed, 4 Jan 2017 04:32:48 +0000 (04:32 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 4 Jan 2017 04:32:48 +0000 (04:32 +0000)
[gcc]
2016-12-30  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/78900
* config/rs6000/rs6000.c (rs6000_split_signbit): Change some
assertions.  Add support for doing the signbit if the IEEE 128-bit
floating point value is in a GPR.
* config/rs6000/rs6000.md (Fsignbit): Delete.
(signbit<mode>2_dm): Delete using <Fsignbit> and just use "wa".
Update the length attribute if the value is in a GPR.
(signbit<mode>2_dm_<su>ext): Add combiner pattern to eliminate
the sign or zero extension instruction, since the value is always
0/1.
(signbit<mode>2_dm2): Delete using <Fsignbit>.

2017-01-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/78953
* config/rs6000/vsx.md (vsx_extract_<mode>_store_p9): If we are
extracting SImode to a GPR register so that we can generate a
store, limit the vector to be in a traditional Altivec register
for the vextuwrx instruction.

[gcc/testsuite]
2017-01-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/78953
* gcc.target/powerpc/pr78953.c: New test.

From-SVN: r244044

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

index f7cf7c98151ea47e9d42fd97a321218bfe92fd91..3114e02af6734b35ac409c0332b0ad396b08dbb4 100644 (file)
@@ -1,3 +1,23 @@
+2016-12-30  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/78900
+       * config/rs6000/rs6000.c (rs6000_split_signbit): Change some
+       assertions.  Add support for doing the signbit if the IEEE 128-bit
+       floating point value is in a GPR.
+       * config/rs6000/rs6000.md (Fsignbit): Delete.
+       (signbit<mode>2_dm): Delete using <Fsignbit> and just use "wa".
+       Update the length attribute if the value is in a GPR.
+       (signbit<mode>2_dm_<su>ext): Add combiner pattern to eliminate
+       the sign or zero extension instruction, since the value is always
+       0/1.
+       (signbit<mode>2_dm2): Delete using <Fsignbit>.
+
+       PR target/78953
+       * config/rs6000/vsx.md (vsx_extract_<mode>_store_p9): If we are
+       extracting SImode to a GPR register so that we can generate a
+       store, limit the vector to be in a traditional Altivec register
+       for the vextuwrx instruction.
+
 2017-01-03  Ian Lance Taylor  <iant@google.com>
 
        * godump.c (go_format_type): Treat ENUMERAL_TYPE like
index a54ab4809a3cc57a8cb549604b82fbdbbb98d754..a287a2363b38d8ae3341f7ac7c37e0c906f83732 100644 (file)
@@ -25170,9 +25170,7 @@ rs6000_split_signbit (rtx dest, rtx src)
   rtx dest_di = (d_mode == DImode) ? dest : gen_lowpart (DImode, dest);
   rtx shift_reg = dest_di;
 
-  gcc_assert (REG_P (dest));
-  gcc_assert (REG_P (src) || MEM_P (src));
-  gcc_assert (s_mode == KFmode || s_mode == TFmode);
+  gcc_assert (FLOAT128_IEEE_P (s_mode) && TARGET_POWERPC64);
 
   if (MEM_P (src))
     {
@@ -25184,17 +25182,20 @@ rs6000_split_signbit (rtx dest, rtx src)
 
   else
     {
-      unsigned int r = REGNO (src);
+      unsigned int r = reg_or_subregno (src);
 
-      /* If this is a VSX register, generate the special mfvsrd instruction
-        to get it in a GPR.  Until we support SF and DF modes, that will
-        always be true.  */
-      gcc_assert (VSX_REGNO_P (r));
+      if (INT_REGNO_P (r))
+       shift_reg = gen_rtx_REG (DImode, r + (BYTES_BIG_ENDIAN == 0));
 
-      if (s_mode == KFmode)
-       emit_insn (gen_signbitkf2_dm2 (dest_di, src));
       else
-       emit_insn (gen_signbittf2_dm2 (dest_di, src));
+       {
+         /* Generate the special mfvsrd instruction to get it in a GPR.  */
+         gcc_assert (VSX_REGNO_P (r));
+         if (s_mode == KFmode)
+           emit_insn (gen_signbitkf2_dm2 (dest_di, src));
+         else
+           emit_insn (gen_signbittf2_dm2 (dest_di, src));
+       }
     }
 
   emit_insn (gen_lshrdi3 (dest_di, shift_reg, GEN_INT (63)));
index 3651fa6bce2b4a5f3eb3e20fd84c3ff0dcdb3cd3..7e103b019f0dda22e913bd34c4192c63da610a76 100644 (file)
 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
                               (TF "FLOAT128_VECTOR_P (TFmode)")])
 
-(define_mode_attr Fsignbit     [(KF "wa")
-                                (TF "wa")])
-
 ; Iterator for ISA 3.0 supported floating point types
 (define_mode_iterator FP_ISA3 [SF
                               DF
 (define_insn_and_split "signbit<mode>2_dm"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
        (unspec:SI
-        [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
+        [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
         UNSPEC_SIGNBIT))]
   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
   "#"
   rs6000_split_signbit (operands[0], operands[1]);
   DONE;
 }
- [(set_attr "length" "8,8,12")
+ [(set_attr "length" "8,8,4")
+  (set_attr "type" "mftgpr,load,integer")])
+
+(define_insn_and_split "*signbit<mode>2_dm_<su>ext"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
+       (any_extend:DI
+        (unspec:SI
+         [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
+         UNSPEC_SIGNBIT)))]
+  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  rs6000_split_signbit (operands[0], operands[1]);
+  DONE;
+}
+ [(set_attr "length" "8,8,4")
   (set_attr "type" "mftgpr,load,integer")])
 
 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
 ;; special pattern to avoid using a normal movdi.
 (define_insn "signbit<mode>2_dm2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
+       (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
                    (const_int 0)]
                   UNSPEC_SIGNBIT))]
   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
index e3135530f27b64f847d38698bc11ce68ab5f71c7..6264e6c72069831c2f0fa6dde08047830049d50a 100644 (file)
 (define_insn_and_split "*vsx_extract_<mode>_store_p9"
   [(set (match_operand:<VS_scalar> 0 "memory_operand" "=Z,m")
        (vec_select:<VS_scalar>
-        (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>,<VSX_EX>")
+        (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>,v")
         (parallel [(match_operand:QI 2 "const_int_operand" "n,n")])))
    (clobber (match_scratch:<VS_scalar> 3 "=<VSX_EX>,&r"))
    (clobber (match_scratch:SI 4 "=X,&r"))]
index 3b448dd98f9d1b7312853a0918313a09fc5df5c6..cd2a065ec14cf55164c00157ef41ea50c1e8d147 100644 (file)
@@ -1,3 +1,8 @@
+2017-01-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/78953
+       * gcc.target/powerpc/pr78953.c: New test.
+
 2017-01-03  Ian Lance Taylor  <iant@google.com>
 
        * gcc.misc-tests/godump-1.c: Update for accurate representation of
diff --git a/gcc/testsuite/gcc.target/powerpc/pr78953.c b/gcc/testsuite/gcc.target/powerpc/pr78953.c
new file mode 100644 (file)
index 0000000..34a3083
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9 -O2 -mupper-regs-di" } */
+
+#include <altivec.h>
+
+/* PR 78953: mem = vec_extract (V4SI, <n>) failed if the vector was in a
+   traditional FPR register.  */
+
+void
+foo (vector int *vp, int *ip)
+{
+  vector int v = *vp;
+  __asm__ (" # fpr %x0" : "+d" (v));
+  ip[4] = vec_extract (v, 0);
+}
+
+/* { dg-final { scan-assembler "xxextractuw\|vextuw\[lr\]x" } } */