Hi! Apparently VECTOR_CSTs shouldn't be stepped if they contain floating elements and also widening conversions can be problematic if there is wrapping in the narrower type. On the following testcase, we create a stepped VECTOR_CST with REAL_CST elts and ICE whenever we try to print it or when we try to expand it. The following patch follows what fold_convert_const does.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-02-05 Jakub Jelinek <ja...@redhat.com> PR middle-end/89210 * fold-const-call.c (fold_const_vec_convert): Pass true as last operand to new_unary_operation only if both element types are integral and it isn't a widening conversion. Return NULL_TREE if new_unary_operation failed. * c-c++-common/builtin-convertvector-2.c: New test. --- gcc/fold-const-call.c.jj 2019-01-07 09:47:33.046517940 +0100 +++ gcc/fold-const-call.c 2019-02-05 19:15:44.111209138 +0100 @@ -665,8 +665,17 @@ fold_const_vec_convert (tree ret_type, t && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type))) code = FLOAT_EXPR; + /* We can't handle steps directly when extending, since the + values need to wrap at the original precision first. */ + bool step_ok_p + = (INTEGRAL_TYPE_P (TREE_TYPE (ret_type)) + && INTEGRAL_TYPE_P (TREE_TYPE (arg_type)) + && (TYPE_PRECISION (TREE_TYPE (ret_type)) + <= TYPE_PRECISION (TREE_TYPE (arg_type)))); tree_vector_builder elts; - elts.new_unary_operation (ret_type, arg, true); + if (!elts.new_unary_operation (ret_type, arg, step_ok_p)) + return NULL_TREE; + unsigned int count = elts.encoded_nelts (); for (unsigned int i = 0; i < count; ++i) { --- gcc/testsuite/c-c++-common/builtin-convertvector-2.c.jj 2019-02-05 19:19:16.981705824 +0100 +++ gcc/testsuite/c-c++-common/builtin-convertvector-2.c 2019-02-05 19:17:20.217627468 +0100 @@ -0,0 +1,12 @@ +/* PR middle-end/89210 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef int v4si __attribute__((vector_size (4 * sizeof (int)))); +typedef double v4df __attribute__((vector_size (4 * sizeof (double)))); +void +foo (v4df *x) +{ + v4si a = { 1, 2, 3, 4 }; + *x = __builtin_convertvector (a, v4df); +} Jakub