This is remaining bits of vectorizing cond expr bits I posted in
last sept. This patch adds support to 1) vectorize conditional
expressions (using vec_cond_optab). 2) It also adds support to check
dependence distance wrt vectorization factor. This work was
presented in two different patches in sept. (along with 4 other
patches but these two missed GCC 4.0 train.). This patches are
used in autovect-branch and apple-ppc-branch since last 6 months.
2005-03-31 Devang Patel <dpatel@apple.com>
* tree-data-ref.c (build_classic_dist_vector,
compute_subscript_distance): Make externally visible.
* tree-data-ref.h (build_classic_dist_vector,
compute_subscript_distance): Same.
* tree-vect-analyze.c (vect_analyze_operations): Check
vectorizable codition.
(vect_analyze_data_ref_dependence): Check distance vector
against vectorization factor.
(vect_analyze_loop): Determine vectorizaion factor before
analyzing data dependences.
* tree-vect-transform.c (vect_is_simple_cond): New function.
(vectorizable_condition): New function.
(vect_transform_stmt): Handle condition_vec_info_type.
* tree-vectorizer.c (loops_num): Make it global and externally
visible.
* tree-vectorizer.h (enum stmt_vec_info_type): Add
condition_vec_info_type.
(vectorizable_condition, loops_num): New.
* config/rs6000.c (rs6000_emit_vector_select): Fix vector
select
operand ordering.
* lib/target-supports.exp
(check_effective_target_vect_condition): New.
* gcc.dg/vect/vect-dv-1.c: New test.
* gcc.dg/vect/vect-dv-2.c: New test.
* gcc.dg/vect/vect-ifcvt-1.c: New test.
* gcc.dg/vect/vect-ifcvt-2.c: New test.
* gcc.dg/vect/vect-ifcvt-3.c: New test.
* gcc.dg/vect/vect-ifcvt-4.c: New test.
* gcc.dg/vect/vect-ifcvt-5.c: New test.
* gcc.dg/vect/vect-ifcvt-6.c: New test.
* gcc.dg/vect/vect-ifcvt-7.c: New test.
* gcc.dg/vect/vect-none.c: Now one loop is vectorized.
Bootstrapped and tested on powerpc-darwin, tested on SPEC.
-
Devang
Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.24
diff -Idpatel.pbxuser -c -3 -p -r2.24 tree-data-ref.c
*** tree-data-ref.c 9 Mar 2005 11:30:36 -0000 2.24
--- tree-data-ref.c 31 Mar 2005 23:56:06 -0000
*************** all_chrecs_equal_p (tree chrec)
*** 646,652 ****
/* Determine for each subscript in the data dependence relation DDR
the distance. */
! static void
compute_subscript_distance (struct data_dependence_relation *ddr)
{
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
--- 646,652 ----
/* Determine for each subscript in the data dependence relation DDR
the distance. */
! void
compute_subscript_distance (struct data_dependence_relation *ddr)
{
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
*************** subscript_dependence_tester (struct data
*** 1769,1775 ****
starting at FIRST_LOOP_DEPTH.
Return TRUE otherwise. */
! static bool
build_classic_dist_vector (struct data_dependence_relation *ddr,
int nb_loops, int first_loop_depth)
{
--- 1769,1775 ----
starting at FIRST_LOOP_DEPTH.
Return TRUE otherwise. */
! bool
build_classic_dist_vector (struct data_dependence_relation *ddr,
int nb_loops, int first_loop_depth)
{
Index: tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.5
diff -Idpatel.pbxuser -c -3 -p -r2.5 tree-data-ref.h
*** tree-data-ref.h 13 Oct 2004 03:48:03 -0000 2.5
--- tree-data-ref.h 31 Mar 2005 23:56:06 -0000
*************** extern bool array_base_name_differ_p (st
*** 176,181 ****
--- 176,183 ----
extern void free_dependence_relation (struct
data_dependence_relation *);
extern void free_dependence_relations (varray_type);
extern void free_data_refs (varray_type);
+ extern void compute_subscript_distance (struct
data_dependence_relation *);
+ extern bool build_classic_dist_vector (struct
data_dependence_relation *, int, int);
Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.14
diff -Idpatel.pbxuser -c -3 -p -r2.14 tree-vect-analyze.c
*** tree-vect-analyze.c 23 Mar 2005 15:52:59 -0000 2.14
--- tree-vect-analyze.c 31 Mar 2005 23:56:07 -0000
*************** vect_analyze_operations (loop_vec_info l
*** 493,499 ****
ok = (vectorizable_operation (stmt, NULL, NULL)
|| vectorizable_assignment (stmt, NULL, NULL)
|| vectorizable_load (stmt, NULL, NULL)
! || vectorizable_store (stmt, NULL, NULL));
if (!ok)
{
--- 493,500 ----
ok = (vectorizable_operation (stmt, NULL, NULL)
|| vectorizable_assignment (stmt, NULL, NULL)
|| vectorizable_load (stmt, NULL, NULL)
! || vectorizable_store (stmt, NULL, NULL)
! || vectorizable_condition (stmt, NULL, NULL));
if (!ok)
{
*************** vect_analyze_data_ref_dependence (struct
*** 773,778 ****
--- 774,785 ----
{
bool differ_p;
struct data_dependence_relation *ddr;
+ struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ int dist = 0;
+ unsigned int loop_depth = 0;
+ struct loop *loop_nest = loop;
+
if (!vect_base_addr_differ_p (dra, drb, &differ_p))
{
*************** vect_analyze_data_ref_dependence (struct
*** 796,802 ****
if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
return false;
!
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
LOOP_LOC (loop_vinfo)))
{
--- 803,867 ----
if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
return false;
!
! if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
! {
! if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
! LOOP_LOC (loop_vinfo)))
! {
! fprintf (vect_dump,
! "not vectorized: can't determine dependence
between ");
! print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
! fprintf (vect_dump, " and ");
! print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
! }
! return true;
! }
!
! /* Find loop depth. */
! while (loop_nest)
! {
! if (loop_nest->outer && loop_nest->outer->outer)
! {
! loop_nest = loop_nest->outer;
! loop_depth++;
! }
! else
! break;
! }
!
! /* Compute distance vector. */
! compute_subscript_distance (ddr);
! build_classic_dist_vector (ddr, loops_num, loop_nest->depth);
!
! if (!DDR_DIST_VECT (ddr))
! {
! if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
! LOOP_LOC (loop_vinfo)))
! {
! fprintf (vect_dump, "not vectorized: bad dist vector for ");
! print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
! fprintf (vect_dump, " and ");
! print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
! }
! return true;
! }
!
! dist = DDR_DIST_VECT (ddr)[loop_depth];
!
! /* Same loop iteration. */
! if (dist == 0)
! {
! if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
LOOP_LOC (loop_vinfo)))
! fprintf (vect_dump, "dependence distance 0.");
! return false;
! }
!
! if (dist >= vectorization_factor)
! /* Dependence distance does not create dependence, as far as
vectorization
! is concerned, in this case. */
! return false;
!
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
LOOP_LOC (loop_vinfo)))
{
*************** vect_analyze_data_ref_dependence (struct
*** 814,823 ****
/* Function vect_analyze_data_ref_dependences.
Examine all the data references in the loop, and make sure
there do not
! exist any data dependences between them.
!
! TODO: dependences which distance is greater than the
vectorization factor
! can be ignored. */
static bool
vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
--- 879,885 ----
/* Function vect_analyze_data_ref_dependences.
Examine all the data references in the loop, and make sure
there do not
! exist any data dependences between them. */
static bool
vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
*************** vect_analyze_loop (struct loop *loop)
*** 2554,2559 ****
--- 2616,2630 ----
return NULL;
}
+ ok = vect_determine_vectorization_factor (loop_vinfo);
+ if (!ok)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC
(loop_vinfo)))
+ fprintf (vect_dump, "can't determine vectorization
factor.");
+ destroy_loop_vec_info (loop_vinfo);
+ return NULL;
+ }
+
/* Analyze data dependences between the data-refs in the loop.
FORNOW: fail at the first data dependence that we
encounter. */
*************** vect_analyze_loop (struct loop *loop)
*** 2578,2592 ****
return NULL;
}
- ok = vect_determine_vectorization_factor (loop_vinfo);
- if (!ok)
- {
- if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC
(loop_vinfo)))
- fprintf (vect_dump, "can't determine vectorization
factor.");
- destroy_loop_vec_info (loop_vinfo);
- return NULL;
- }
-
/* Analyze the alignment of the data-refs in the loop.
FORNOW: Only aligned accesses are handled. */
--- 2649,2654 ----
Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.7
diff -Idpatel.pbxuser -c -3 -p -r2.7 tree-vect-transform.c
*** tree-vect-transform.c 15 Mar 2005 18:32:58 -0000 2.7
--- tree-vect-transform.c 31 Mar 2005 23:56:07 -0000
*************** static tree vect_get_vec_def_for_operand
*** 57,62 ****
--- 57,63 ----
static tree vect_init_vector (tree, tree);
static void vect_finish_stmt_generation
(tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
+ static bool vect_is_simple_cond (tree, loop_vec_info);
/* Utility function dealing with loop peeling (not peeling
itself). */
static void vect_generate_tmps_on_preheader
*************** vectorizable_load (tree stmt, block_stmt
*** 1128,1133 ****
--- 1129,1273 ----
return true;
}
+ /* Function vect_is_simple_cond.
+
+ Input:
+ LOOP - the loop that is being vectorized.
+ COND - Condition that is checked for simple use.
+
+ Returns whether a COND can be vectorized. Checkes whether
+ condition operands are supportable using vec_is_simple_use. */
+
+ static bool
+ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
+ {
+ tree lhs, rhs;
+
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) != tcc_comparison)
+ return false;
+
+ lhs = TREE_OPERAND (cond, 0);
+ rhs = TREE_OPERAND (cond, 1);
+
+ if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ tree lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
+ if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt))
+ return false;
+ }
+ else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) !=
REAL_CST)
+ return false;
+
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ tree rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt))
+ return false;
+ }
+ else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) !=
REAL_CST)
+ return false;
+
+ return true;
+ }
+
+ /* vectorizable_condition.
+
+ Check if STMT is conditional modify expression that can be
vectorized.
+ If VEC_STMT is also passed, vectorize the STMT: create a
vectorized
+ stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT,
and insert it
+ at BSI.
+
+ Return FALSE if not a vectorizable STMT, TRUE otherwise. */
+
+ bool
+ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree
*vec_stmt)
+ {
+ tree scalar_dest = NULL_TREE;
+ tree vec_dest = NULL_TREE;
+ tree op = NULL_TREE;
+ tree cond_expr, then_clause, else_clause;
+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ tree vec_cond_lhs, vec_cond_rhs, vec_then_clause, vec_else_clause;
+ tree vec_compare, vec_cond_expr;
+ tree new_temp;
+ loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ enum machine_mode vec_mode;
+
+ if (!STMT_VINFO_RELEVANT_P (stmt_info))
+ return false;
+
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return false;
+
+ op = TREE_OPERAND (stmt, 1);
+
+ if (TREE_CODE (op) != COND_EXPR)
+ return false;
+
+ cond_expr = TREE_OPERAND (op, 0);
+ then_clause = TREE_OPERAND (op, 1);
+ else_clause = TREE_OPERAND (op, 2);
+
+ if (!vect_is_simple_cond (cond_expr, loop_vinfo))
+ return false;
+
+ if (TREE_CODE (then_clause) == SSA_NAME)
+ {
+ tree then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
+ if (!vect_is_simple_use (then_clause, loop_vinfo,
&then_def_stmt))
+ return false;
+ }
+ else if (TREE_CODE (then_clause) != INTEGER_CST
+ && TREE_CODE (then_clause) != REAL_CST)
+ return false;
+
+ if (TREE_CODE (else_clause) == SSA_NAME)
+ {
+ tree else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
+ if (!vect_is_simple_use (else_clause, loop_vinfo,
&else_def_stmt))
+ return false;
+ }
+ else if (TREE_CODE (else_clause) != INTEGER_CST
+ && TREE_CODE (else_clause) != REAL_CST)
+ return false;
+
+
+ vec_mode = TYPE_MODE (vectype);
+
+ if (!vec_stmt)
+ {
+ STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
+ return expand_vec_cond_expr_p (op, vec_mode);
+ }
+
+ /* Transform */
+
+ /* Handle def. */
+ scalar_dest = TREE_OPERAND (stmt, 0);
+ 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);
+ vec_cond_rhs =
+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
stmt);
+ vec_then_clause = vect_get_vec_def_for_operand (then_clause,
stmt);
+ vec_else_clause = vect_get_vec_def_for_operand (else_clause,
stmt);
+
+ /* 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 = build (VEC_COND_EXPR, vectype,
+ vec_compare, vec_then_clause,
vec_else_clause);
+
+ *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
vec_cond_expr);
+ new_temp = make_ssa_name (vec_dest, *vec_stmt);
+ TREE_OPERAND (*vec_stmt, 0) = new_temp;
+ vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+
+ return true;
+ }
/* Function vect_transform_stmt.
*************** vect_transform_stmt (tree stmt, block_st
*** 1163,1168 ****
--- 1303,1314 ----
gcc_assert (done);
is_store = true;
break;
+
+ case condition_vec_info_type:
+ done = vectorizable_condition (stmt, bsi, &vec_stmt);
+ gcc_assert (done);
+ break;
+
default:
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "stmt not supported.");
Index: tree-vectorizer.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
retrieving revision 2.80
diff -Idpatel.pbxuser -c -3 -p -r2.80 tree-vectorizer.c
*** tree-vectorizer.c 16 Mar 2005 21:42:55 -0000 2.80
--- tree-vectorizer.c 31 Mar 2005 23:56:07 -0000
*************** FILE *vect_dump;
*** 176,182 ****
to mark that it's uninitialized. */
enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
!
/
**********************************************************************
***
Simple Loop Peeling Utilities
--- 176,182 ----
to mark that it's uninitialized. */
enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
! unsigned int loops_num;
/
**********************************************************************
***
Simple Loop Peeling Utilities
*************** need_imm_uses_for (tree var)
*** 1554,1560 ****
void
vectorize_loops (struct loops *loops)
{
! unsigned int i, loops_num;
unsigned int num_vectorized_loops = 0;
/* Fix the verbosity level if not defined explicitly by the
user. */
--- 1554,1560 ----
void
vectorize_loops (struct loops *loops)
{
! unsigned int i;
unsigned int num_vectorized_loops = 0;
/* Fix the verbosity level if not defined explicitly by the
user. */
Index: tree-vectorizer.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.h,v
retrieving revision 2.16
diff -Idpatel.pbxuser -c -3 -p -r2.16 tree-vectorizer.h
*** tree-vectorizer.h 15 Mar 2005 18:33:00 -0000 2.16
--- tree-vectorizer.h 31 Mar 2005 23:56:07 -0000
*************** enum stmt_vec_info_type {
*** 144,150 ****
load_vec_info_type,
store_vec_info_type,
op_vec_info_type,
! assignment_vec_info_type
};
typedef struct _stmt_vec_info {
--- 144,151 ----
load_vec_info_type,
store_vec_info_type,
op_vec_info_type,
! assignment_vec_info_type,
! condition_vec_info_type
};
typedef struct _stmt_vec_info {
*************** known_alignment_for_access_p (struct dat
*** 270,276 ****
/* vect_dump will be set to stderr or dump_file if exist. */
extern FILE *vect_dump;
extern enum verbosity_levels vect_verbosity_level;
!
/
*-----------------------------------------------------------------*/
/* Function
prototypes. */
/
*-----------------------------------------------------------------*/
--- 271,277 ----
/* vect_dump will be set to stderr or dump_file if exist. */
extern FILE *vect_dump;
extern enum verbosity_levels vect_verbosity_level;
! extern unsigned int loops_num;
/
*-----------------------------------------------------------------*/
/* Function
prototypes. */
/
*-----------------------------------------------------------------*/
*************** extern bool vectorizable_load (tree, blo
*** 321,326 ****
--- 322,328 ----
extern bool vectorizable_store (tree, block_stmt_iterator *, tree
*);
extern bool vectorizable_operation (tree, block_stmt_iterator *,
tree *);
extern bool vectorizable_assignment (tree, block_stmt_iterator *,
tree *);
+ extern bool vectorizable_condition (tree, block_stmt_iterator *,
tree *);
/* Driver for transformation stage. */
extern void vect_transform_loop (loop_vec_info, struct loops *);
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.796
diff -Idpatel.pbxuser -c -3 -p -r1.796 rs6000.c
*** config/rs6000/rs6000.c 20 Mar 2005 23:25:14 -0000 1.796
--- config/rs6000/rs6000.c 31 Mar 2005 23:56:08 -0000
*************** rs6000_emit_vector_select (rtx dest, rtx
*** 10667,10673 ****
t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
gen_rtx_fmt_Ei (UNSPEC, dest_mode,
! gen_rtvec (3, op1, op2, mask),
vsel_insn_index));
emit_insn (t);
emit_move_insn (dest, temp);
--- 10667,10673 ----
t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
gen_rtx_fmt_Ei (UNSPEC, dest_mode,
! gen_rtvec (3, op2, op1, mask),
vsel_insn_index));
emit_insn (t);
emit_move_insn (dest, temp);
Index: testsuite/gcc.dg/vect/vect-dv-1.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-1.c
diff -N testsuite/gcc.dg/vect/vect-dv-1.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-1.c 31 Mar 2005 23:56:09 -0000
***************
*** 0 ****
--- 1,22 ----
+ /* Test compiler crash when dependence analyzer can not represent
+ dependence relation by distance vector. */
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_int } */
+
+ int x[199];
+
+ void foo()
+
+ {
+ int t,j;
+
+ for (j=99;j>0;j--)
+ x [j+j]=x[j];
+
+ for (j=198;j>=100;j--)
+ if(x[j])
+ {
+ x[j-63]=x[j-3]-x[j];
+ }
+ }
+
Index: testsuite/gcc.dg/vect/vect-dv-2.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-2.c
diff -N testsuite/gcc.dg/vect/vect-dv-2.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-2.c 31 Mar 2005 23:56:09 -0000
***************
*** 0 ****
--- 1,73 ----
+ /* { dg-do run } */
+ /* { dg-require-effective-target vect_int } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 64
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N];
+ int B[N];
+ int C[N];
+ int D[N];
+
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ {
+ A[i] = i;
+ B[i] = i;
+ C[i] = i;
+ D[i] = i;
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < 16; i++)
+ {
+ A[i] = A[i+20];
+ }
+
+ /* check results: */
+ for (i = 0; i < 16; i++)
+ {
+ if (A[i] != A[i+20])
+ abort ();
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < 16; i++)
+ {
+ B[i] = B[i] + 5;
+ }
+
+ /* check results: */
+ for (i = 0; i < 16; i++)
+ {
+ if (B[i] != C[i] + 5)
+ abort ();
+ }
+
+ /* Not vectorizable */
+ for (i = 0; i < 4; i++)
+ {
+ C[i] = C[i+3];
+ }
+
+ /* check results: */
+ for (i = 0; i < 4; i++)
+ {
+ if (C[i] != D[i+3])
+ abort ();
+ }
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1
"vect" { xfail vect_no_align } } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-1.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-1.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-1.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-1.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,75 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -
maltivec" { target powerpc*-*-* } } */
+ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -
msse2" { target i?86-*-* x86_64-*-* } } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 64
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N];
+ int B[N];
+ int C[N];
+ int D[N];
+
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ {
+ A[i] = i;
+ B[i] = i;
+ C[i] = i;
+ D[i] = i;
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < 16; i++)
+ {
+ A[i] = A[i+20];
+ }
+
+ /* check results: */
+ for (i = 0; i < 16; i++)
+ {
+ if (A[i] != A[i+20])
+ abort ();
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < 16; i++)
+ {
+ B[i] = B[i] + 5;
+ }
+
+ /* check results: */
+ for (i = 0; i < 16; i++)
+ {
+ if (B[i] != C[i] + 5)
+ abort ();
+ }
+
+ /* Not vectorizable */
+ for (i = 0; i < 4; i++)
+ {
+ C[i] = C[i+3];
+ }
+
+ /* check results: */
+ for (i = 0; i < 4; i++)
+ {
+ if (C[i] != D[i+3])
+ abort ();
+ }
+
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1
"vect" { xfail vect_no_align } } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-2.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-2.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-2.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-2.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] >= MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-3.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-3.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-3.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-3.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] > MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-4.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-4.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-4.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-4.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] <= MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-5.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-5.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-5.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-5.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] < MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-6.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-6.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-6.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-6.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11};
+ int B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] != MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-7.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-7.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-7.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-7.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11};
+ int B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42};
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] == MAX ? 0 : MAX);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-9.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-9.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-9.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-9.c 31 Mar 2005
23:56:09 -0000
***************
*** 0 ****
--- 1,36 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ void foo () __attribute__((always_inline));
+ void foo ()
+ {
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] >= MAX ? MAX : 0);
+ }
+
+ int main ()
+ {
+
+ int i, j;
+ foo ();
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+ }
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-none.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-none.c,v
retrieving revision 1.4
diff -Idpatel.pbxuser -c -3 -p -r1.4 vect-none.c
*** testsuite/gcc.dg/vect/vect-none.c 9 Jan 2005 17:30:24
-0000 1.4
--- testsuite/gcc.dg/vect/vect-none.c 31 Mar 2005 23:56:09 -0000
*************** foo (int n)
*** 181,184 ****
}
/* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 3
"vect"} } */
--- 181,185 ----
}
/* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1
"vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2
"vect"} } */
Index: testsuite/lib/target-supports.exp
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/lib/target-supports.exp,v
retrieving revision 1.46
diff -Idpatel.pbxuser -c -3 -p -r1.46 target-supports.exp
*** testsuite/lib/target-supports.exp 25 Mar 2005 02:21:01
-0000 1.46
--- testsuite/lib/target-supports.exp 31 Mar 2005 23:56:09 -0000
*************** proc check_effective_target_vect_no_alig
*** 765,770 ****
--- 765,789 ----
return $et_vect_no_align_saved
}
+ # Return 1 if the target supports vector conditional operations,
0 otherwise.
+
+ proc check_effective_target_vect_condition { } {
+ global et_vect_cond_saved
+
+ if [info exists et_vect_int_cond] {
+ verbose "check_effective_target_vect_cond: using cached
result" 2
+ } else {
+ set et_vect_cond_saved 0
+ if { [istarget powerpc*-*-*] } {
+ set et_vect_cond_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_cond: returning
$et_vect_cond_saved" 2
+ return $et_vect_cond_saved
+ }
+
+
# Return 1 if the target matches the effective target 'arg', 0
otherwise.
# This can be used with any check_* proc that takes no argument and
# returns only 1 or 0. It could be used with check_* procs that
take