diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-10-25 10:02:08 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-10-25 10:02:08 +0200 |
commit | ab0ef7069390b376263a13cb1dbdf38883d664d7 (patch) | |
tree | 98fa7d9be8e8feb32d1a93e13c5d8bc78f7ac8b8 | |
parent | db8543789305f6d56005bba91f784831d3745970 (diff) | |
download | gcc-ab0ef7069390b376263a13cb1dbdf38883d664d7.tar.gz |
re PR tree-optimization/50596 (Problems in vectorization of condition expression)
PR tree-optimization/50596
* tree-vect-stmts.c (vect_mark_relevant): Only use
FOR_EACH_IMM_USE_FAST if lhs is SSA_NAME.
(vectorizable_store): If is_pattern_stmt_p look through
VIEW_CONVERT_EXPR on lhs.
* tree-vect-patterns.c (check_bool_pattern, adjust_bool_pattern):
Use unsigned type instead of signed.
(vect_recog_bool_pattern): Optimize also stores into bool memory in
addition to casts from bool to integral types.
(vect_mark_pattern_stmts): If pattern_stmt already has vinfo
created, don't create it again.
* gcc.dg/vect/vect-cond-10.c: New test.
From-SVN: r180424
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-cond-10.c | 165 | ||||
-rw-r--r-- | gcc/tree-vect-patterns.c | 57 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 28 |
5 files changed, 249 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c5235bf37ff..3f9af649076 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2011-10-25 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50596 + * tree-vect-stmts.c (vect_mark_relevant): Only use + FOR_EACH_IMM_USE_FAST if lhs is SSA_NAME. + (vectorizable_store): If is_pattern_stmt_p look through + VIEW_CONVERT_EXPR on lhs. + * tree-vect-patterns.c (check_bool_pattern, adjust_bool_pattern): + Use unsigned type instead of signed. + (vect_recog_bool_pattern): Optimize also stores into bool memory in + addition to casts from bool to integral types. + (vect_mark_pattern_stmts): If pattern_stmt already has vinfo + created, don't create it again. + 2011-10-25 Kai Tietz <ktietz@redhat.com> * config/i386/i386.c (ix86_frame_pointer_required): Require diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 256a84c667a..7cf4d3f1aae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-25 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50596 + * gcc.dg/vect/vect-cond-10.c: New test. + 2011-10-24 Joey Ye <joey.ye@arm.com> * gcc.target/arm/pr42575.c: Remove architecture option. diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-10.c b/gcc/testsuite/gcc.dg/vect/vect-cond-10.c new file mode 100644 index 00000000000..687d42f0591 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-10.c @@ -0,0 +1,165 @@ +/* { dg-require-effective-target vect_cond_mixed } */ + +#include "tree-vect.h" + +#define N 1024 +float a[N], b[N], c[N], d[N]; +_Bool k[N]; + +__attribute__((noinline, noclone)) void +f1 (void) +{ + int i; + for (i = 0; i < N; ++i) + { + int x = a[i] < b[i]; + int y = c[i] < d[i]; + k[i] = x & y; + } +} + +__attribute__((noinline, noclone)) void +f2 (void) +{ + int i; + for (i = 0; i < N; ++i) + k[i] = (a[i] < b[i]) & (c[i] < d[i]); +} + +__attribute__((noinline, noclone)) void +f3 (void) +{ + int i; + for (i = 0; i < N; ++i) + { + int x = a[i] < b[i]; + int y = c[i] < d[i]; + k[i] = x | y; + } +} + +__attribute__((noinline, noclone)) void +f4 (void) +{ + int i; + for (i = 0; i < N; ++i) + k[i] = (a[i] < b[i]) | (c[i] < d[i]); +} + +__attribute__((noinline, noclone)) void +f5 (_Bool *p) +{ + int i; + for (i = 0; i < N; ++i) + { + int x = a[i] < b[i]; + int y = c[i] < d[i]; + p[i] = x & y; + } +} + +__attribute__((noinline, noclone)) void +f6 (_Bool *p) +{ + int i; + for (i = 0; i < N; ++i) + p[i] = (a[i] < b[i]) & (c[i] < d[i]); +} + +__attribute__((noinline, noclone)) void +f7 (_Bool *p) +{ + int i; + for (i = 0; i < N; ++i) + { + int x = a[i] < b[i]; + int y = c[i] < d[i]; + p[i] = x | y; + } +} + +__attribute__((noinline, noclone)) void +f8 (_Bool *p) +{ + int i; + for (i = 0; i < N; ++i) + p[i] = (a[i] < b[i]) | (c[i] < d[i]); +} + +int +main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break; + case 1: a[i] = 0; b[i] = 0; break; + case 2: a[i] = i + 1; b[i] = - i - 1; break; + case 3: a[i] = i; b[i] = i + 7; break; + case 4: a[i] = i; b[i] = i; break; + case 5: a[i] = i + 16; b[i] = i + 3; break; + case 6: a[i] = - i - 5; b[i] = - i; break; + case 7: a[i] = - i; b[i] = - i; break; + case 8: a[i] = - i; b[i] = - i - 7; break; + } + } + for (i = 0; i < N; i++) + { + switch ((i / 9) % 3) + { + case 0: c[i] = a[i / 9]; d[i] = b[i / 9]; break; + case 1: c[i] = a[i / 9 + 3]; d[i] = b[i / 9 + 3]; break; + case 2: c[i] = a[i / 9 + 6]; d[i] = b[i / 9 + 6]; break; + } + } + f1 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 && ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f2 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 && ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f3 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 || ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f4 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 || ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f5 (k); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 && ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f6 (k); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 && ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f7 (k); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 || ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + f8 (k); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 || ((i / 9) % 3) == 0)) + abort (); + __builtin_memset (k, 0, sizeof (k)); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "note: vectorized 1 loops" 8 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 94e28016681..1386a747955 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1617,7 +1617,7 @@ check_bool_pattern (tree var, loop_vec_info loop_vinfo) { enum machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1)); tree itype - = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 0); + = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1); vecitype = get_vectype_for_scalar_type (itype); if (vecitype == NULL_TREE) return false; @@ -1813,11 +1813,11 @@ adjust_bool_pattern (tree var, tree out_type, tree trueval, default: gcc_assert (TREE_CODE_CLASS (rhs_code) == tcc_comparison); if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE - || TYPE_UNSIGNED (TREE_TYPE (rhs1))) + || !TYPE_UNSIGNED (TREE_TYPE (rhs1))) { enum machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1)); itype - = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 0); + = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1); } else itype = TREE_TYPE (rhs1); @@ -1933,6 +1933,44 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, VEC_safe_push (gimple, heap, *stmts, last_stmt); return pattern_stmt; } + else if (rhs_code == SSA_NAME + && STMT_VINFO_DATA_REF (stmt_vinfo)) + { + stmt_vec_info pattern_stmt_info; + vectype = STMT_VINFO_VECTYPE (stmt_vinfo); + gcc_assert (vectype != NULL_TREE); + if (!check_bool_pattern (var, loop_vinfo)) + return NULL; + + rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), NULL_TREE, stmts); + lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vectype), lhs); + if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) + { + tree rhs2 = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); + gimple cast_stmt + = gimple_build_assign_with_ops (NOP_EXPR, rhs2, rhs, NULL_TREE); + STMT_VINFO_PATTERN_DEF_STMT (stmt_vinfo) = cast_stmt; + rhs = rhs2; + } + pattern_stmt + = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs, NULL_TREE); + pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL); + set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); + STMT_VINFO_DATA_REF (pattern_stmt_info) + = STMT_VINFO_DATA_REF (stmt_vinfo); + STMT_VINFO_DR_BASE_ADDRESS (pattern_stmt_info) + = STMT_VINFO_DR_BASE_ADDRESS (stmt_vinfo); + STMT_VINFO_DR_INIT (pattern_stmt_info) = STMT_VINFO_DR_INIT (stmt_vinfo); + STMT_VINFO_DR_OFFSET (pattern_stmt_info) + = STMT_VINFO_DR_OFFSET (stmt_vinfo); + STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo); + STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info) + = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo); + *type_out = vectype; + *type_in = vectype; + VEC_safe_push (gimple, heap, *stmts, last_stmt); + return pattern_stmt; + } else return NULL; } @@ -1949,19 +1987,22 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (orig_stmt_info); gimple def_stmt; - set_vinfo_for_stmt (pattern_stmt, - new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL)); - gimple_set_bb (pattern_stmt, gimple_bb (orig_stmt)); pattern_stmt_info = vinfo_for_stmt (pattern_stmt); + if (pattern_stmt_info == NULL) + { + pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL); + set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); + } + gimple_set_bb (pattern_stmt, gimple_bb (orig_stmt)); STMT_VINFO_RELATED_STMT (pattern_stmt_info) = orig_stmt; STMT_VINFO_DEF_TYPE (pattern_stmt_info) - = STMT_VINFO_DEF_TYPE (orig_stmt_info); + = STMT_VINFO_DEF_TYPE (orig_stmt_info); STMT_VINFO_VECTYPE (pattern_stmt_info) = pattern_vectype; STMT_VINFO_IN_PATTERN_P (orig_stmt_info) = true; STMT_VINFO_RELATED_STMT (orig_stmt_info) = pattern_stmt; STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info) - = STMT_VINFO_PATTERN_DEF_STMT (orig_stmt_info); + = STMT_VINFO_PATTERN_DEF_STMT (orig_stmt_info); if (STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info)) { def_stmt = STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index fd1cd19f7b3..1aba74601c1 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -159,19 +159,20 @@ vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt, /* This use is out of pattern use, if LHS has other uses that are pattern uses, we should mark the stmt itself, and not the pattern stmt. */ - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) - { - if (is_gimple_debug (USE_STMT (use_p))) - continue; - use_stmt = USE_STMT (use_p); + if (TREE_CODE (lhs) == SSA_NAME) + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) + { + if (is_gimple_debug (USE_STMT (use_p))) + continue; + use_stmt = USE_STMT (use_p); - if (vinfo_for_stmt (use_stmt) - && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) - { - found = true; - break; - } - } + if (vinfo_for_stmt (use_stmt) + && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) + { + found = true; + break; + } + } } if (!found) @@ -3722,6 +3723,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, return false; scalar_dest = gimple_assign_lhs (stmt); + if (TREE_CODE (scalar_dest) == VIEW_CONVERT_EXPR + && is_pattern_stmt_p (stmt_info)) + scalar_dest = TREE_OPERAND (scalar_dest, 0); if (TREE_CODE (scalar_dest) != ARRAY_REF && TREE_CODE (scalar_dest) != INDIRECT_REF && TREE_CODE (scalar_dest) != COMPONENT_REF |