This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Abort in output_vec_const_move





> Hi Hartmut.

> Before I take a closer look at this... Since we are duplicating the
> code below in easy_vector_constant, can you come up with a generic way
>(be it macros or a separate function) to avoid duplicating all this
> code.  (Preferably a separate function).

Yes, you are right ...
Look at the new patch below (bootstrapped / tested with gcc-3.4)
      regards, Hartmut

testsuite/ChangeLog

 2004-03-22  Hartmut Penner  <hpenner@de.ibm.com>

      * gcc.dg/altivec-11.c: Extend test for more valid cases.

gcc/ChangeLog

 2004-03-22  Hartmut Penner  <hpenner@de.ibm.com>

      * config/rs6000/rs6000.c (output_vec_const_move):
      Find all cases of EASY_VECTOR_15_ADD_SELF.
      (easy_vector_constant_add_self): Accept
      all vector constant loadable by vsplt* and vadd*.
      (easy_vector_splat_const): New function.
      * config/rs6000/altivec.md (movv4si): Change to
      emit move insn with halfed vector constant.

Index: gcc/config/rs6000/altivec.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/altivec.md,v
retrieving revision 1.12.4.1
diff -u -p -r1.12.4.1 altivec.md
--- gcc/config/rs6000/altivec.md    12 Feb 2004 14:17:53 -0000    1.12.4.1
+++ gcc/config/rs6000/altivec.md    23 Mar 2004 15:29:24 -0000
@@ -124,13 +124,22 @@
   [(set (match_operand:V4SI 0 "altivec_register_operand" "")
      (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-     (unspec:V4SI [(match_dup 3)] UNSPEC_VSPLTISW))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
      (plus:V4SI (match_dup 0)
               (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1);
}")
+{
+  int i, units;
+  rtvec v;
+  units = GET_MODE_NUNITS (GET_MODE (operands[1]));
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < units; i++)
+    RTVEC_ELT (v, i) =
+      GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], i)) >> 1);
+  operands[3] = gen_rtx_raw_CONST_VECTOR (GET_MODE (operands[1]), v);
+}")

 (define_expand "movv8hi"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")

@@ -172,13 +181,22 @@
   [(set (match_operand:V8HI 0 "altivec_register_operand" "")
      (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-     (unspec:V8HI [(match_dup 3)] UNSPEC_VSPLTISH))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
      (plus:V8HI (match_dup 0)
               (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }")
+{
+  int i, units;
+  rtvec v;
+  units = GET_MODE_NUNITS (GET_MODE (operands[1]));
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < units; i++)
+    RTVEC_ELT (v, i) =
+      GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], i)) >> 1);
+  operands[3] = gen_rtx_raw_CONST_VECTOR (GET_MODE (operands[1]), v);
+}")

 (define_expand "movv16qi"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
@@ -220,13 +238,22 @@
   [(set (match_operand:V16QI 0 "altivec_register_operand" "")
      (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-     (unspec:V16QI [(match_dup 3)] UNSPEC_VSPLTISB))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
      (plus:V16QI (match_dup 0)
               (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }")
+{
+  int i, units;
+  rtvec v;
+  units = GET_MODE_NUNITS (GET_MODE (operands[1]));
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < units; i++)
+    RTVEC_ELT (v, i) =
+      GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], i)) >> 1);
+  operands[3] = gen_rtx_raw_CONST_VECTOR (GET_MODE (operands[1]), v);
+}")

 (define_expand "movv4sf"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.576.2.15
diff -u -p -r1.576.2.15 rs6000.c
--- gcc/config/rs6000/rs6000.c      15 Mar 2004 23:22:49 -0000    1.576.2.15
+++ gcc/config/rs6000/rs6000.c      23 Mar 2004 15:29:31 -0000
@@ -60,12 +60,9 @@
 #define TARGET_NO_PROTOTYPE 0
 #endif

-#define EASY_VECTOR_15(n, x, y) ((n) >= -16 && (n) <= 15 \
-                        && easy_vector_same (x, y))
-
-#define EASY_VECTOR_15_ADD_SELF(n, x, y) ((n) >= 0x10 && (n) <= 0x1e \
-                                          && !((n) & 1)              \
-                               && easy_vector_same (x, y))
+#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
+#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \
+                                          && !((n) & 1))

 #define min(A,B) ((A) < (B) ? (A) : (B))
 #define max(A,B) ((A) > (B) ? (A) : (B))
