re PR target/27158 (ICE in extract_insn with -maltivec)
authorRoger Sayle <roger@eyesopen.com>
Mon, 12 Jun 2006 02:02:14 +0000 (02:02 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 12 Jun 2006 02:02:14 +0000 (02:02 +0000)
PR target/27158
* config/rs6000/rs6000.c (const_vector_elt_as_int): New function to
extract a CONST_VECTOR element and interpret it as an integer.
(vspltis_constant): Use const_vector_elt_as_int instead of the
macro CONST_VECTOR_ELT in order to handle FP vector modes.
* config/rs6000/predicates.md (easy_vector_const): Consider
floating point ALTIVEC_VECTOR_MODEs via easy_altivec_constant.

From-SVN: r114558

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.c

index 16f77b0..0e14efc 100644 (file)
@@ -1,3 +1,13 @@
+2006-06-11  Roger Sayle  <roger@eyesopen.com>
+
+       PR target/27158
+       * config/rs6000/rs6000.c (const_vector_elt_as_int): New function to
+       extract a CONST_VECTOR element and interpret it as an integer.
+       (vspltis_constant): Use const_vector_elt_as_int instead of the
+       macro CONST_VECTOR_ELT in order to handle FP vector modes.
+       * config/rs6000/predicates.md (easy_vector_const): Consider
+       floating point ALTIVEC_VECTOR_MODEs via easy_altivec_constant.
+
 2006-06-11  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR middle-end/27942
index e0486a9..f8e00ff 100644 (file)
     {
       if (zero_constant (op, mode))
         return true;
-      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
-        return false;
-
       return easy_altivec_constant (op, mode);
     }
 
index dd41f62..6d78f84 100644 (file)
@@ -2122,6 +2122,20 @@ num_insns_constant (rtx op, enum machine_mode mode)
     }
 }
 
+/* Interpret element ELT of the CONST_VECTOR OP as an integer value.
+   If the mode of OP is MODE_VECTOR_INT, this simply returns the
+   corresponding element of the vector, but for V4SFmode and V2SFmode,
+   the corresponding "float" is interpreted as an SImode integer.  */
+
+static HOST_WIDE_INT
+const_vector_elt_as_int (rtx op, unsigned int elt)
+{
+  rtx tmp = CONST_VECTOR_ELT (op, elt);
+  if (GET_MODE (op) == V4SFmode
+      || GET_MODE (op) == V2SFmode)
+    tmp = gen_lowpart (SImode, tmp);
+  return INTVAL (tmp);
+}
 
 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
    or vspltisw instruction.  OP is a CONST_VECTOR.  Which instruction is used
@@ -2141,8 +2155,7 @@ vspltis_constant (rtx op, unsigned step, unsigned copies)
   unsigned bitsize = GET_MODE_BITSIZE (inner);
   unsigned mask = GET_MODE_MASK (inner);
 
-  rtx last = CONST_VECTOR_ELT (op, nunits - 1);
-  HOST_WIDE_INT val = INTVAL (last);
+  HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
   HOST_WIDE_INT splat_val = val;
   HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
 
@@ -2182,7 +2195,7 @@ vspltis_constant (rtx op, unsigned step, unsigned copies)
       else
        desired_val = msb_val;
 
-      if (desired_val != INTVAL (CONST_VECTOR_ELT (op, i)))
+      if (desired_val != const_vector_elt_as_int (op, i))
        return false;
     }