gcc-patches@gcc.gnu.org
[Top] [All Lists]

[power7-meissner] Patch to disable V2DImode in Altivec mode & fix copysi

Subject: [power7-meissner] Patch to disable V2DImode in Altivec mode & fix copysign/unspec suggestions
From: Michael Meissner
Date: Tue, 28 Jul 2009 14:44:31 -0400
This patch disables allowing V2DImode type in altivec mode, because altivec
doesn't have the support for set, init, and extract.  This brings us back to
the previous status quo.

The patch also makes the changes that David suggested for using CONST0_RTX for
the copysign builtin instead of (const_int 0), and changing the UNSPEC number
of VCMPBFP so it doesn't clash with the unspecs in rs6000.md.

2009-07-28  Michael Meissner  <meissner@xxxxxxxxxxxxxxxxxx>

        * config/rs6000/vector.md (vector_copysign<mode>3): Use
        CONST0_RTX, not integer constant 0 in RTL expansion.
        * config/rs6000/vsx.md (vsx_copysign<mode>3): Ditto.
        * config/rs6000/rs6000.md (copysigndf3): Ditto.

        * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Do not
        allow V2DImode under Altivec, since it doesn't have vector set,
        extract, or splat support.
        (rs6000_expand_vector_init): Ditto.
        (rs6000_expand_vector_set): Ditto.
        (rs6000_expand_vector_extract): Ditto.

        * config/rs6000/vsx.md (vsx_copysign<mode>3): Use CONST0_RTX, not
        constant 0 in comparison.
        (vsx_extract_<mode>_one): Delete, because it wasn't being
        recognized.

        * config/rs6000/altivec.md (UNSPEC_VCMPBFP): Move to 64 to avoid
        overlap with rs6000.md.

Index: gcc/config/rs6000/vector.md
===================================================================
--- gcc/config/rs6000/vector.md (revision 149953)
+++ gcc/config/rs6000/vector.md (working copy)
@@ -294,7 +294,7 @@ (define_expand "vector_copysign<mode>3"
   [(set (match_operand:VEC_F 0 "vfloat_operand" "")
        (if_then_else:VEC_F
         (ge:VEC_F (match_operand:VEC_F 2 "vfloat_operand" "")
-                  (const_int 0))
+                  (match_dup 3))
         (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" ""))
         (neg:VEC_F (abs:VEC_F (match_dup 1)))))]
   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
@@ -306,6 +306,8 @@ (define_expand "vector_copysign<mode>3"
                                             operands[2]));
       DONE;
     }
+
+  operands[3] = CONST0_RTX (<MODE>mode);
 }")
 
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 150066)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -1875,20 +1875,14 @@ rs6000_init_hard_regno_mode_ok (void)
        }
     }
 
-  /* V2DImode, prefer vsx over altivec, since the main use will be for
-     vectorized floating point conversions.  */
+  /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
+     Altivec doesn't have 64-bit support.  */
   if (TARGET_VSX)
     {
       rs6000_vector_mem[V2DImode] = VECTOR_VSX;
       rs6000_vector_unit[V2DImode] = VECTOR_NONE;
       rs6000_vector_align[V2DImode] = align64;
     }
-  else if (TARGET_ALTIVEC)
-    {
-      rs6000_vector_mem[V2DImode] = VECTOR_ALTIVEC;
-      rs6000_vector_unit[V2DImode] = VECTOR_NONE;
-      rs6000_vector_align[V2DImode] = align64;
-    }
 
   /* DFmode, see if we want to use the VSX unit.  */
   if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
@@ -4252,8 +4246,9 @@ rs6000_expand_vector_init (rtx target, r
       return;
     }
 
-  /* Store value to stack temp.  Load vector element.  Splat.  */
-  if (all_same)
+  /* Store value to stack temp.  Load vector element.  Splat.  However, splat
+     of 64-bit items is not supported on Altivec.  */
+  if (all_same && GET_MODE_SIZE (mode) <= 4)
     {
       mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
       emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
@@ -4311,11 +4306,10 @@ rs6000_expand_vector_set (rtx target, rt
   int width = GET_MODE_SIZE (inner_mode);
   int i;
 
-  if (mode == V2DFmode || mode == V2DImode)
+  if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
     {
       rtx (*set_func) (rtx, rtx, rtx, rtx)
        = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
-      gcc_assert (TARGET_VSX);
       emit_insn (set_func (target, target, val, GEN_INT (elt)));
       return;
     }
@@ -4357,11 +4351,10 @@ rs6000_expand_vector_extract (rtx target
   enum machine_mode inner_mode = GET_MODE_INNER (mode);
   rtx mem, x;
 
-  if (mode == V2DFmode || mode == V2DImode)
+  if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
     {
       rtx (*extract_func) (rtx, rtx, rtx)
        = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
-      gcc_assert (TARGET_VSX);
       emit_insn (extract_func (target, vec, GEN_INT (elt)));
       return;
     }
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md    (revision 150066)
+++ gcc/config/rs6000/vsx.md    (working copy)
@@ -900,7 +900,7 @@ (define_insn "vsx_copysign<mode>3"
   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
        (if_then_else:VSX_B
         (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")
-                  (const_int 0))
+                  (match_operand:VSX_B 3 "zero_constant" "j,j"))
         (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa"))
         (neg:VSX_B (abs:VSX_B (match_dup 1)))))]
   "VECTOR_UNIT_VSX_P (<MODE>mode)"
@@ -1226,18 +1226,6 @@ (define_insn "*vsx_extract_<mode>_zero"
   [(set_attr "type" "fpload")
    (set_attr "length" "4")])  
 
-;; Optimize element 1 for a single pointer reference using the traditional
-;; offsetable memory load
-(define_insn "*vsx_extract_<mode>_one"
-  [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=d")
-       (vec_select:<VS_scalar>
-        (mem:VSX_D (match_operand:P 1 "gpc_reg_operand" "b"))
-        (parallel [(const_int 1)])))]
-  "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN"
-  "lfd %0,4(%1)"
-  [(set_attr "type" "fpload")
-   (set_attr "length" "4")])  
-
 ;; General double word oriented permute, allow the other vector types for
 ;; optimizing the permute instruction.
 (define_insn "vsx_xxpermdi_<mode>"
Index: gcc/config/rs6000/altivec.md
===================================================================
--- gcc/config/rs6000/altivec.md        (revision 149953)
+++ gcc/config/rs6000/altivec.md        (working copy)
@@ -20,8 +20,8 @@
 ;; <http://www.gnu.org/licenses/>.
 
 (define_constants
-  [(UNSPEC_VCMPBFP       50)
    ;; 51-62 deleted
+  [(UNSPEC_VCMPBFP       64)
    (UNSPEC_VMSUMU        65)
    (UNSPEC_VMSUMM        66)
    (UNSPEC_VMSUMSHM      68)
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 150066)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -5911,7 +5911,7 @@ (define_expand "copysigndf3"
      if (VECTOR_UNIT_VSX_P (DFmode))
        {
         emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1],
-                                        operands[2]));
+                                        operands[2], CONST0_RTX (DFmode)));
         DONE;
        }
      operands[3] = gen_reg_rtx (DFmode);


-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@xxxxxxxxxxxxxxxxxx

<Prev in Thread] Current Thread [Next in Thread>
  • [power7-meissner] Patch to disable V2DImode in Altivec mode & fix copysign/unspec suggestions, Michael Meissner <=