diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61fb81a14d14d3634a21f0f2b13d291e318f5766..531a1f90889d7191447bdbfe70731c28e24cb7fc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,46 @@
+2006-12-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+	PR tree-opt/28436
+	* tree.h (DECL_COMPLEX_GIMPLE_REG_P): Rename to ...
+	(DECL_GIMPLE_REG_P): This.
+	* fold-const.c (fold_indirect_ref_1): Fold *(foo *)&vectorfoo into
+	using BIT_FIELD_REF.
+	* omp-low.c (omp_copy_decl_2): Use the renamed DECL_GIMPLE_REG_P.
+	* tree-gimple.c (is_gimple_reg): Use the renamed DECL_GIMPLE_REG_P
+	and check for VECTOR_TYPE.
+	* expr.c (get_inner_reference): Set the mode for BIT_FIELD_REF with
+	vector types.
+	* tree-flow-inline.h (var_can_have_subvars): Use the renamed
+	DECL_GIMPLE_REG_P.
+	* gimplify.c (internal_get_tmp_var): Use the renamed DECL_GIMPLE_REG_P
+	and check for VECTOR_TYPE.
+	(gimplify_bind_expr): Likewise.
+	(gimplify_function_tree): Likewise.
+	* expmed.c: Include target.h.
+	(extract_bit_field): For vector mode, try find a better mode first.
+	If that fails use gen_lowpart (for vectors only).
+	* tree-dfa.c (make_rename_temp): Use the renamed DECL_GIMPLE_REG_P
+	and check for VECTOR_TYPE.
+	* tree-ssa-pre.c (create_expressions_by_pieces): Likewise.
+	(insert_into_preds_of_block): Likewise.
+	(insert_fake_stores): Create gimple register store_tmps for
+	vector types.
+	* tree-sra.c (sra_elt): New field, is_vector_lhs.
+	(sra_walk_expr <case BIT_FIELD_REF>): For vector types that
+	are the left hand side, set the element's is_vector_lhs to true.
+	(instantiate_element): For vector types which were on the left
+	hand size, set DECL_GIMPLE_REG_P to false.
+	* tree-nested.c (create_tmp_var_for): Use the renamed DECL_GIMPLE_REG_P.	* tree-inline.c (declare_return_variable):  Use the renamed
+	DECL_GIMPLE_REG_P
+	and check for VECTOR_TYPE.
+	(copy_decl_to_var):  Use the renamed DECL_GIMPLE_REG_P.
+	(copy_result_decl_to_var): Likewise.
+	* tree-vect-transform.c (vect_get_new_vect_var): For vector types,
+	create a gimple register variable.
+	(vect_permute_store_chain): Set DECL_GIMPLE_REG_P to true for the
+	vect_inter_* temp variables.
+	* Makefile.in (expmed.o): Update dependencies.
+
 2006-12-12  Peter Bergner  <bergner@vnet.ibm.com>
 
 	* reload1.c (eliminate_regs_in_insn): Merge the plus_src "else" and
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0c9fa37779fb88e5dc64c2c1511a91a166b6edc2..ab4f5b81d46999d75a4c1bcff87ad56019a95765 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2230,7 +2230,7 @@ calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(CGRAPH_H) except.h sbitmap.h
 expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(REAL_H) \
-   toplev.h $(TM_P_H) langhooks.h
+   toplev.h $(TM_P_H) langhooks.h $(TARGET_H)
 explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    $(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
    toplev.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 4008c08d2230a2dc44cc00398d5f6feef8eb5bdb..29440d1a5db224f3238b1d4acd6dc4d3715cbca4 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -37,6 +37,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "real.h"
 #include "recog.h"
 #include "langhooks.h"
+#include "target.h"
 
 static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
@@ -1126,6 +1127,28 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       return op0;
     }
 
