diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-12-30 18:05:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-12-30 18:05:10 +0100 |
commit | acdcd61b09ce9342b634539642203bc387477092 (patch) | |
tree | 2a5008f0e2734867398f5c1300db88d05c5e8016 /gcc | |
parent | 51ac3042e79ed2a67bd5979dadd324f46a58c51e (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr59591-1.c | 55 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr59591-2.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59591-1.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59591-2.c | 17 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 72 |
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. */ |