Hi! On the following testcase because of the SCCVN limit we end up with a weird, but valid, BIT_FIELD_REF - trying to extract V1TImode type out of a V1TImode SSA_NAME, with 128 bits width and offset 0 (just SSA_NAME move would be enough). Not trying to address why we create it, rather fix how we handle it.
The problem is that the BIT_FIELD_REF vector extraction is guarded with: (if (VECTOR_TYPE_P (TREE_TYPE (@0)) && (types_match (type, TREE_TYPE (TREE_TYPE (@0))) || (VECTOR_TYPE_P (type) && types_match (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0)))))) and thus we must handle vector type as result, but assume incorrectly that if count is 1, then we must be asking for an element and thus not vector type. For the first hunk we could do what we do in the second hunk, do a VIEW_CONVERT_EXPR, but it seems cleaner to just fall through into the count > 1 code which builds a CONSTRUCTOR. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-04-04 Jakub Jelinek <ja...@redhat.com> PR middle-end/85195 * match.pd (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2): If count == 1, only use elt value if type is not vector type, otherwise build CONSTRUCTOR. For n == const_k, use view_convert. * gcc.dg/pr85195.c: New test. --- gcc/match.pd.jj 2018-03-28 21:15:00.000000000 +0200 +++ gcc/match.pd 2018-04-04 14:35:10.424127155 +0200 @@ -4648,7 +4648,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (multiple_p (idx, k, &elt) && multiple_p (n, k, &count)) (if (CONSTRUCTOR_NELTS (ctor) == 0) { build_constructor (type, NULL); } - (if (count == 1) + (if (count == 1 && !VECTOR_TYPE_P (type)) (if (elt < CONSTRUCTOR_NELTS (ctor)) { CONSTRUCTOR_ELT (ctor, elt)->value; } { build_zero_cst (type); }) @@ -4668,7 +4668,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (CONSTRUCTOR_NELTS (ctor) <= idx / const_k) { build_zero_cst (type); }) (if (n == const_k) - { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; }) + (view_convert { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; })) (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; } @1 { bitsize_int ((idx % const_k) * width); }))))))))) --- gcc/testsuite/gcc.dg/pr85195.c.jj 2018-04-04 14:38:29.233235494 +0200 +++ gcc/testsuite/gcc.dg/pr85195.c 2018-04-04 14:38:14.696227566 +0200 @@ -0,0 +1,19 @@ +/* PR middle-end/85195 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-Wno-psabi -O -fno-tree-ccp --param=sccvn-max-scc-size=10" } */ + +typedef __int128 V __attribute__ ((vector_size (16))); + +extern int bar (V); + +V v; +int i; + +V +foo (void) +{ + do + v *= bar (v & i); + while ((V){}[0]); + return v; +} Jakub