+  /* See if we can get a better vector mode before extracting.  */
+  if (VECTOR_MODE_P (GET_MODE (op0))
+      && !MEM_P (op0)
+      && GET_MODE_INNER (GET_MODE (op0)) != tmode)
+    {
+      enum machine_mode new_mode;
+      int nunits = GET_MODE_NUNITS (GET_MODE (op0));
+
+      if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
+	new_mode = MIN_MODE_VECTOR_FLOAT;
+      else
+	new_mode = MIN_MODE_VECTOR_INT;
+
+      for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode))
+	if (GET_MODE_NUNITS (new_mode) == nunits
+	    && GET_MODE_INNER (new_mode) == tmode
+	    && targetm.vector_mode_supported_p (new_mode))
+	  break;
+      if (new_mode != VOIDmode)
+	op0 = gen_lowpart (new_mode, op0);
+    }
+
   /* Use vec_extract patterns for extracting parts of vectors whenever
      available.  */
   if (VECTOR_MODE_P (GET_MODE (op0))
@@ -1176,6 +1199,8 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 	{
 	  emit_insn (seq);
 	  emit_insn (pat);
+      	  if (mode0 != mode)
+	    return gen_lowpart (tmode, dest);
 	  return dest;
 	}
     }
diff --git a/gcc/expr.c b/gcc/expr.c
index 9c2d2a64771c9852db3168cb06afc4fc7997ebcd..943a4c44caa4040e7a215ec065184cd6ae31419e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5671,6 +5671,13 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
     {
       size_tree = TREE_OPERAND (exp, 1);
       *punsignedp = BIT_FIELD_REF_UNSIGNED (exp);
+      
+      /* For vector types, with the correct size of access, use the mode of
+	 inner type.  */
+      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
+	  && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
+	  && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
+        mode = TYPE_MODE (TREE_TYPE (exp));
     }
   else
     {
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f1f9c00226181ab81d23938eb1d44c96f761e544..da1bfed173e820fbc1c1c09cbab992b8d9bf1888 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -13094,6 +13094,14 @@ fold_indirect_ref_1 (tree type, tree op0)
       else if (TREE_CODE (optype) == COMPLEX_TYPE
 	       && type == TREE_TYPE (optype))
 	return fold_build1 (REALPART_EXPR, type, op);
+      /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
+      else if (TREE_CODE (optype) == VECTOR_TYPE
+	       && type == TREE_TYPE (optype))
+	{
+	  tree part_width = TYPE_SIZE (type);
+	  tree index = bitsize_int (0);
+	  return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
+	}
     }
 
   /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index efe6b96dcdf6205648d32a48e466457956ee8f22..97745309e98f6d6db61ec9e2b4e7d7ec4e44fa44 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -606,8 +606,9 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
 	}
     }
 
-  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
-    DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
+  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+    DECL_GIMPLE_REG_P (t) = 1;
 
   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
 
@@ -1078,11 +1079,12 @@ gimplify_bind_expr (tree *expr_p, tree *pre_p)
       /* Preliminarily mark non-addressed complex variables as eligible
 	 for promotion to gimple registers.  We'll transform their uses
 	 as we find them.  */
-      if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+      if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+	   || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
 	  && !TREE_THIS_VOLATILE (t)
 	  && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
 	  && !needs_to_live_in_memory (t))
-	DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
+	DECL_GIMPLE_REG_P (t) = 1;
     }
 
   gimple_push_bind_expr (bind_expr);
@@ -3460,7 +3462,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
 
 /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
-   DECL_COMPLEX_GIMPLE_REG_P set.  */
+   DECL_GIMPLE_REG_P set.  */
 
 static enum gimplify_status
 gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
@@ -6372,16 +6374,18 @@ gimplify_function_tree (tree fndecl)
       /* Preliminarily mark non-addressed complex variables as eligible
          for promotion to gimple registers.  We'll transform their uses
          as we find them.  */
-      if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
+      if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
+	   || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
           && !TREE_THIS_VOLATILE (parm)
           && !needs_to_live_in_memory (parm))
-        DECL_COMPLEX_GIMPLE_REG_P (parm) = 1;
+        DECL_GIMPLE_REG_P (parm) = 1;
     }
 
   ret = DECL_RESULT (fndecl);
-  if (TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
+  if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
+	   || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
       && !needs_to_live_in_memory (ret))
-    DECL_COMPLEX_GIMPLE_REG_P (ret) = 1;
+    DECL_GIMPLE_REG_P (ret) = 1;
 
   gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 141efa04b7e1e33a15158a8f7cbb0e69ce9cecb4..ca6aa3afc9274cd06d8977a77a937975614d97c8 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -514,7 +514,7 @@ omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
   tree copy = build_decl (VAR_DECL, name, type);
 
   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
-  DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (var);
+  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
   DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
   DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
   TREE_USED (copy) = 1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 16e08e0590eba1f4153f41a6ec1264220d3dc175..743412569178af8f3d121c4c4234b1b3a34bb3f1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2006-12-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+	PR tree-opt/28436
+	* gcc.c-torture/compile/vector-1.c: New test.
+	* gcc.c-torture/compile/vector-2.c: New test.
+	* gcc.c-torture/compile/vector-3.c: New test.
+
 2006-12-12  Tobias Schlüter  <tobias.schlueter@physik.uni-muenchen.de>
 
 	* lib/fortran-torture.exp: Update copyright years.  Remove
diff --git a/gcc/testsuite/gcc.c-torture/compile/vector-1.c b/gcc/testsuite/gcc.c-torture/compile/vector-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..d22afd55df5593a485902aa8b2277a85c428e69b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/vector-1.c
@@ -0,0 +1,11 @@
+#define vector __attribute__((vector_size(16) ))
+struct ss
+{
+ vector float mVec;
+};
+float getCapsule(vector int t)
+{
+ vector float t1 = (vector float)t;
+ struct ss y = {t1};
+ return *((float*)&y.mVec);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/vector-2.c b/gcc/testsuite/gcc.c-torture/compile/vector-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..930a9c1f8707e5ad3a8abd52c7e6e67c0c3dcb3f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/vector-2.c
@@ -0,0 +1,12 @@
+#define vector __attribute__((vector_size(16) ))
+struct ss
+{
+ vector float mVec;
+};
+vector float getCapsule(vector int t)
+{
+ vector float t1 = (vector float)t;
+ struct ss y = {t1};
+ *((float*)&y.mVec) = 1.0;
+ return y.mVec;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/vector-3.c b/gcc/testsuite/gcc.c-torture/compile/vector-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b731488163109fff6f6a351daebf6f77314b32b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/vector-3.c
@@ -0,0 +1,7 @@
+#define vector __attribute__((vector_size(16) ))
+vector float g(void)
+{
+  float t = 1.0f;
+  return (vector float){0.0, 0.0, t, 0.0};
+}
+
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index f4ad1d2a5d5c642dd6ad4ae6015bd8308e12376b..0aabc80b7a7b9ea5a0524e85ca5f1421919cd861 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -206,8 +206,9 @@ make_rename_temp (tree type, const char *prefix)
 {
   tree t = create_tmp_var (type, prefix);
 
-  if (TREE_CODE (type) == COMPLEX_TYPE)
-    DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
+  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+    DECL_GIMPLE_REG_P (t) = 1;
 
   if (gimple_referenced_vars (cfun))
     {
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index 97dadd4b56423a12ac328d1faf3e86571642221d..e2b4f9791405cc2085c431999c5a25560aa6a149 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -1681,7 +1681,7 @@ var_can_have_subvars (tree v)
   /* Complex types variables which are not also a gimple register can
     have subvars. */
   if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE
-      && !DECL_COMPLEX_GIMPLE_REG_P (v))
+      && !DECL_GIMPLE_REG_P (v))
     return true;
 
   return false;
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
index 60d9afc277d25fddd2ea040a99dd42efe59bc7cc..f3a5db7c2ed6ee295aacd94d88bec61614aa6e62 100644
--- a/gcc/tree-gimple.c
+++ b/gcc/tree-gimple.c
@@ -316,8 +316,9 @@ is_gimple_reg (tree t)
 
   /* Complex values must have been put into ssa form.  That is, no 
      assignments to the individual components.  */
-  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
-    return DECL_COMPLEX_GIMPLE_REG_P (t);
+  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+    return DECL_GIMPLE_REG_P (t);
 
   return true;
 }
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 429cc2cb0f6d1704b8bcaa19a5a32b54b09f5c39..86485e576e543ddb3c8e7fc4b805754bbf801cf9 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1204,10 +1204,11 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
 	var = return_slot_addr;
       else
 	var = build_fold_indirect_ref (return_slot_addr);
-      if (TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
-	  && !DECL_COMPLEX_GIMPLE_REG_P (result)
+      if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
+           || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
+	  && !DECL_GIMPLE_REG_P (result)
 	  && DECL_P (var))
-	DECL_COMPLEX_GIMPLE_REG_P (var) = 0;
+	DECL_GIMPLE_REG_P (var) = 0;
       use = NULL;
       goto done;
     }