@@ -382,6 +379,7 @@ static void is_altivec_return_reg (rtx,
 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
 int easy_vector_constant (rtx, enum machine_mode);
 static int easy_vector_same (rtx, enum machine_mode);
+static int easy_vector_splat_const (int, enum machine_mode);
 static bool is_ev64_opaque_type (tree);
 static rtx rs6000_dwarf_register_span (rtx);
 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
@@ -1628,6 +1626,38 @@ easy_fp_constant (rtx op, enum machine_m
     abort ();
 }

+/* Returns the constant for the splat instrunction, if exists.  */
+
+static int
+easy_vector_splat_const (int cst, enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case V4SImode:
+      if (EASY_VECTOR_15 (cst)
+       || EASY_VECTOR_15_ADD_SELF (cst))
+     return cst;
+      if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
+     break;
+      cst = cst >> 16;
+    case V8HImode:
+      if (EASY_VECTOR_15 (cst)
+       || EASY_VECTOR_15_ADD_SELF (cst))
+     return cst;
+      if ((cst & 0xff) != ((cst >> 8) & 0xff))
+     break;
+      cst = cst >> 8;
+    case V16QImode:
+       if (EASY_VECTOR_15 (cst)
+           || EASY_VECTOR_15_ADD_SELF (cst))
+         return cst;
+    default:
+      break;
+    }
+  return 0;
+}
+
+
 /* Return nonzero if all elements of a vector have the same value.  */

 static int
@@ -1641,7 +1671,7 @@ easy_vector_same (rtx op, enum machine_m
   for (i = 1; i < units; ++i)
     if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
       break;
-  if (i == units)
+  if (i == units && easy_vector_splat_const (cst, mode))
     return 1;
   return 0;
 }
@@ -1687,31 +1717,14 @@ easy_vector_constant (rtx op, enum machi
       && cst2 >= -0x7fff && cst2 <= 0x7fff)
     return 1;

-  if (TARGET_ALTIVEC)
-    switch (mode)
-      {
-      case V4SImode:
-     if (EASY_VECTOR_15 (cst, op, mode))
-       return 1;
-     if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
-       break;
-     cst = cst >> 16;
-      case V8HImode:
-     if (EASY_VECTOR_15 (cst, op, mode))
-       return 1;
-     if ((cst & 0xff) != ((cst >> 8) & 0xff))
-       break;
-     cst = cst >> 8;
-      case V16QImode:
-     if (EASY_VECTOR_15 (cst, op, mode))
-       return 1;
-      default:
-     break;
-      }
-
-  if (TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode))
-    return 1;
-
+  if (TARGET_ALTIVEC
+      && easy_vector_same (op, mode))
+    {
+      cst = easy_vector_splat_const (cst, mode);
+      if (EASY_VECTOR_15_ADD_SELF (cst)
+       || EASY_VECTOR_15 (cst))
+     return 1;
+    }
   return 0;
 }

@@ -1721,13 +1734,15 @@ int
 easy_vector_constant_add_self (rtx op, enum machine_mode mode)
 {
   int cst;
-
-  if (!easy_vector_constant (op, mode))
-    return 0;
-
-  cst = INTVAL (CONST_VECTOR_ELT (op, 0));
-
-  return TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode);
+  if (TARGET_ALTIVEC
+      && GET_CODE (op) == CONST_VECTOR
+      && easy_vector_same (op, mode))
+    {
+      cst = easy_vector_splat_const (INTVAL (CONST_VECTOR_ELT (op, 0)), mode);
+      if (EASY_VECTOR_15_ADD_SELF (cst))
+     return 1;
+    }
+  return 0;
 }

 const char *
