| Submitter | Michael Matz |
|---|---|
| Date | Sept. 7, 2010, 1:10 p.m. |
| Message ID | <Pine.LNX.4.64.1009071507470.29722@wotan.suse.de> |
| Download | mbox | patch |
| Permalink | /patch/64010/ |
| State | New |
| Headers | show |
Comments
On Tue, Sep 7, 2010 at 3:10 PM, Michael Matz <matz@suse.de> wrote: > Hi, > > for this testcase we need to emit multiple vectorized conditional > statement per original statement (ncopies > 1). This patch implements the > support for that in case the conditional isn't part of a reduction (I'm > didn't 100% follow the code under which conditions reduc_index is != 0 and > what reduc_def then is, exactly). > > Regstrapped on x86_64-linux, no regressions. Okay? Ok. Thanks, Richard. > > Ciao, > Michael. > -- > PR tree-optimization/43430 > * tree-vect-stmts.c (vectorizable_condition): Support multiple > copies for conditional statements if it's not part of a reduction. > > testsuite/ > PR tree-optimization/43430 > * gcc.dg/vect/pr43430-2.c: New test. > > Index: tree-vect-stmts.c > =================================================================== > --- tree-vect-stmts.c (revision 163773) > +++ tree-vect-stmts.c (working copy) > @@ -4011,16 +4011,18 @@ vectorizable_condition (gimple stmt, gim > loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); > enum machine_mode vec_mode; > tree def; > - enum vect_def_type dt; > + enum vect_def_type dt, dts[4]; > int nunits = TYPE_VECTOR_SUBPARTS (vectype); > int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; > enum tree_code code; > + stmt_vec_info prev_stmt_info = NULL; > + int j; > > /* FORNOW: unsupported in basic block SLP. */ > gcc_assert (loop_vinfo); > > gcc_assert (ncopies >= 1); > - if (ncopies > 1) > + if (reduc_index && ncopies > 1) > return false; /* FORNOW */ > > if (!STMT_VINFO_RELEVANT_P (stmt_info)) > @@ -4107,29 +4109,68 @@ vectorizable_condition (gimple stmt, gim > vec_dest = vect_create_destination_var (scalar_dest, vectype); > > /* Handle cond expr. */ > - vec_cond_lhs = > - vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL); > - vec_cond_rhs = > - vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL); > - if (reduc_index == 1) > - vec_then_clause = reduc_def; > - else > - vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL); > - if (reduc_index == 2) > - vec_else_clause = reduc_def; > - else > - vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL); > - > - /* Arguments are ready. Create the new vector stmt. */ > - vec_compare = build2 (TREE_CODE (cond_expr), vectype, > - vec_cond_lhs, vec_cond_rhs); > - vec_cond_expr = build3 (VEC_COND_EXPR, vectype, > - vec_compare, vec_then_clause, vec_else_clause); > - > - *vec_stmt = gimple_build_assign (vec_dest, vec_cond_expr); > - new_temp = make_ssa_name (vec_dest, *vec_stmt); > - gimple_assign_set_lhs (*vec_stmt, new_temp); > - vect_finish_stmt_generation (stmt, *vec_stmt, gsi); > + for (j = 0; j < ncopies; j++) > + { > + gimple new_stmt; > + if (j == 0) > + { > + gimple gtemp; > + vec_cond_lhs = > + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), > + stmt, NULL); > + vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo, > + NULL, >emp, &def, &dts[0]); > + vec_cond_rhs = > + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), > + stmt, NULL); > + vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo, > + NULL, >emp, &def, &dts[1]); > + if (reduc_index == 1) > + vec_then_clause = reduc_def; > + else > + { > + vec_then_clause = vect_get_vec_def_for_operand (then_clause, > + stmt, NULL); > + vect_is_simple_use (then_clause, loop_vinfo, > + NULL, >emp, &def, &dts[2]); > + } > + if (reduc_index == 2) > + vec_else_clause = reduc_def; > + else > + { > + vec_else_clause = vect_get_vec_def_for_operand (else_clause, > + stmt, NULL); > + vect_is_simple_use (else_clause, loop_vinfo, > + NULL, >emp, &def, &dts[3]); > + } > + } > + else > + { > + vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs); > + vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs); > + vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2], > + vec_then_clause); > + vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3], > + vec_else_clause); > + } > + > + /* Arguments are ready. Create the new vector stmt. */ > + vec_compare = build2 (TREE_CODE (cond_expr), vectype, > + vec_cond_lhs, vec_cond_rhs); > + vec_cond_expr = build3 (VEC_COND_EXPR, vectype, > + vec_compare, vec_then_clause, vec_else_clause); > + > + new_stmt = gimple_build_assign (vec_dest, vec_cond_expr); > + new_temp = make_ssa_name (vec_dest, new_stmt); > + gimple_assign_set_lhs (new_stmt, new_temp); > + vect_finish_stmt_generation (stmt, new_stmt, gsi); > + if (j == 0) > + STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; > + else > + STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; > + > + prev_stmt_info = vinfo_for_stmt (new_stmt); > + } > > return true; > } > Index: testsuite/gcc.dg/vect/pr43430-2.c > =================================================================== > --- testsuite/gcc.dg/vect/pr43430-2.c (revision 0) > +++ testsuite/gcc.dg/vect/pr43430-2.c (revision 0) > @@ -0,0 +1,17 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target vect_int } */ > +/* { dg-options "-O3 -fno-vect-cost-model -fdump-tree-vect-details" } */ > +typedef unsigned char uint8_t; > +vsad16_c (void *c, uint8_t * s1, uint8_t * s2, int stride, int h) > +{ > + int score = 0; > + int x, y; > + for (x = 0; x < 16; x++) > + score += ((s1[x] - s1[x + stride] + s2[x + stride]) >= 0 ? > + s1[x] + s2[x + stride] : > + s2[x + stride]); > + return score; > +} > + > +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */ > +/* { dg-final { cleanup-tree-dump "vect" } } */ >
Patch
Index: tree-vect-stmts.c =================================================================== --- tree-vect-stmts.c (revision 163773) +++ tree-vect-stmts.c (working copy) @@ -4011,16 +4011,18 @@ vectorizable_condition (gimple stmt, gim loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); enum machine_mode vec_mode; tree def; - enum vect_def_type dt; + enum vect_def_type dt, dts[4]; int nunits = TYPE_VECTOR_SUBPARTS (vectype); int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; enum tree_code code; + stmt_vec_info prev_stmt_info = NULL; + int j; /* FORNOW: unsupported in basic block SLP. */ gcc_assert (loop_vinfo); gcc_assert (ncopies >= 1); - if (ncopies > 1) + if (reduc_index && ncopies > 1) return false; /* FORNOW */ if (!STMT_VINFO_RELEVANT_P (stmt_info)) @@ -4107,29 +4109,68 @@ vectorizable_condition (gimple stmt, gim vec_dest = vect_create_destination_var (scalar_dest, vectype); /* Handle cond expr. */ - vec_cond_lhs = - vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL); - vec_cond_rhs = - vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL); - if (reduc_index == 1) - vec_then_clause = reduc_def; - else - vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL); - if (reduc_index == 2) - vec_else_clause = reduc_def; - else - vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL); - - /* Arguments are ready. Create the new vector stmt. */ - vec_compare = build2 (TREE_CODE (cond_expr), vectype, - vec_cond_lhs, vec_cond_rhs); - vec_cond_expr = build3 (VEC_COND_EXPR, vectype, - vec_compare, vec_then_clause, vec_else_clause); - - *vec_stmt = gimple_build_assign (vec_dest, vec_cond_expr); - new_temp = make_ssa_name (vec_dest, *vec_stmt); - gimple_assign_set_lhs (*vec_stmt, new_temp); - vect_finish_stmt_generation (stmt, *vec_stmt, gsi); + for (j = 0; j < ncopies; j++) + { + gimple new_stmt; + if (j == 0) + { + gimple gtemp; + vec_cond_lhs = + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), + stmt, NULL); + vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo, + NULL, >emp, &def, &dts[0]); + vec_cond_rhs = + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), + stmt, NULL); + vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo, + NULL, >emp, &def, &dts[1]); + if (reduc_index == 1) + vec_then_clause = reduc_def; + else + { + vec_then_clause = vect_get_vec_def_for_operand (then_clause, + stmt, NULL); + vect_is_simple_use (then_clause, loop_vinfo, + NULL, >emp, &def, &dts[2]); + } + if (reduc_index == 2) + vec_else_clause = reduc_def; + else + { + vec_else_clause = vect_get_vec_def_for_operand (else_clause, + stmt, NULL); + vect_is_simple_use (else_clause, loop_vinfo, + NULL, >emp, &def, &dts[3]); + } + } + else + { + vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs); + vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs); + vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2], + vec_then_clause); + vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3], + vec_else_clause); + } + + /* Arguments are ready. Create the new vector stmt. */ + vec_compare = build2 (TREE_CODE (cond_expr), vectype, + vec_cond_lhs, vec_cond_rhs); + vec_cond_expr = build3 (VEC_COND_EXPR, vectype, + vec_compare, vec_then_clause, vec_else_clause); + + new_stmt = gimple_build_assign (vec_dest, vec_cond_expr); + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_assign_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (stmt, new_stmt, gsi); + if (j == 0) + STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; + else + STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; + + prev_stmt_info = vinfo_for_stmt (new_stmt); + } return true; } Index: testsuite/gcc.dg/vect/pr43430-2.c =================================================================== --- testsuite/gcc.dg/vect/pr43430-2.c (revision 0) +++ testsuite/gcc.dg/vect/pr43430-2.c (revision 0) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-options "-O3 -fno-vect-cost-model -fdump-tree-vect-details" } */ +typedef unsigned char uint8_t; +vsad16_c (void *c, uint8_t * s1, uint8_t * s2, int stride, int h) +{ + int score = 0; + int x, y; + for (x = 0; x < 16; x++) + score += ((s1[x] - s1[x + stride] + s2[x + stride]) >= 0 ? + s1[x] + s2[x + stride] : + s2[x + stride]); + return score; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */