aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-12-30 18:05:10 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-12-30 18:05:10 +0100
commitacdcd61b09ce9342b634539642203bc387477092 (patch)
tree2a5008f0e2734867398f5c1300db88d05c5e8016 /gcc
parent51ac3042e79ed2a67bd5979dadd324f46a58c51e (diff)
downloadgcc-acdcd61b09ce9342b634539642203bc387477092.zip
gcc-acdcd61b09ce9342b634539642203bc387477092.tar.gz
gcc-acdcd61b09ce9342b634539642203bc387477092.tar.bz2
re PR tree-optimization/59591 (ICE in vect_get_vec_def_for_stmt_copy, at tree-vect-stmts.c:156 for -march=core-avx2)
PR tree-optimization/59591 * tree-vect-stmts.c (vectorizable_mask_load_store): Fix up handling of modifier = NARROW masked gathers. (permute_vec_elements): Use gimple_get_lhs instead of gimple_assign_lhs. * gcc.dg/vect/pr59591-1.c: New test. * gcc.dg/vect/pr59591-2.c: New test. * gcc.target/i386/pr59591-1.c: New test. * gcc.target/i386/pr59591-2.c: New test. From-SVN: r206248
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr59591-1.c55
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr59591-2.c56
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59591-1.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59591-2.c17
-rw-r--r--gcc/tree-vect-stmts.c72
7 files changed, 201 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1a6ae5e..09e0ad2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-12-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59591
+ * tree-vect-stmts.c (vectorizable_mask_load_store): Fix up handling
+ of modifier = NARROW masked gathers.
+ (permute_vec_elements): Use gimple_get_lhs instead of
+ gimple_assign_lhs.
+
2013-12-30 Nick Clifton <nickc@redhat.com>
* config/msp430/msp430.c (msp430_print_operand): Rename %B to %b
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e5f1a82..3d68675 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2013-12-30 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/59591
+ * gcc.dg/vect/pr59591-1.c: New test.
+ * gcc.dg/vect/pr59591-2.c: New test.
+ * gcc.target/i386/pr59591-1.c: New test.
+ * gcc.target/i386/pr59591-2.c: New test.
+
PR target/59501
* gcc.target/i386/pr59501-1.c: New test.
* gcc.target/i386/pr59501-1a.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/pr59591-1.c b/gcc/testsuite/gcc.dg/vect/pr59591-1.c
new file mode 100644
index 0000000..b216dee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr59591-1.c
@@ -0,0 +1,55 @@
+/* PR tree-optimization/59591 */
+/* { dg-do run } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#ifndef CHECK_H
+#include "tree-vect.h"
+#endif
+
+extern void abort (void);
+
+int p[256], q[256], r[256], t[256];
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+ int i;
+ #pragma omp simd safelen(64)
+ for (i = 0; i < 256; i++)
+ if (r[i] > 32)
+ t[i] = p[q[i] * 3L + 2L];
+}
+
+__attribute__((noinline, noclone)) void
+bar (void)
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ r[i] = ((i >> 2) & (1 << (i & 3))) ? 32 + i : 32 - i;
+ q[i] = r[i] > 32 ? ((i * 7) % 84) : 99 + i;
+ p[i] = i * 11;
+ t[i] = i * 13;
+ }
+ foo ();
+ for (i = 0; i < 256; i++)
+ if ((i >> 2) & (1 << (i & 3)))
+ {
+ if (t[i] != (((i * 7) % 84) * 3 + 2) * 11)
+ abort ();
+ }
+ else if (t[i] != i * 13)
+ abort ();
+}
+
+#ifndef CHECK_H
+int
+main ()
+{
+ check_vect ();
+ bar ();
+ return 0;
+}
+#endif
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr59591-2.c b/gcc/testsuite/gcc.dg/vect/pr59591-2.c
new file mode 100644
index 0000000..429b187
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr59591-2.c
@@ -0,0 +1,56 @@
+/* PR tree-optimization/59591 */
+/* { dg-do run } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#ifndef CHECK_H
+#include "tree-vect.h"
+#endif
+
+extern void abort (void);
+
+long long int p[256], r[256], t[256];
+int q[256];
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+ int i;
+ #pragma omp simd safelen(64)
+ for (i = 0; i < 256; i++)
+ if (r[i] > 32LL)
+ t[i] = p[q[i]];
+}
+
+__attribute__((noinline, noclone)) void
+bar (void)
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ r[i] = ((i >> 2) & (1 << (i & 3))) ? 32 + i : 32 - i;
+ q[i] = r[i] > 32 ? ((i * 7) % 256) : 258 + i;
+ p[i] = i * 11;
+ t[i] = i * 13;
+ }
+ foo ();
+ for (i = 0; i < 256; i++)
+ if ((i >> 2) & (1 << (i & 3)))
+ {
+ if (t[i] != ((i * 7) % 256) * 11)
+ abort ();
+ }
+ else if (t[i] != i * 13)
+ abort ();
+}
+
+#ifndef CHECK_H
+int
+main ()
+{
+ check_vect ();
+ bar ();
+ return 0;
+}
+#endif
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59591-1.c b/gcc/testsuite/gcc.target/i386/pr59591-1.c
new file mode 100644
index 0000000..a88c6fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr59591-1.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/59591 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp-simd -mavx2 -fno-vect-cost-model" } */
+/* { dg-require-effective-target avx2 } */
+
+#define CHECK_H "avx2-check.h"
+#define TEST avx2_test
+
+#include "../../gcc.dg/vect/pr59591-1.c"
+
+#include CHECK_H
+
+static void
+TEST (void)
+{
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr59591-2.c b/gcc/testsuite/gcc.target/i386/pr59591-2.c
new file mode 100644
index 0000000..c032364
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr59591-2.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/59591 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp-simd -mavx2 -fno-vect-cost-model" } */
+/* { dg-require-effective-target avx2 } */
+
+#define CHECK_H "avx2-check.h"
+#define TEST avx2_test
+
+#include "../../gcc.dg/vect/pr59591-2.c"
+
+#include CHECK_H
+
+static void
+TEST (void)
+{
+ bar ();
+}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index e3009d9..a07c14d 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1855,14 +1855,24 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
tree vec_oprnd0 = NULL_TREE, op;
tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gather_decl));
tree rettype, srctype, ptrtype, idxtype, masktype, scaletype;
- tree ptr, vec_mask = NULL_TREE, mask_op, var, scale;
+ tree ptr, vec_mask = NULL_TREE, mask_op = NULL_TREE, var, scale;
tree perm_mask = NULL_TREE, prev_res = NULL_TREE;
+ tree mask_perm_mask = NULL_TREE;
edge pe = loop_preheader_edge (loop);
gimple_seq seq;
basic_block new_bb;
enum { NARROW, NONE, WIDEN } modifier;
int gather_off_nunits = TYPE_VECTOR_SUBPARTS (gather_off_vectype);
+ rettype = TREE_TYPE (TREE_TYPE (gather_decl));
+ srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
+ scaletype = TREE_VALUE (arglist);
+ gcc_checking_assert (types_compatible_p (srctype, rettype)
+ && types_compatible_p (srctype, masktype));
+
if (nunits == gather_off_nunits)
modifier = NONE;
else if (nunits == gather_off_nunits / 2)
@@ -1888,19 +1898,14 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
perm_mask = vect_gen_perm_mask (vectype, sel);
gcc_assert (perm_mask != NULL_TREE);
ncopies *= 2;
+ for (i = 0; i < nunits; ++i)
+ sel[i] = i | gather_off_nunits;
+ mask_perm_mask = vect_gen_perm_mask (masktype, sel);
+ gcc_assert (mask_perm_mask != NULL_TREE);
}
else
gcc_unreachable ();
- rettype = TREE_TYPE (TREE_TYPE (gather_decl));
- srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- ptrtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- idxtype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- masktype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
- scaletype = TREE_VALUE (arglist);
- gcc_checking_assert (types_compatible_p (srctype, rettype)
- && types_compatible_p (srctype, masktype));
-
vec_dest = vect_create_destination_var (gimple_call_lhs (stmt), vectype);
ptr = fold_convert (ptrtype, gather_base);
@@ -1940,28 +1945,35 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
op = var;
}
- if (j == 0)
- vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ if (mask_perm_mask && (j & 1))
+ mask_op = permute_vec_elements (mask_op, mask_op,
+ mask_perm_mask, stmt, gsi);
else
{
- vect_is_simple_use (vec_mask, NULL, loop_vinfo, NULL, &def_stmt,
- &def, &dt);
- vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
- }
+ if (j == 0)
+ vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ else
+ {
+ vect_is_simple_use (vec_mask, NULL, loop_vinfo, NULL,
+ &def_stmt, &def, &dt);
+ vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
+ }
- mask_op = vec_mask;
- if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask)))
- {
- gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
- == TYPE_VECTOR_SUBPARTS (masktype));
- var = vect_get_new_vect_var (masktype, vect_simple_var, NULL);
- var = make_ssa_name (var, NULL);
- mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
- new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
- mask_op, NULL_TREE);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
- mask_op = var;
+ mask_op = vec_mask;
+ if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask)))
+ {
+ gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
+ == TYPE_VECTOR_SUBPARTS (masktype));
+ var = vect_get_new_vect_var (masktype, vect_simple_var,
+ NULL);
+ var = make_ssa_name (var, NULL);
+ mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
+ new_stmt
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
+ mask_op, NULL_TREE);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ mask_op = var;
+ }
}
new_stmt
@@ -5446,7 +5458,7 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt,
tree perm_dest, data_ref;
gimple perm_stmt;
- perm_dest = vect_create_destination_var (gimple_assign_lhs (stmt), vectype);
+ perm_dest = vect_create_destination_var (gimple_get_lhs (stmt), vectype);
data_ref = make_ssa_name (perm_dest, NULL);
/* Generate the permute statement. */