This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix VEC_PERM_EXPR folding (PR tree-optimization/85331)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Richard Sandiford <richard dot sandiford at arm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Apr 2018 15:11:26 +0200
- Subject: [PATCH] Fix VEC_PERM_EXPR folding (PR tree-optimization/85331)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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.
--- 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;
+}
Jakub