@@ -1245,9 +1246,10 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
 	    use_it = false;
 	  else if (is_global_var (base_m))
 	    use_it = false;
-	  else if (TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
-		   && !DECL_COMPLEX_GIMPLE_REG_P (result)
-		   && DECL_COMPLEX_GIMPLE_REG_P (base_m))
+	  else if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
+		    || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
+		   && !DECL_GIMPLE_REG_P (result)
+		   && DECL_GIMPLE_REG_P (base_m))
 	    use_it = false;
 	  else if (!TREE_ADDRESSABLE (base_m))
 	    use_it = true;
@@ -2648,7 +2650,7 @@ copy_decl_to_var (tree decl, copy_body_data *id)
   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
   TREE_READONLY (copy) = TREE_READONLY (decl);
   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
-  DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl);
+  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
 
   return copy_decl_for_dup_finish (id, decl, copy);
 }
@@ -2674,7 +2676,7 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
   if (!DECL_BY_REFERENCE (decl))
     {
       TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
-      DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl);
+      DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
     }
 
   return copy_decl_for_dup_finish (id, decl, copy);
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index ed4a1ae664706b01060d90469603d407cbda7287..42aef32884193b47f76fd803f6e192a189b67afc 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -149,7 +149,7 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
   TREE_CHAIN (tmp_var) = info->new_local_var_chain;
   DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
   if (TREE_CODE (type) == COMPLEX_TYPE)
-    DECL_COMPLEX_GIMPLE_REG_P (tmp_var) = 1;
+    DECL_GIMPLE_REG_P (tmp_var) = 1;
 
   info->new_local_var_chain = tmp_var;
 
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 14507ad3adf84576e88209c0f184a7659a40f532..da338fc28fd8ea34d7e9a09379d14e1b9cd48f04 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -140,6 +140,9 @@ struct sra_elt
 
   /* A flag for use with/after random access traversals.  */
   bool visited;
+
+  /* True if there is BIT_FIELD_REF on the lhs with a vector. */
+  bool is_vector_lhs;
 };
 
 #define IS_ELEMENT_FOR_GROUP(ELEMENT) (TREE_CODE (ELEMENT) == RANGE_EXPR)
@@ -787,9 +790,18 @@ sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
 	break;
 
       case BIT_FIELD_REF:
+	/* A bit field reference to a specific vector is scalarized but for
+	   ones for inputs need to be marked as used on the left hand size so
+	   when we scalarize it, we can mark that variable as non renamable.  */
+	if (is_output && TREE_CODE (TREE_TYPE (TREE_OPERAND (inner, 0))) == VECTOR_TYPE)
+	  {
+	    struct sra_elt *elt = maybe_lookup_element_for_expr (TREE_OPERAND (inner, 0));
+	    elt->is_vector_lhs = true;
+	  }
 	/* A bit field reference (access to *multiple* fields simultaneously)
 	   is not currently scalarized.  Consider this an access to the
 	   complete outer element, to which walk_tree will bring us next.  */
+	  
 	goto use_all;
 
       case VIEW_CONVERT_EXPR:
@@ -1178,6 +1190,12 @@ instantiate_element (struct sra_elt *elt)
   base = base_elt->element;
 
   elt->replacement = var = make_rename_temp (elt->type, "SR");
+
+  /* For vectors, if used on the left hand side with BIT_FIELD_REF,
+     they are not a gimple register.  */
+  if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE && elt->is_vector_lhs)
+    DECL_GIMPLE_REG_P (var) = 0;
+
   DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
   DECL_ARTIFICIAL (var) = 1;
 
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index c4a01839b185214104f503712a6553371d1e387a..871006dc232aea1113e3d38f42ef80c75601e053 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2630,8 +2630,9 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts)
   temp = pretemp;
   add_referenced_var (temp);
 
