diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0fff6f8e353f4ab6602cc9acb3b6ad7a5a12b2e6..698537fee5f85f02586b745d644f2b4a5759ce6b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-19  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+	* c-typeck.c (build_binary_op): Allow % on integal vectors.
+	* doc/extend.texi (Vector Extension): Document that % is allowed too.
+
 2009-05-19  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/i386/i386.c (ix86_avoid_jump_mispredicts): Check
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 62b5ee913afd563212181eefbe561fe7b9bd9462..ee1853a0f739a95dfcb79bab6e9fa4b74a6d6e3f 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -8988,7 +8988,11 @@ build_binary_op (location_t location, enum tree_code code,
     case FLOOR_MOD_EXPR:
       warn_for_div_by_zero (location, op1);
 
-      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+	  && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+	common = 1;
+      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  /* Although it would be tempting to shorten always here, that loses
 	     on some targets, since the modulo instruction is undefined if the
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 813413e767d3e79d95886c284949e27fcab7c541..bd81af6b406abf5136e1e9fe9da8e44374c40af1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,7 @@
+2009-05-19  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+	* typeck.c (build_binary_op): Allow % on integal vectors.
+
 2009-05-18  Jason Merrill  <jason@redhat.com>
 
 	Implement explicit conversions ops as specified in N2437.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 66472ee96ebfb5f1d3528952172da98b3c0e660c..a5f36188f77c9fbabdd501e26ece5cf01b099402 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3492,7 +3492,11 @@ cp_build_binary_op (location_t location,
     case FLOOR_MOD_EXPR:
       warn_for_div_by_zero (location, op1);
 
-      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+	  && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+	common = 1;
+      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  /* Although it would be tempting to shorten always here, that loses
 	     on some targets, since the modulo instruction is undefined if the
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 6b626e2add7b8b32bb4f746001673e6cadce2031..98df9d59447ce078e50d834e4323070c75f25e91 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -5746,7 +5746,7 @@ produce code that uses 4 @code{SIs}.
 
 The types defined in this manner can be used with a subset of normal C
 operations.  Currently, GCC will allow using the following operators
-on these types: @code{+, -, *, /, unary minus, ^, |, &, ~}@.
+on these types: @code{+, -, *, /, unary minus, ^, |, &, ~, %}@.
 
 The operations behave like C++ @code{valarrays}.  Addition is defined as
 the addition of the corresponding elements of the operands.  For
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d3267554d6aa3e77c679fd2bd1fd13bfcd60a78b..df16058cf36049992e79b9fb35ce10ebff4d197c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-05-19  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+	* gcc.dg/vector-4.c: New testcase.
+	* gcc.dg/simd-1b.c: % is now allowed for integer vectors.
+	* g++.dg/ext/vector16.C: New testcase.
+
 2009-05-19  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR c/40172
diff --git a/gcc/testsuite/g++.dg/ext/vector16.C b/gcc/testsuite/g++.dg/ext/vector16.C
new file mode 100644
index 0000000000000000000000000000000000000000..7964a881f4a367e0cf41ca337be76805a934e08a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector16.C
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#define vector __attribute__((vector_size(4*sizeof(int)) ))
+
+vector int a, b, c;
+
+
+/* Test that remainder works for vectors. */
+void f(void)
+{
+  a = b % c;
+}
diff --git a/gcc/testsuite/gcc.dg/simd-1b.c b/gcc/testsuite/gcc.dg/simd-1b.c
index 56d94b91c68fa9e5f092b50b5a0187588bc336c9..1e2b597b56518fce85a5cc3d6a81f65a490ec990 100644
--- a/gcc/testsuite/gcc.dg/simd-1b.c
+++ b/gcc/testsuite/gcc.dg/simd-1b.c
@@ -14,7 +14,7 @@ void
 hanneke ()
 {
   /* Operators on compatible SIMD types.  */
-  a %= b; /* { dg-error "invalid operands to binary %" } */
+  a %= b;
   c &= d;
   a |= b;
   c ^= d;
diff --git a/gcc/testsuite/gcc.dg/vector-4.c b/gcc/testsuite/gcc.dg/vector-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..7964a881f4a367e0cf41ca337be76805a934e08a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vector-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#define vector __attribute__((vector_size(4*sizeof(int)) ))
+
+vector int a, b, c;
+
+
+/* Test that remainder works for vectors. */
+void f(void)
+{
+  a = b % c;
+}