Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c	2017-05-18 07:51:12.387750673 +0100
+++ gcc/tree-vect-slp.c	2017-06-01 07:21:44.094320070 +0100
@@ -671,6 +671,13 @@ vect_build_slp_tree_1 (vec_info *vinfo,
               first_op1 = gimple_assign_rhs2 (stmt);
             }
 	}
+      else if ((TREE_CODE_CLASS (rhs_code) == tcc_constant
+		|| rhs_code == SSA_NAME)
+	       && (TREE_CODE_CLASS (first_stmt_code) == tcc_constant
+		   || first_stmt_code == SSA_NAME))
+	/* Merging two simple rvalues is OK and doesn't count as two
+	   operations.  */
+	;
       else
 	{
 	  if (first_stmt_code != rhs_code
@@ -800,11 +807,14 @@ vect_build_slp_tree_1 (vec_info *vinfo,
 	    }
 
 	  /* Not memory operation.  */
-	  if (TREE_CODE_CLASS (rhs_code) != tcc_binary
-	      && TREE_CODE_CLASS (rhs_code) != tcc_unary
-	      && TREE_CODE_CLASS (rhs_code) != tcc_expression
-	      && TREE_CODE_CLASS (rhs_code) != tcc_comparison
-	      && rhs_code != CALL_EXPR)
+	  if (REFERENCE_CLASS_P (lhs)
+	      || (TREE_CODE_CLASS (rhs_code) != tcc_binary
+		  && TREE_CODE_CLASS (rhs_code) != tcc_unary
+		  && TREE_CODE_CLASS (rhs_code) != tcc_expression
+		  && TREE_CODE_CLASS (rhs_code) != tcc_comparison
+		  && TREE_CODE_CLASS (rhs_code) != tcc_constant
+		  && rhs_code != CALL_EXPR
+		  && rhs_code != SSA_NAME))
 	    {
 	      if (dump_enabled_p ())
 		{
Index: gcc/testsuite/gcc.dg/vect/slp-temp-1.c
===================================================================
--- /dev/null	2017-06-01 07:09:35.344016119 +0100
+++ gcc/testsuite/gcc.dg/vect/slp-temp-1.c	2017-06-01 07:39:24.406603119 +0100
@@ -0,0 +1,71 @@
+/* { dg-do run { target { lp64 || ilp32 } } } */
+/* { dg-additional-options "-fgimple -fno-tree-copy-prop" } */
+
+void __GIMPLE (startwith ("loop"))
+f (int *x, int n)
+{
+  int i_in;
+  int i_out;
+  int double_i;
+
+  long unsigned int index_0;
+  long unsigned int offset_0;
+  int *addr_0;
+  int temp_0;
+
+  long unsigned int index_1;
+  long unsigned int offset_1;
+  int *addr_1;
+  int temp_1;
+
+ entry:
+  goto loop;
+
+ loop:
+  i_in = __PHI (entry: 0, latch: i_out);
+  double_i = i_in * 2;
+
+  index_0 = (long unsigned int) double_i;
+  offset_0 = index_0 * 4ul;
+  addr_0 = x_1(D) + offset_0;
+  temp_0 = 1;
+  *addr_0 = temp_0;
+
+  index_1 = index_0 + 1ul;
+  offset_1 = index_1 * 4ul;
+  addr_1 = x_1(D) + offset_1;
+  temp_1 = 3;
+  *addr_1 = temp_1;
+
+  i_out = i_in + 1;
+  if (n_2(D) > i_out)
+    goto latch;
+  else
+    goto exit;
+
+ latch:
+  goto loop;
+
+ exit:
+  return;
+}
+
+#define N 1024
+
+int
+main (void)
+{
+  int a[N * 2];
+  f (a, N);
+  for (int i = 0; i < N; ++i)
+    {
+      if (a[i * 2] != 1
+	  || a[i * 2 + 1] != 3)
+	__builtin_abort ();
+      asm volatile ("" ::: "memory");
+    }
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_int } } } */
Index: gcc/testsuite/gcc.dg/vect/slp-temp-2.c
===================================================================
--- /dev/null	2017-06-01 07:09:35.344016119 +0100
+++ gcc/testsuite/gcc.dg/vect/slp-temp-2.c	2017-06-01 07:39:30.914219838 +0100
@@ -0,0 +1,71 @@
+/* { dg-do run { target { lp64 || ilp32 } } } */
+/* { dg-additional-options "-fgimple -fno-tree-copy-prop" } */
+
+void __GIMPLE (startwith ("loop"))
+f (int *x, int n, int foo)
+{
+  int i_in;
+  int i_out;
+  int double_i;
+
+  long unsigned int index_0;
+  long unsigned int offset_0;
+  int *addr_0;
+  int temp_0;
+
+  long unsigned int index_1;
+  long unsigned int offset_1;
+  int *addr_1;
+  int temp_1;
+
+ entry:
+  goto loop;
+
+ loop:
+  i_in = __PHI (entry: 0, latch: i_out);
+  double_i = i_in * 2;
+
+  index_0 = (long unsigned int) double_i;
+  offset_0 = index_0 * 4ul;
+  addr_0 = x_1(D) + offset_0;
+  temp_0 = 1;
+  *addr_0 = temp_0;
+
+  index_1 = index_0 + 1ul;
+  offset_1 = index_1 * 4ul;
+  addr_1 = x_1(D) + offset_1;
+  temp_1 = foo_2(D);
+  *addr_1 = temp_1;
+
+  i_out = i_in + 1;
+  if (n_3(D) > i_out)
+    goto latch;
+  else
+    goto exit;
+
+ latch:
+  goto loop;
+
+ exit:
+  return;
+}
+
+#define N 1024
+
+int
+main (void)
+{
+  int a[N * 2];
+  f (a, N, 11);
+  for (int i = 0; i < N; ++i)
+    {
+      if (a[i * 2] != 1
+	  || a[i * 2 + 1] != 11)
+	__builtin_abort ();
+      asm volatile ("" ::: "memory");
+    }
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_int } } } */
Index: gcc/testsuite/gcc.dg/vect/slp-temp-3.c
===================================================================
--- /dev/null	2017-06-01 07:09:35.344016119 +0100
+++ gcc/testsuite/gcc.dg/vect/slp-temp-3.c	2017-06-01 07:39:40.925589561 +0100
@@ -0,0 +1,84 @@
+/* { dg-do run { target { lp64 || ilp32 } } } */
+/* { dg-additional-options "-fgimple -fno-tree-copy-prop" } */
+
+void __GIMPLE (startwith ("loop")) __attribute__ ((noinline, noclone))
+f (int *x, int n)
+{
+  int i_in;
+  int i_out;
+  int double_i;
+
+  long unsigned int index_0;
+  long unsigned int offset_0;
+  int *addr_0;
+  int old_0;
+  int new_0;
+  int temp_0;
+
+  long unsigned int index_1;
+  long unsigned int offset_1;
+  int *addr_1;
+  int old_1;
+  int new_1;
+  int temp_1;
+
+ entry:
+  goto loop;
+
+ loop:
+  i_in = __PHI (entry: 0, latch: i_out);
+  double_i = i_in * 2;
+
+  index_0 = (long unsigned int) double_i;
+  offset_0 = index_0 * 4ul;
+  addr_0 = x_1(D) + offset_0;
+  old_0 = *addr_0;
+  new_0 = old_0 + 1;
+  temp_0 = new_0;
+  *addr_0 = temp_0;
+
+  index_1 = index_0 + 1ul;
+  offset_1 = index_1 * 4ul;
+  addr_1 = x_1(D) + offset_1;
+  old_1 = *addr_1;
+  new_1 = old_1 + 3;
+  temp_1 = new_1;
+  *addr_1 = temp_1;
+
+  i_out = i_in + 1;
+  if (n_2(D) > i_out)
+    goto latch;
+  else
+    goto exit;
+
+ latch:
+  goto loop;
+
+ exit:
+  return;
+}
+
+#define N 1024
+
+int
+main (void)
+{
+  int a[N * 2];
+  for (int i = 0; i < N * 2; ++i)
+    {
+      a[i] = i * 4;
+      asm volatile ("" ::: "memory");
+    }
+  f (a, N);
+  for (int i = 0; i < N; ++i)
+    {
+      if (a[i * 2] != i * 8 + 1
+	  || a[i * 2 + 1] != i * 8 + 7)
+	__builtin_abort ();
+      asm volatile ("" ::: "memory");
+    }
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_int } } } */