-  if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
-    DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
+  if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE
+      || TREE_CODE (TREE_TYPE (expr)) == VECTOR_TYPE)
+    DECL_GIMPLE_REG_P (temp) = 1;
 
   newexpr = build2_gimple (GIMPLE_MODIFY_STMT, temp, newexpr);
   name = make_ssa_name (temp, newexpr);
@@ -2778,8 +2779,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
   temp = prephitemp;
   add_referenced_var (temp);
 
-  if (TREE_CODE (type) == COMPLEX_TYPE)
-    DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
+
+  if (TREE_CODE (type) == COMPLEX_TYPE
+      || TREE_CODE (type) == VECTOR_TYPE)
+    DECL_GIMPLE_REG_P (temp) = 1;
   temp = create_phi_node (temp, block);
 
   NECESSARY (temp) = 0;
@@ -3535,6 +3538,8 @@ insert_fake_stores (void)
 	      if (!storetemp || TREE_TYPE (rhs) != TREE_TYPE (storetemp))
 		{
 		  storetemp = create_tmp_var (TREE_TYPE (rhs), "storetmp");
+		  if (TREE_CODE (TREE_TYPE (storetemp)) == VECTOR_TYPE)
+		    DECL_GIMPLE_REG_P (storetemp) = 1;
 		  get_var_ann (storetemp);
 		}
 
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index f83d92a39ff269bce7a1ea4a0a4aeb34d610a44d..401e35871827509f4221358e62b3410a7f10a011 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -106,6 +106,10 @@ vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
   else
     new_vect_var = create_tmp_var (type, prefix);
 
+  /* Mark vector typed variable as a gimple register variable.  */
+  if (TREE_CODE (type) == VECTOR_TYPE)
+    DECL_GIMPLE_REG_P (new_vect_var) = true;
+
   return new_vect_var;
 }
 
@@ -2598,6 +2602,7 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
              and in the case of little endian: 
                                 high = interleave_low (vect1, vect2).  */
 	  perm_dest = create_tmp_var (vectype, "vect_inter_high");
+	  DECL_GIMPLE_REG_P (perm_dest) = 1;
 	  add_referenced_var (perm_dest);
           if (BYTES_BIG_ENDIAN)
 	    perm_stmt = build2 (GIMPLE_MODIFY_STMT, void_type_node, perm_dest,
@@ -2618,6 +2623,7 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
              and in the case of little endian:
                                low  = interleave_high (vect1, vect2).  */     
 	  perm_dest = create_tmp_var (vectype, "vect_inter_low");
+	  DECL_GIMPLE_REG_P (perm_dest) = 1;
 	  add_referenced_var (perm_dest);
 	  if (BYTES_BIG_ENDIAN)
 	    perm_stmt = build2 (GIMPLE_MODIFY_STMT, void_type_node, perm_dest,
diff --git a/gcc/tree.h b/gcc/tree.h
index f0bb850a1be24ff6c029212a2ce61314c365283d..f88c244146f73dab6586b4f731e16a891556514e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2598,12 +2598,13 @@ struct tree_memory_partition_tag GTY(())
 #define DECL_PRESERVE_P(DECL) \
   DECL_COMMON_CHECK (DECL)->decl_common.preserve_flag
 
-/* For function local variables of COMPLEX type, indicates that the
-   variable is not aliased, and that all modifications to the variable
-   have been adjusted so that they are killing assignments.  Thus the
-   variable may now be treated as a GIMPLE register, and use real
-   instead of virtual ops in SSA form.  */
-#define DECL_COMPLEX_GIMPLE_REG_P(DECL) \
+/* For function local variables of COMPLEX and VECTOR types,
+   indicates that the variable is not aliased, and that all
+   modifications to the variable have been adjusted so that
+   they are killing assignments.  Thus the variable may now
+   be treated as a GIMPLE register, and use real instead of
+   virtual ops in SSA form.  */
+#define DECL_GIMPLE_REG_P(DECL) \
   DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
 
 /* This is true if DECL is call clobbered in the current function.