Index: Makefile.in
===================================================================
--- Makefile.in	(revision 191644)
+++ Makefile.in	(working copy)
@@ -2239,21 +2239,21 @@ tree-outof-ssa.o : tree-outof-ssa.c $(TR
    $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \
    $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \
    $(GIMPLE_PRETTY_PRINT_H) langhooks.h
 tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \
-   $(OPTABS_H)
+   $(OPTABS_H) tree-ssa-propagate.h
 tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    langhooks.h $(FLAGS_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    $(TREE_PRETTY_PRINT_H)
 tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
Index: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c	(revision 191644)
+++ tree-ssa-forwprop.c	(working copy)
@@ -27,20 +27,21 @@ along with GCC; see the file COPYING3.
 #include "basic-block.h"
 #include "gimple-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "langhooks.h"
 #include "flags.h"
 #include "gimple.h"
 #include "expr.h"
 #include "cfgloop.h"
 #include "optabs.h"
+#include "tree-ssa-propagate.h"
 
 /* This pass propagates the RHS of assignment statements into use
    sites of the LHS of the assignment.  It's basically a specialized
    form of tree combination.   It is hoped all of this can disappear
    when we have a generalized tree combiner.
 
    One class of common cases we handle is forward propagating a single use
    variable into a COND_EXPR.
 
      bb0:
@@ -2575,39 +2576,49 @@ simplify_bitfield_ref (gimple_stmt_itera
   enum tree_code code;
 
   op = gimple_assign_rhs1 (stmt);
   gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
 
   op0 = TREE_OPERAND (op, 0);
   if (TREE_CODE (op0) != SSA_NAME
       || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
     return false;
 
+  def_stmt = get_prop_source_stmt (op0, false, NULL);
+  if (!def_stmt || !can_propagate_from (def_stmt))
+    return false;
+
+  op1 = TREE_OPERAND (op, 1);
+  op2 = TREE_OPERAND (op, 2);
+  code = gimple_assign_rhs_code (def_stmt);
+
+  if (code == CONSTRUCTOR)
+    {
+      tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),
+			       gimple_assign_rhs1 (def_stmt), op1, op2);
+      if (!tem || !valid_gimple_rhs_p (tem))
+	return false;
+      gimple_assign_set_rhs_from_tree (gsi, tem);
+      update_stmt (gsi_stmt (*gsi));
+      return true;
+    }
+
   elem_type = TREE_TYPE (TREE_TYPE (op0));
   if (TREE_TYPE (op) != elem_type)
     return false;
 
   size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
-  op1 = TREE_OPERAND (op, 1);
   n = TREE_INT_CST_LOW (op1) / size;
   if (n != 1)
     return false;
-
-  def_stmt = get_prop_source_stmt (op0, false, NULL);
-  if (!def_stmt || !can_propagate_from (def_stmt))
-    return false;
-
-  op2 = TREE_OPERAND (op, 2);
   idx = TREE_INT_CST_LOW (op2) / size;
 
-  code = gimple_assign_rhs_code (def_stmt);
-
   if (code == VEC_PERM_EXPR)
     {
       tree p, m, index, tem;
       unsigned nelts;
       m = gimple_assign_rhs3 (def_stmt);
       if (TREE_CODE (m) != VECTOR_CST)
 	return false;
       nelts = VECTOR_CST_NELTS (m);
       idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
       idx %= 2 * nelts;
Index: testsuite/gcc.dg/tree-ssa/forwprop-23.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/forwprop-23.c	(revision 0)
+++ testsuite/gcc.dg/tree-ssa/forwprop-23.c	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));
+
+long f (long d, long e)
+{
+  vec x = { d, e };
+  vec m = { 1, 0 };
+  return __builtin_shuffle (x, m) [1];
+}
+
+
+/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
