diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e373f88d5e6384fe16b6b70a44e7a129a992f629..ea38acb902a0482f089a72059980ddc653a734dc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+	    Alan Hayward  <alan.hayward@arm.com>
+	    David Sherwood  <david.sherwood@arm.com>
+
+	* target.def (get_mask_mode): Take the number of units and length
+	as poly_uint64s rather than unsigned ints.
+	* targhooks.h (default_get_mask_mode): Update accordingly.
+	* targhooks.c (default_get_mask_mode): Likewise.
+	* config/i386/i386.c (ix86_get_mask_mode): Likewise.
+	* doc/tm.texi: Regenerate.
+
 2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
 	    Alan Hayward  <alan.hayward@arm.com>
 	    David Sherwood  <david.sherwood@arm.com>
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1acb2c6ab838d97b9c839a456ed5d624090c60f7..a0875a718e33ea1c7094757fa48d025c69b1b036 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -48958,7 +48958,7 @@ ix86_autovectorize_vector_sizes (void)
 /* Implemenation of targetm.vectorize.get_mask_mode.  */
 
 static opt_machine_mode
-ix86_get_mask_mode (unsigned nunits, unsigned vector_size)
+ix86_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size)
 {
   unsigned elem_size = vector_size / nunits;
 
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 9793a0ed230b3aba068da223eff54b21dcb8fe3e..344867de49e5659bfa83669fed7fd4d11c427400 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5880,7 +5880,7 @@ mode returned by @code{TARGET_VECTORIZE_PREFERRED_SIMD_MODE}.
 The default is zero which means to not iterate over other vector sizes.
 @end deftypefn
 
-@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (unsigned @var{nunits}, unsigned @var{length})
+@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (poly_uint64 @var{nunits}, poly_uint64 @var{length})
 A vector mask is a value that holds one boolean result for every element
 in a vector.  This hook returns the machine mode that should be used to
 represent such a mask when the vector in question is @var{length} bytes
diff --git a/gcc/target.def b/gcc/target.def
index e9eacc891ed7b2d8d1946002b78fe0eea49ae4a8..c024bb1be6f1767bc9c8d0a022b197f6ece63fcf 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1915,7 +1915,7 @@ The default implementation returns the mode of an integer vector that\n\
 is @var{length} bytes long and that contains @var{nunits} elements,\n\
 if such a mode exists.",
  opt_machine_mode,
- (unsigned nunits, unsigned length),
+ (poly_uint64 nunits, poly_uint64 length),
  default_get_mask_mode)
 
 /* Target builtin that implements vector gather operation.  */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 653567cab3e536482dcffc987403730b9a233555..f47956a0a12574c0f7242e0ac238f1aa0014b438 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1290,17 +1290,17 @@ default_autovectorize_vector_sizes (void)
   return 0;
 }
 
-/* By defaults a vector of integers is used as a mask.  */
+/* By default a vector of integers is used as a mask.  */
 
 opt_machine_mode
-default_get_mask_mode (unsigned nunits, unsigned vector_size)
+default_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size)
 {
-  unsigned elem_size = vector_size / nunits;
+  unsigned int elem_size = vector_element_size (vector_size, nunits);
   scalar_int_mode elem_mode
     = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT);
   machine_mode vector_mode;
 
-  gcc_assert (elem_size * nunits == vector_size);
+  gcc_assert (known_eq (elem_size * nunits, vector_size));
 
   if (mode_for_vector (elem_mode, nunits).exists (&vector_mode)
       && VECTOR_MODE_P (vector_mode)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index e753e58f3d29a96353afbf2a81a7b2efbb342bfe..2535c96ae3723aa8ac08ced084e1fd87b892edee 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -109,7 +109,7 @@ default_builtin_support_vector_misalignment (machine_mode mode,
 					     int, bool);
 extern machine_mode default_preferred_simd_mode (scalar_mode mode);
 extern unsigned int default_autovectorize_vector_sizes (void);
-extern opt_machine_mode default_get_mask_mode (unsigned, unsigned);
+extern opt_machine_mode default_get_mask_mode (poly_uint64, poly_uint64);
 extern void *default_init_cost (struct loop *);
 extern unsigned default_add_stmt_cost (void *, int, enum vect_cost_for_stmt,
 				       struct _stmt_vec_info *, int,