We've traditionally allowed vectors of enums (not sure if that's deliberate) but vector_types_compatible_elements_p checked for INTEGER_TYPE rather than INTEGRAL_TYPE_P.
Tested on aarch64-linux-gnu. OK to install? Richard 2018-10-05 Richard Sandiford <richard.sandif...@arm.com> gcc/c-family/ PR c/87286 * c-common.c (vector_types_compatible_elements_p): Use INTEGRAL_TYPE_P instead of checking only for INTEGER_TYPE. gcc/testsuite/ PR c/87286 * gcc.dg/pr87286.c: New test. Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c 2018-10-05 13:46:08.287811117 +0100 +++ gcc/c-family/c-common.c 2018-10-05 13:47:08.291325001 +0100 @@ -7465,8 +7465,11 @@ vector_types_compatible_elements_p (tree enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2); - gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE || c1 == FIXED_POINT_TYPE) - && (c2 == INTEGER_TYPE || c2 == REAL_TYPE + gcc_assert ((INTEGRAL_TYPE_P (t1) + || c1 == REAL_TYPE + || c1 == FIXED_POINT_TYPE) + && (INTEGRAL_TYPE_P (t2) + || c2 == REAL_TYPE || c2 == FIXED_POINT_TYPE)); t1 = c_common_signed_type (t1); @@ -7476,7 +7479,7 @@ vector_types_compatible_elements_p (tree if (t1 == t2) return true; if (opaque && c1 == c2 - && (c1 == INTEGER_TYPE || c1 == REAL_TYPE) + && (INTEGRAL_TYPE_P (t1) || c1 == REAL_TYPE) && TYPE_PRECISION (t1) == TYPE_PRECISION (t2)) return true; return false; Index: gcc/testsuite/gcc.dg/pr87286.c =================================================================== --- /dev/null 2018-09-14 11:16:31.122530289 +0100 +++ gcc/testsuite/gcc.dg/pr87286.c 2018-10-05 13:47:08.291325001 +0100 @@ -0,0 +1,3 @@ +enum foo { F }; +typedef enum foo vec_foo __attribute__((vector_size (16))); +vec_foo add (vec_foo x, vec_foo y) { return x + y; }