Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 247111)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -5595,11 +5595,11 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg1 = (*arglist)[1];
       tree arg1_type = TREE_TYPE (arg1);
 
-      /* Both arguments must be vectors and the types must match.  */
-      if (arg0_type != arg1_type)
-	goto bad;
+      /* Both arguments must be vectors and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
@@ -5610,8 +5610,8 @@ altivec_resolve_overloaded_builtin (location_t loc
 	  case TImode:
 	    {
 	      /* For scalar types just use a multiply expression.  */
-	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0),
-					arg0, arg1);
+	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
+				      fold_convert (TREE_TYPE (arg0), arg1));
 	    }
 	  case SFmode:
 	    {
@@ -5655,13 +5655,12 @@ altivec_resolve_overloaded_builtin (location_t loc
 	  || (TYPE_MODE (TREE_TYPE (arg0_type)) == SFmode)
 	  || (TYPE_MODE (TREE_TYPE (arg0_type)) == DFmode))
 	{
-	  /* Both arguments must be vectors and the types must match.  */
-	  if (arg0_type != arg1_type)
-	    goto bad;
+	  /* Both arguments must be vectors and the types must be compatible.  */
 	  if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	    goto bad;
+	  if (!lang_hooks.types_compatible_p (arg0_type, arg1_type))
+	    goto bad;
 
-
 	  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	    {
 	      /* vec_cmpneq (va, vb) == vec_nor (vec_cmpeq (va, vb),
@@ -5720,11 +5719,12 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg2_type = TREE_TYPE (arg2);
 
       /* All 3 arguments must be vectors of (signed or unsigned) (int or
-	  __int128) and the types must match.  */
-      if ((arg0_type != arg1_type) || (arg1_type != arg2_type))
-	goto bad;
+	  __int128) and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) ||
+	  !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
@@ -5783,11 +5783,13 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg2_type = TREE_TYPE (arg2);
 
       /* All 3 arguments must be vectors of (signed or unsigned) (int or
-	__int128) and the types must match.  */
-      if (arg0_type != arg1_type || arg1_type != arg2_type)
-	goto bad;
+	__int128) and the types must be compatible.  */
+      /* Both arguments must be vectors and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) ||
+	  !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
Index: gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c	(working copy)
@@ -0,0 +1,31 @@
+/* Test that const and volatile qualifiers can mix on vec_mul operands.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -mvsx" } */
+
+#include <altivec.h>
+
+void P() {
+  const volatile vector float cvva = vec_splats(0.00187682f);
+  volatile vector float vva = vec_splats(0.00187682f);
+  const vector float cva = vec_splats(0.00187682f);
+  vector float va = vec_splats(0.00187682f);
+  vector float dx = {1.0f, 2.0f, 3.0f, 4.0f};
+
+  vector float X1m0 = vec_mul(va, va);
+  vector float X2m0 = vec_mul(va, dx);
+  vector float X3m0 = vec_mul(dx, va);
+
+  vector float X1m1 = vec_mul(cva, cva);
+  vector float X2m1 = vec_mul(cva, dx);
+  vector float X3m1 = vec_mul(dx, cva);
+
+  vector float Y1m2 = vec_mul(vva, vva);
+  vector float Y2m2 = vec_mul(vva, dx);
+  vector float Y3m2 = vec_mul(dx, vva);
+
+  vector float X1m3 = vec_mul(cvva, cvva);
+  vector float X2m3 = vec_mul(cvva, dx);
+  vector float X3m3 = vec_mul(dx, cvva);
+}Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 247116)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -5595,11 +5595,11 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg1 = (*arglist)[1];
       tree arg1_type = TREE_TYPE (arg1);
 
-      /* Both arguments must be vectors and the types must match.  */
-      if (arg0_type != arg1_type)
-	goto bad;
+      /* Both arguments must be vectors and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
@@ -5610,8 +5610,8 @@ altivec_resolve_overloaded_builtin (location_t loc
 	  case TImode:
 	    {
 	      /* For scalar types just use a multiply expression.  */
-	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0),
-					arg0, arg1);
+	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
+				      fold_convert (TREE_TYPE (arg0), arg1));
 	    }
 	  case SFmode:
 	    {
@@ -5655,13 +5655,12 @@ altivec_resolve_overloaded_builtin (location_t loc
 	  || (TYPE_MODE (TREE_TYPE (arg0_type)) == SFmode)
 	  || (TYPE_MODE (TREE_TYPE (arg0_type)) == DFmode))
 	{
-	  /* Both arguments must be vectors and the types must match.  */
-	  if (arg0_type != arg1_type)
-	    goto bad;
+	  /* Both arguments must be vectors and the types must be compatible.  */
 	  if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	    goto bad;
+	  if (!lang_hooks.types_compatible_p (arg0_type, arg1_type))
+	    goto bad;
 
-
 	  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	    {
 	      /* vec_cmpneq (va, vb) == vec_nor (vec_cmpeq (va, vb),
@@ -5720,11 +5719,12 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg2_type = TREE_TYPE (arg2);
 
       /* All 3 arguments must be vectors of (signed or unsigned) (int or
-	  __int128) and the types must match.  */
-      if ((arg0_type != arg1_type) || (arg1_type != arg2_type))
-	goto bad;
+	 __int128) and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) ||
+	  !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
@@ -5783,11 +5783,12 @@ altivec_resolve_overloaded_builtin (location_t loc
       tree arg2_type = TREE_TYPE (arg2);
 
       /* All 3 arguments must be vectors of (signed or unsigned) (int or
-	__int128) and the types must match.  */
-      if (arg0_type != arg1_type || arg1_type != arg2_type)
-	goto bad;
+	 __int128) and the types must be compatible.  */
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) ||
+	  !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
Index: gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c	(working copy)
@@ -0,0 +1,31 @@
+/* Test that const and volatile qualifiers can mix on vec_mul operands.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -mvsx" } */
+
+#include <altivec.h>
+
+void P() {
+  const volatile vector float cvva = vec_splats(0.00187682f);
+  volatile vector float vva = vec_splats(0.00187682f);
+  const vector float cva = vec_splats(0.00187682f);
+  vector float va = vec_splats(0.00187682f);
+  vector float dx = {1.0f, 2.0f, 3.0f, 4.0f};
+
+  vector float X1m0 = vec_mul(va, va);
+  vector float X2m0 = vec_mul(va, dx);
+  vector float X3m0 = vec_mul(dx, va);
+
+  vector float X1m1 = vec_mul(cva, cva);
+  vector float X2m1 = vec_mul(cva, dx);
+  vector float X3m1 = vec_mul(dx, cva);
+
+  vector float Y1m2 = vec_mul(vva, vva);
+  vector float Y2m2 = vec_mul(vva, dx);
+  vector float Y3m2 = vec_mul(dx, vva);
+
+  vector float X1m3 = vec_mul(cvva, cvva);
+  vector float X2m3 = vec_mul(cvva, dx);
+  vector float X3m3 = vec_mul(dx, cvva);
+}
