Hi! We ICE on the following testcase, because VEC_PERM_EXPR indexes are supposed to be clamped into the 0 .. 2 * nelts - 1 range, but if some index is very large constant (larger or equal than HOST_WIDE_INT_1 << 33), then clamp doesn't actually perform any clamping. This is because can_div_trunc_p stores the quotient into int variable and this doesn't fit in that case into int. As element_type is poly_int64, it should fit into HOST_WIDE_INT.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-04-11 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/85331 * vec-perm-indices.h (vec_perm_indices::clamp): Change input type from int to HOST_WIDE_INT. * gcc.c-torture/execute/pr85331.c: New test. --- gcc/vec-perm-indices.h.jj 2018-01-03 10:19:54.969533927 +0100 +++ gcc/vec-perm-indices.h 2018-04-11 09:48:02.043153054 +0200 @@ -119,7 +119,7 @@ inline vec_perm_indices::element_type vec_perm_indices::clamp (element_type elt) const { element_type limit = input_nelts (), elem_within_input; - int input; + HOST_WIDE_INT input; if (!can_div_trunc_p (elt, limit, &input, &elem_within_input)) return elt; --- gcc/testsuite/gcc.c-torture/execute/pr85331.c.jj 2018-04-11 09:54:02.044206856 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr85331.c 2018-04-11 09:53:22.359200922 +0200 @@ -0,0 +1,22 @@ +/* PR tree-optimization/85331 */ + +typedef double V __attribute__((vector_size (2 * sizeof (double)))); +typedef long long W __attribute__((vector_size (2 * sizeof (long long)))); + +__attribute__((noipa)) void +foo (V *r) +{ + V y = { 1.0, 2.0 }; + W m = { 10000000001LL, 0LL }; + *r = __builtin_shuffle (y, m); +} + +int +main () +{ + V r; + foo (&r); + if (r[0] != 2.0 || r[1] != 1.0) + __builtin_abort (); + return 0; +} Jakub