Index: testsuite/ChangeLog.autovect =================================================================== --- testsuite/ChangeLog.autovect (revision 127146) +++ testsuite/ChangeLog.autovect (working copy) @@ -1,3 +1,7 @@ +2007-08-02 Ira Rosen + + * gcc.dg/vect/slp-36.c: New. + 2007-08-01 Dorit Nuzman Ira Rosen Index: testsuite/gcc.dg/vect/slp-36.c =================================================================== --- testsuite/gcc.dg/vect/slp-36.c (revision 0) +++ testsuite/gcc.dg/vect/slp-36.c (revision 0) @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ + +#define N 32 +void +test_1 (void) +{ + static unsigned int bm[N]; + static unsigned int cm[N]; + int j; + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= 8; + bm[2*j+1] <<= 8; + } + for (j = 0; j < N/2; j++) + { + cm[2*j] <<= 8; + cm[2*j+1] <<= 7; + } +} + +void +test_2 (int a, int b) +{ + static unsigned int bm[N]; + static unsigned int cm[N]; + int j; + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= a; + bm[2*j+1] <<= a; + } + for (j = 0; j < N/2; j++) + { + cm[2*j] <<= a; + cm[2*j+1] <<= b; + } +} + +void +test_3 (void) +{ + static unsigned int bm[N]; + int am[N]; + int j; + + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= am[j]; + bm[2*j+1] <<= am[j]; + } + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= am[2*j]; + bm[2*j+1] <<= am[2*j+1]; + } + +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ Index: tree-vect-analyze.c =================================================================== --- tree-vect-analyze.c (revision 127146) +++ tree-vect-analyze.c (working copy) @@ -39,6 +39,7 @@ Software Foundation, 51 Franklin Street, #include "tree-scalar-evolution.h" #include "tree-vectorizer.h" #include "toplev.h" +#include "recog.h" /* Main analysis functions. */ static loop_vec_info vect_analyze_loop_form (struct loop *); @@ -2316,9 +2317,13 @@ vect_build_slp_tree (loop_vec_info loop_ enum tree_code first_stmt_code = 0; tree first_stmt_def1_type = NULL_TREE, first_stmt_def0_type = NULL_TREE; tree lhs, rhs, prev_stmt = NULL_TREE; - bool stop_recursion = false; - tree vectype, scalar_type; + bool stop_recursion = false, need_same_oprnds = false; + tree vectype, scalar_type, first_op1 = NULL_TREE; unsigned int vectorization_factor = 0, ncopies; + optab optab; + int icode; + enum machine_mode optab_op2_mode; + enum machine_mode vec_mode; /* For every stmt in NODE find its def stmt/s. */ for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++) @@ -2359,19 +2364,57 @@ vect_build_slp_tree (loop_vec_info loop_ /* Check the operation. */ if (i == 0) - first_stmt_code = TREE_CODE (rhs); - else - if (first_stmt_code != TREE_CODE (rhs)) - { - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, - "Build SLP failed: different operation in stmt "); - print_generic_expr (vect_dump, stmt, TDF_SLIM); - } + { + first_stmt_code = TREE_CODE (rhs); - return false; - } + /* Shift arguments should be equal in all the packed stmts for a + vector shift with scalar shift operand. */ + if (TREE_CODE (rhs) == LSHIFT_EXPR || TREE_CODE (rhs) == RSHIFT_EXPR) + { + vec_mode = TYPE_MODE (vectype); + optab = optab_for_tree_code (TREE_CODE (rhs), vectype); + if (!optab) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Build SLP failed: no optab."); + return false; + } + icode = (int) optab->handlers[(int) vec_mode].insn_code; + optab_op2_mode = insn_data[icode].operand[2].mode; + if (!VECTOR_MODE_P (optab_op2_mode)) + { + need_same_oprnds = true; + first_op1 = TREE_OPERAND (rhs, 1); + } + } + } + else + { + if (first_stmt_code != TREE_CODE (rhs)) + { + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, + "Build SLP failed: different operation in stmt "); + print_generic_expr (vect_dump, stmt, TDF_SLIM); + } + + return false; + } + + if (need_same_oprnds + && !operand_equal_p (first_op1, TREE_OPERAND (rhs, 1), 0)) + { + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, + "Build SLP failed: different shift arguments in "); + print_generic_expr (vect_dump, stmt, TDF_SLIM); + } + + return false; + } + } /* Strided store or load. */ if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt))) @@ -2455,7 +2498,7 @@ vect_build_slp_tree (loop_vec_info loop_ { if (vect_print_dump_info (REPORT_DETAILS)) { - fprintf (vect_dump, "Build SLP failed: operation not"); + fprintf (vect_dump, "Build SLP failed: operation"); fprintf (vect_dump, " unsupported "); print_generic_expr (vect_dump, stmt, TDF_SLIM); } Index: tree-vect-transform.c =================================================================== --- tree-vect-transform.c (revision 127146) +++ tree-vect-transform.c (working copy) @@ -3626,10 +3626,6 @@ vectorizable_operation (tree stmt, block if (!VECTOR_MODE_P (vec_mode)) return false; - /* FORNOW: SLP not supported. */ - if (STMT_VINFO_SLP_TYPE (stmt_info)) - return false; - /* Invariant argument is needed for a vector shift by a scalar shift operand. */ optab_op2_mode = insn_data[icode].operand[2].mode; Index: Makefile.in =================================================================== --- Makefile.in (revision 127146) +++ Makefile.in (working copy) @@ -2158,7 +2158,7 @@ tree-data-ref.o: tree-data-ref.c $(CONFI $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h langhooks.h tree-vect-analyze.o: tree-vect-analyze.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(BASIC_BLOCK_H) \ + $(TM_H) $(GGC_H) $(OPTABS_H) $(RECOG_H) $(TREE_H) $(BASIC_BLOCK_H) \ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) tree-chrec.h tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \