diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 880dff8ded647f45eee2b5ec69140c7d4d10d632..9c3c9e2d4f8870c807587b04a4c7c58702b53ab0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-01-31  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/56157
+	* tree-vect-slp.c (vect_get_slp_defs): More thoroughly try to
+	match up operand with SLP child.
+
 2013-01-31  Jason Merrill  <jason@redhat.com>
 
 	PR c++/54410
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2632cd06d07cdc0139277f1b8ea5ec2ceb624248..7a8baa6e9051f9133ce94cd50b0d60400f2becd2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-01-31  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/56157
+	* gcc.dg/torture/pr56157.c: New testcase.
+
 2013-01-30  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/56150
diff --git a/gcc/testsuite/gcc.dg/torture/pr56157.c b/gcc/testsuite/gcc.dg/torture/pr56157.c
new file mode 100644
index 0000000000000000000000000000000000000000..796e3235c299d7d990ef94076783f52ba2257caa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr56157.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-ftree-vectorize" } */
+
+struct Pixel {
+    unsigned short r;
+    unsigned short g;
+    unsigned short b;
+    unsigned short a;
+};
+
+void fn(unsigned char * __restrict dst, const unsigned char * __restrict src)
+{
+  unsigned x;
+  for(x = 0; x < 1024; x += 1)
+    {
+      struct Pixel pixel;
+      pixel.r = (unsigned short)(((unsigned)src[0]) * 0xffff / 0xff);
+      pixel.g = (unsigned short)(((unsigned)src[1]) * 0xffff / 0xff);
+      pixel.b = (unsigned short)(((unsigned)src[2]) * 0xffff / 0xff);
+      pixel.a = (unsigned short)(((unsigned)src[3]) * 0xffff / 0xff);
+      __builtin_memcpy(dst, &pixel, sizeof pixel);
+      src += 4;
+      dst += 8;
+    }
+}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 941661e0edc18e42793c79f15970b0e62fbb4b21..36f81299d5c5ace6b243ccd40d00d3feff8d8983 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2616,13 +2616,13 @@ void
 vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
                    vec<slp_void_p> *vec_oprnds, int reduc_index)
 {
-  gimple first_stmt, first_def;
+  gimple first_stmt;
   int number_of_vects = 0, i;
   unsigned int child_index = 0;
   HOST_WIDE_INT lhs_size_unit, rhs_size_unit;
   slp_tree child = NULL;
   vec<tree> *vec_defs;
-  tree oprnd, def_lhs;
+  tree oprnd;
   bool vectorized_defs;
 
   first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
@@ -2638,29 +2638,22 @@ vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
       if (SLP_TREE_CHILDREN (slp_node).length () > child_index)
         {
           child = (slp_tree) SLP_TREE_CHILDREN (slp_node)[child_index];
-          first_def = SLP_TREE_SCALAR_STMTS (child)[0];
-
-	  /* In the end of a pattern sequence we have a use of the original stmt,
-	     so we need to compare OPRND with the original def.  */
-          if (is_pattern_stmt_p (vinfo_for_stmt (first_def))
-	      && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt))
-              && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt)))
-            first_def = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def));
 
-          if (is_gimple_call (first_def))
-            def_lhs = gimple_call_lhs (first_def);
-          else
-            def_lhs = gimple_assign_lhs (first_def);
+	  /* We have to check both pattern and original def, if available.  */
+	  gimple first_def = SLP_TREE_SCALAR_STMTS (child)[0];
+	  gimple related = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def));
 
-          if (operand_equal_p (oprnd, def_lhs, 0))
-            {
-              /* The number of vector defs is determined by the number of
-                 vector statements in the node from which we get those
+	  if (operand_equal_p (oprnd, gimple_get_lhs (first_def), 0)
+	      || (related
+		  && operand_equal_p (oprnd, gimple_get_lhs (related), 0)))
+	    {
+	      /* The number of vector defs is determined by the number of
+		 vector statements in the node from which we get those
 		 statements.  */
-                 number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child);
-                 vectorized_defs = true;
+	      number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child);
+	      vectorized_defs = true;
 	      child_index++;
-            }
+	    }
         }
 
       if (!vectorized_defs)