diff mbox series

Fix fold_const_vec_convert (PR middle-end/89210)

Message ID 20190205223629.GZ2135@tucnak
State New
Headers show
Series Fix fold_const_vec_convert (PR middle-end/89210) | expand

Commit Message

Jakub Jelinek Feb. 5, 2019, 10:36 p.m. UTC
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.

	* c-c++-common/builtin-convertvector-2.c: New test.


	Jakub

Comments

Richard Sandiford Feb. 6, 2019, 9:01 a.m. UTC | #1
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
diff mbox series

Patch

--- 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);
+}