diff mbox series

Fix VEC_PERM_EXPR folding (PR tree-optimization/85331)

Message ID 20180411131126.GR8577@tucnak
State New
Headers show
Series Fix VEC_PERM_EXPR folding (PR tree-optimization/85331) | expand

Commit Message

Jakub Jelinek April 11, 2018, 1:11 p.m. UTC
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  <jakub@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.


	Jakub
diff mbox series

Patch

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