2017-03-07  Will Schmidt  <will_schmidt@vnet.ibm.com>

	PR middle-end/79941
	* config/rs6000/rs6000.c (gimplify_init_constructor): Remove multiply
	even and multiply odd unsigned (vmule/vmulo) intrinsics from the
	multiply folding sequence.

	* gcc.target/powerpc/fold-vec-mult-even_odd_misc.c: New test.

--- gcc/config/rs6000/rs6000.c	2017-03-03 20:31:01.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2017-03-08 18:52:48.409967121 +0100
@@ -16855,9 +16855,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_
     /* Even element flavors of vec_mul (signed). */
     case ALTIVEC_BUILTIN_VMULESB:
     case ALTIVEC_BUILTIN_VMULESH:
-    /* Even element flavors of vec_mul (unsigned).  */
-    case ALTIVEC_BUILTIN_VMULEUB:
-    case ALTIVEC_BUILTIN_VMULEUH:
       {
 	arg0 = gimple_call_arg (stmt, 0);
 	arg1 = gimple_call_arg (stmt, 1);
@@ -16870,9 +16867,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_
     /* Odd element flavors of vec_mul (signed).  */
     case ALTIVEC_BUILTIN_VMULOSB:
     case ALTIVEC_BUILTIN_VMULOSH:
-    /* Odd element flavors of vec_mul (unsigned). */
-    case ALTIVEC_BUILTIN_VMULOUB:
-    case ALTIVEC_BUILTIN_VMULOUH:
       {
 	arg0 = gimple_call_arg (stmt, 0);
 	arg1 = gimple_call_arg (stmt, 1);
--- gcc/testsuite/gcc.target/powerpc/fold-vec-mult-even_odd_misc.c
+++ gcc/testsuite/gcc.target/powerpc/fold-vec-mult-even_odd_misc.c
@@ -0,0 +1,58 @@
+
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-maltivec -mvsx -O2 -save-temps" } */
+
+#include <altivec.h>
+
+__attribute__((noinline)) void 
+test_eub_char ()
+{
+  vector unsigned char v0 = {1, 0, 0, 0, 0, 0, 0, 0};
+  vector unsigned char v1 = {0xff, 0, 0, 0, 0, 0, 0, 0};
+  vector unsigned short res = vec_vmuleub (v0, v1);
+  if (res[0] != (unsigned short)v0[0] * (unsigned short)v1[0])
+    __builtin_abort ();
+}
+__attribute__((noinline)) void 
+test_oub_char ()
+{
+  vector unsigned char v0 = {0, 1, 0, 0, 0, 0, 0, 0};
+  vector unsigned char v1 = {0, 0xff, 0, 0, 0, 0, 0, 0};
+  vector unsigned short res = vec_vmuloub (v0, v1);
+  if (res[0] != (unsigned short)v0[1] * (unsigned short)v1[1])
+    __builtin_abort ();
+}
+
+__attribute__((noinline)) void 
+test_euh_short ()
+{
+  vector unsigned short v0 = {1, 0, 0, 0};
+  vector unsigned short v1 = {0xff, 0, 0, 0};
+  vector unsigned int res = vec_vmuleuh (v0, v1);
+  if (res[0] != (unsigned int)v0[0] * (unsigned int)v1[0])
+    __builtin_abort ();
+}
+__attribute__((noinline)) void 
+test_ouh_short ()
+{
+  vector unsigned short v0 = {0, 1, 0, 0};
+  vector unsigned short v1 = {0, 0xff, 0, 0};
+  vector unsigned int res = vec_vmulouh (v0, v1);
+  if (res[0] != (unsigned int)v0[1] * (unsigned int)v1[1])
+    __builtin_abort ();
+}
+
+int main ()
+{
+  test_eub_char();
+  test_oub_char();
+  test_euh_short();
+  test_ouh_short();
+}
+
+/* { dg-final { scan-assembler-times "vmuleub" 1 } } */
+/* { dg-final { scan-assembler-times "vmuloub" 1 } } */
+/* { dg-final { scan-assembler-times "vmuleuh" 1 } } */
+/* { dg-final { scan-assembler-times "vmulouh" 1 } } */
+