@@ -1748,33 +1763,37 @@ output_vec_const_move (rtx *operands)
     {
       if (zero_constant (vec, mode))
      return "vxor %0,%0,%0";
-      else if (EASY_VECTOR_15_ADD_SELF (cst, vec, mode))
-     return "#";
       else if (easy_vector_constant (vec, mode))
      {
        operands[1] = GEN_INT (cst);
        switch (mode)
          {
          case V4SImode:
-           if (EASY_VECTOR_15 (cst, vec, mode))
+           if (EASY_VECTOR_15 (cst))
            {
              operands[1] = GEN_INT (cst);
              return "vspltisw %0,%1";
            }
+           else if (EASY_VECTOR_15_ADD_SELF (cst))
+           return "#";
            cst = cst >> 16;
          case V8HImode:
-           if (EASY_VECTOR_15 (cst, vec, mode))
+           if (EASY_VECTOR_15 (cst))
            {
              operands[1] = GEN_INT (cst);
              return "vspltish %0,%1";
            }
+           else if (EASY_VECTOR_15_ADD_SELF (cst))
+           return "#";
            cst = cst >> 8;
          case V16QImode:
-           if (EASY_VECTOR_15 (cst, vec, mode))
+           if (EASY_VECTOR_15 (cst))
            {
              operands[1] = GEN_INT (cst);
              return "vspltisb %0,%1";
            }
+           else if (EASY_VECTOR_15_ADD_SELF (cst))
+           return "#";
          default:
            abort ();
          }
Index: gcc/testsuite/gcc.dg/altivec-11.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/altivec-11.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-11.c
--- gcc/testsuite/gcc.dg/altivec-11.c     8 Jan 2004 07:27:09 -0000     1.1
+++ gcc/testsuite/gcc.dg/altivec-11.c     23 Mar 2004 15:29:31 -0000
@@ -22,6 +22,10 @@ bar (void)
   foo ((vector int) {0x1010101, 0x1010101, 0x1010101, 0x1010101});
   foo ((vector int) {0xf0f0f0f, 0xf0f0f0f, 0xf0f0f0f, 0xf0f0f0f});
   foo ((vector int) {0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0});
+  foo ((vector int) {0x10101010, 0x10101010, 0x10101010, 0x10101010});
+  foo ((vector int) {0x1e1e1e1e, 0x1e1e1e1e, 0x1e1e1e1e, 0x1e1e1e1e});
+  foo ((vector int) {0x100010, 0x100010, 0x100010, 0x100010});
+  foo ((vector int) {0x1e001e, 0x1e001e, 0x1e001e, 0x1e001e});
   foo ((vector int) {0x10, 0x10, 0x10, 0x10});
   foo ((vector int) {0x1e, 0x1e, 0x1e, 0x1e});

@@ -33,6 +37,10 @@ bar (void)
                         0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0});
   foo_s ((vector short int) {0xf0f, 0xf0f, 0xf0f, 0xf0f,
                         0xf0f, 0xf0f, 0xf0f, 0xf0f});
+  foo_s ((vector short int) {0x1010, 0x1010, 0x1010, 0x1010,
+                        0x1010, 0x1010, 0x1010, 0x1010});
+  foo_s ((vector short int) {0x1e1e, 0x1e1e, 0x1e1e, 0x1e1e,
+                        0x1e1e, 0x1e1e, 0x1e1e, 0x1e1e});

   foo_c ((vector char) {0, 0, 0, 0, 0, 0, 0, 0,
                    0, 0, 0, 0, 0, 0, 0, 0});
@@ -42,4 +50,9 @@ bar (void)
                    15, 15, 15, 15, 15, 15, 15, 15});
   foo_c ((vector char) {-16, -16, -16, -16, -16, -16, -16, -16,
                    -16, -16, -16, -16, -16, -16, -16, -16});
+  foo_c ((vector char) {16, 16, 16, 16, 16, 16, 16, 16,
+                   16, 16, 16, 16, 16, 16, 16, 16});
+  foo_c ((vector char) {30, 30, 30, 30, 30, 30, 30, 30,
+                   30, 30, 30, 30, 30, 30, 30, 30});
+
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]