Message ID | 20190205223629.GZ2135@tucnak |
---|---|
State | New |
Headers | show |
Series | Fix fold_const_vec_convert (PR middle-end/89210) | expand |
Jakub Jelinek <jakub@redhat.com> writes: > 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 <jakub@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. OK, thanks. Richard
--- 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); +}