diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106769.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106769.patch | 1281 |
1 files changed, 0 insertions, 1281 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106769.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106769.patch deleted file mode 100644 index 3a149231f8..0000000000 --- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106769.patch +++ /dev/null @@ -1,1281 +0,0 @@ -2011-07-11 Ira Rosen <ira.rosen@linaro.org> - - Backport from FSF: - 2011-06-16 Ira Rosen <ira.rosen@linaro.org> - - gcc/ - * tree-vectorizer.h (vect_recog_func_ptr): Change the first - argument to be a VEC of statements. - * tree-vect-loop.c (vect_determine_vectorization_factor): Remove the - assert that pattern statements have to have their vector type set. - * tree-vect-patterns.c (vect_recog_widen_sum_pattern): - Change the first argument to be a VEC of statements. Update - documentation. - (vect_recog_dot_prod_pattern, vect_recog_pow_pattern): Likewise. - (vect_handle_widen_mult_by_const): New function. - (vect_recog_widen_mult_pattern): Change the first argument to be a - VEC of statements. Update documentation. Check that the constant is - INTEGER_CST. Support multiplication by a constant that fits an - intermediate type - call vect_handle_widen_mult_by_const. - (vect_pattern_recog_1): Update vect_recog_func_ptr and its - call. Handle additional pattern statements if necessary. - - gcc/testsuite/ - * gcc.dg/vect/vect-widen-mult-half-u8.c: New test. - - and - 2011-06-30 Ira Rosen <ira.rosen@linaro.org> - - gcc/ - * tree-vect-loop.c (vect_determine_vectorization_factor): Handle - both pattern and original statements if necessary. - (vect_transform_loop): Likewise. - * tree-vect-patterns.c (vect_pattern_recog): Update documentation. - * tree-vect-stmts.c (vect_mark_relevant): Add new argument. - Mark the pattern statement only if the original statement doesn't - have its own uses. - (process_use): Call vect_mark_relevant with additional parameter. - (vect_mark_stmts_to_be_vectorized): Likewise. - (vect_get_vec_def_for_operand): Use vectorized pattern statement. - (vect_analyze_stmt): Handle both pattern and original statements - if necessary. - (vect_transform_stmt): Don't store vectorized pattern statement - in the original statement. - (vect_is_simple_use_1): Use related pattern statement only if the - original statement is irrelevant. - * tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise. - - gcc/testsuite/ - * gcc.dg/vect/slp-widen-mult-half.c: New test. - * gcc.dg/vect/vect-widen-mult-half.c: New test. - -=== added file 'gcc/testsuite/gcc.dg/vect/slp-widen-mult-half.c' -Index: gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/slp-widen-mult-half.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/slp-widen-mult-half.c 2012-01-09 15:03:29.156918805 -0800 -@@ -0,0 +1,52 @@ -+/* { dg-require-effective-target vect_int } */ -+ -+#include "tree-vect.h" -+#include <stdlib.h> -+ -+#define N 32 -+#define COEF 32470 -+#define COEF2 324700 -+ -+unsigned char in[N]; -+int out[N]; -+int out2[N]; -+ -+__attribute__ ((noinline)) void -+foo () -+{ -+ int i; -+ -+ for (i = 0; i < N/2; i++) -+ { -+ out[2*i] = in[2*i] * COEF; -+ out2[2*i] = in[2*i] + COEF2; -+ out[2*i+1] = in[2*i+1] * COEF; -+ out2[2*i+1] = in[2*i+1] + COEF2; -+ } -+} -+ -+int main (void) -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ { -+ in[i] = i; -+ __asm__ volatile (""); -+ } -+ -+ foo (); -+ -+ for (i = 0; i < N; i++) -+ if (out[i] != in[i] * COEF || out2[i] != in[i] + COEF2) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ -+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_widen_mult_hi_to_si } } } */ -+/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { scan-tree-dump-times "pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ -+ -Index: gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half-u8.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half-u8.c 2012-01-09 15:03:29.156918805 -0800 -@@ -0,0 +1,59 @@ -+/* { dg-require-effective-target vect_int } */ -+ -+#include "tree-vect.h" -+#include <stdlib.h> -+ -+#define N 32 -+#define COEF 32470 -+ -+unsigned char in[N]; -+int out[N]; -+ -+__attribute__ ((noinline)) void -+foo () -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ out[i] = in[i] * COEF; -+} -+ -+__attribute__ ((noinline)) void -+bar () -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ out[i] = COEF * in[i]; -+} -+ -+int main (void) -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ { -+ in[i] = i; -+ __asm__ volatile (""); -+ } -+ -+ foo (); -+ -+ for (i = 0; i < N; i++) -+ if (out[i] != in[i] * COEF) -+ abort (); -+ -+ bar (); -+ -+ for (i = 0; i < N; i++) -+ if (out[i] != in[i] * COEF) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_widen_mult_hi_to_si } } } */ -+/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { scan-tree-dump-times "pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ -+ -Index: gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half.c 2012-01-09 15:03:29.160918806 -0800 -@@ -0,0 +1,49 @@ -+/* { dg-require-effective-target vect_int } */ -+ -+#include "tree-vect.h" -+#include <stdlib.h> -+ -+#define N 32 -+#define COEF 32470 -+#define COEF2 324700 -+ -+unsigned char in[N]; -+int out[N]; -+int out2[N]; -+ -+__attribute__ ((noinline)) void -+foo (int a) -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ { -+ out[i] = in[i] * COEF; -+ out2[i] = in[i] + a; -+ } -+} -+ -+int main (void) -+{ -+ int i; -+ -+ for (i = 0; i < N; i++) -+ { -+ in[i] = i; -+ __asm__ volatile (""); -+ } -+ -+ foo (COEF2); -+ -+ for (i = 0; i < N; i++) -+ if (out[i] != in[i] * COEF || out2[i] != in[i] + COEF2) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ -+/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { scan-tree-dump-times "pattern recognized" 1 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ -+ -Index: gcc-4_6-branch/gcc/tree-vect-loop.c -=================================================================== ---- gcc-4_6-branch.orig/gcc/tree-vect-loop.c 2012-01-09 15:02:15.000000000 -0800 -+++ gcc-4_6-branch/gcc/tree-vect-loop.c 2012-01-09 15:03:29.160918806 -0800 -@@ -181,6 +181,8 @@ - stmt_vec_info stmt_info; - int i; - HOST_WIDE_INT dummy; -+ gimple stmt, pattern_stmt = NULL; -+ bool analyze_pattern_stmt = false; - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "=== vect_determine_vectorization_factor ==="); -@@ -241,12 +243,20 @@ - } - } - -- for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) -+ for (si = gsi_start_bb (bb); !gsi_end_p (si) || analyze_pattern_stmt;) - { -- tree vf_vectype; -- gimple stmt = gsi_stmt (si), pattern_stmt; -- stmt_info = vinfo_for_stmt (stmt); -+ tree vf_vectype; -+ -+ if (analyze_pattern_stmt) -+ { -+ stmt = pattern_stmt; -+ analyze_pattern_stmt = false; -+ } -+ else -+ stmt = gsi_stmt (si); - -+ stmt_info = vinfo_for_stmt (stmt); -+ - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "==> examining statement: "); -@@ -276,10 +286,17 @@ - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "skip."); -+ gsi_next (&si); - continue; - } - } - -+ else if (STMT_VINFO_IN_PATTERN_P (stmt_info) -+ && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info)) -+ && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) -+ || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) -+ analyze_pattern_stmt = true; -+ - if (gimple_get_lhs (stmt) == NULL_TREE) - { - if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) -@@ -311,9 +328,7 @@ - } - else - { -- gcc_assert (!STMT_VINFO_DATA_REF (stmt_info) -- && !is_pattern_stmt_p (stmt_info)); -- -+ gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)); - scalar_type = TREE_TYPE (gimple_get_lhs (stmt)); - if (vect_print_dump_info (REPORT_DETAILS)) - { -@@ -385,6 +400,9 @@ - if (!vectorization_factor - || (nunits > vectorization_factor)) - vectorization_factor = nunits; -+ -+ if (!analyze_pattern_stmt) -+ gsi_next (&si); - } - } - -@@ -4740,6 +4758,8 @@ - tree cond_expr = NULL_TREE; - gimple_seq cond_expr_stmt_list = NULL; - bool do_peeling_for_loop_bound; -+ gimple stmt, pattern_stmt; -+ bool transform_pattern_stmt = false; - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "=== vec_transform_loop ==="); -@@ -4827,11 +4847,19 @@ - } - } - -- for (si = gsi_start_bb (bb); !gsi_end_p (si);) -+ pattern_stmt = NULL; -+ for (si = gsi_start_bb (bb); !gsi_end_p (si) || transform_pattern_stmt;) - { -- gimple stmt = gsi_stmt (si), pattern_stmt; - bool is_store; - -+ if (transform_pattern_stmt) -+ { -+ stmt = pattern_stmt; -+ transform_pattern_stmt = false; -+ } -+ else -+ stmt = gsi_stmt (si); -+ - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "------>vectorizing statement: "); -@@ -4869,6 +4897,11 @@ - continue; - } - } -+ else if (STMT_VINFO_IN_PATTERN_P (stmt_info) -+ && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info)) -+ && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) -+ || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) -+ transform_pattern_stmt = true; - - gcc_assert (STMT_VINFO_VECTYPE (stmt_info)); - nunits = (unsigned int) TYPE_VECTOR_SUBPARTS ( -@@ -4897,8 +4930,9 @@ - /* Hybrid SLP stmts must be vectorized in addition to SLP. */ - if (!vinfo_for_stmt (stmt) || PURE_SLP_STMT (stmt_info)) - { -- gsi_next (&si); -- continue; -+ if (!transform_pattern_stmt) -+ gsi_next (&si); -+ continue; - } - } - -@@ -4917,7 +4951,7 @@ - the chain. */ - vect_remove_stores (DR_GROUP_FIRST_DR (stmt_info)); - gsi_remove (&si, true); -- continue; -+ continue; - } - else - { -@@ -4927,7 +4961,9 @@ - continue; - } - } -- gsi_next (&si); -+ -+ if (!transform_pattern_stmt) -+ gsi_next (&si); - } /* stmts in BB */ - } /* BBs in loop */ - -Index: gcc-4_6-branch/gcc/tree-vect-patterns.c -=================================================================== ---- gcc-4_6-branch.orig/gcc/tree-vect-patterns.c 2012-01-09 15:02:15.000000000 -0800 -+++ gcc-4_6-branch/gcc/tree-vect-patterns.c 2012-01-09 15:03:29.160918806 -0800 -@@ -39,10 +39,13 @@ - #include "diagnostic-core.h" - - /* Pattern recognition functions */ --static gimple vect_recog_widen_sum_pattern (gimple *, tree *, tree *); --static gimple vect_recog_widen_mult_pattern (gimple *, tree *, tree *); --static gimple vect_recog_dot_prod_pattern (gimple *, tree *, tree *); --static gimple vect_recog_pow_pattern (gimple *, tree *, tree *); -+static gimple vect_recog_widen_sum_pattern (VEC (gimple, heap) **, tree *, -+ tree *); -+static gimple vect_recog_widen_mult_pattern (VEC (gimple, heap) **, tree *, -+ tree *); -+static gimple vect_recog_dot_prod_pattern (VEC (gimple, heap) **, tree *, -+ tree *); -+static gimple vect_recog_pow_pattern (VEC (gimple, heap) **, tree *, tree *); - static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = { - vect_recog_widen_mult_pattern, - vect_recog_widen_sum_pattern, -@@ -142,9 +145,9 @@ - - Input: - -- * LAST_STMT: A stmt from which the pattern search begins. In the example, -- when this function is called with S7, the pattern {S3,S4,S5,S6,S7} will be -- detected. -+ * STMTS: Contains a stmt from which the pattern search begins. In the -+ example, when this function is called with S7, the pattern {S3,S4,S5,S6,S7} -+ will be detected. - - Output: - -@@ -165,12 +168,13 @@ - inner-loop nested in an outer-loop that us being vectorized). */ - - static gimple --vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) -+vect_recog_dot_prod_pattern (VEC (gimple, heap) **stmts, tree *type_in, -+ tree *type_out) - { -- gimple stmt; -+ gimple stmt, last_stmt = VEC_index (gimple, *stmts, 0); - tree oprnd0, oprnd1; - tree oprnd00, oprnd01; -- stmt_vec_info stmt_vinfo = vinfo_for_stmt (*last_stmt); -+ stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); - tree type, half_type; - gimple pattern_stmt; - tree prod_type; -@@ -178,10 +182,10 @@ - struct loop *loop = LOOP_VINFO_LOOP (loop_info); - tree var, rhs; - -- if (!is_gimple_assign (*last_stmt)) -+ if (!is_gimple_assign (last_stmt)) - return NULL; - -- type = gimple_expr_type (*last_stmt); -+ type = gimple_expr_type (last_stmt); - - /* Look for the following pattern - DX = (TYPE1) X; -@@ -207,7 +211,7 @@ - /* Starting from LAST_STMT, follow the defs of its uses in search - of the above pattern. */ - -- if (gimple_assign_rhs_code (*last_stmt) != PLUS_EXPR) -+ if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) - return NULL; - - if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) -@@ -228,12 +232,12 @@ - - if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def) - return NULL; -- oprnd0 = gimple_assign_rhs1 (*last_stmt); -- oprnd1 = gimple_assign_rhs2 (*last_stmt); -+ oprnd0 = gimple_assign_rhs1 (last_stmt); -+ oprnd1 = gimple_assign_rhs2 (last_stmt); - if (!types_compatible_p (TREE_TYPE (oprnd0), type) - || !types_compatible_p (TREE_TYPE (oprnd1), type)) - return NULL; -- stmt = *last_stmt; -+ stmt = last_stmt; - - if (widened_name_p (oprnd0, stmt, &half_type, &def_stmt, true)) - { -@@ -319,11 +323,79 @@ - - /* We don't allow changing the order of the computation in the inner-loop - when doing outer-loop vectorization. */ -- gcc_assert (!nested_in_vect_loop_p (loop, *last_stmt)); -+ gcc_assert (!nested_in_vect_loop_p (loop, last_stmt)); - - return pattern_stmt; - } - -+/* Handle two cases of multiplication by a constant. The first one is when -+ the constant, CONST_OPRND, fits the type (HALF_TYPE) of the second -+ operand (OPRND). In that case, we can peform widen-mult from HALF_TYPE to -+ TYPE. -+ -+ Otherwise, if the type of the result (TYPE) is at least 4 times bigger than -+ HALF_TYPE, and CONST_OPRND fits an intermediate type (2 times smaller than -+ TYPE), we can perform widen-mult from the intermediate type to TYPE and -+ replace a_T = (TYPE) a_t; with a_it - (interm_type) a_t; */ -+ -+static bool -+vect_handle_widen_mult_by_const (tree const_oprnd, tree *oprnd, -+ VEC (gimple, heap) **stmts, tree type, -+ tree *half_type, gimple def_stmt) -+{ -+ tree new_type, new_oprnd, tmp; -+ gimple new_stmt; -+ -+ if (int_fits_type_p (const_oprnd, *half_type)) -+ { -+ /* CONST_OPRND is a constant of HALF_TYPE. */ -+ *oprnd = gimple_assign_rhs1 (def_stmt); -+ return true; -+ } -+ -+ if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4) -+ || !vinfo_for_stmt (def_stmt)) -+ return false; -+ -+ /* TYPE is 4 times bigger than HALF_TYPE, try widen-mult for -+ a type 2 times bigger than HALF_TYPE. */ -+ new_type = build_nonstandard_integer_type (TYPE_PRECISION (type) / 2, -+ TYPE_UNSIGNED (type)); -+ if (!int_fits_type_p (const_oprnd, new_type)) -+ return false; -+ -+ /* Use NEW_TYPE for widen_mult. */ -+ if (STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt))) -+ { -+ new_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); -+ /* Check if the already created pattern stmt is what we need. */ -+ if (!is_gimple_assign (new_stmt) -+ || gimple_assign_rhs_code (new_stmt) != NOP_EXPR -+ || TREE_TYPE (gimple_assign_lhs (new_stmt)) != new_type) -+ return false; -+ -+ *oprnd = gimple_assign_lhs (new_stmt); -+ } -+ else -+ { -+ /* Create a_T = (NEW_TYPE) a_t; */ -+ *oprnd = gimple_assign_rhs1 (def_stmt); -+ tmp = create_tmp_var (new_type, NULL); -+ add_referenced_var (tmp); -+ new_oprnd = make_ssa_name (tmp, NULL); -+ new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, *oprnd, -+ NULL_TREE); -+ SSA_NAME_DEF_STMT (new_oprnd) = new_stmt; -+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt; -+ VEC_safe_push (gimple, heap, *stmts, def_stmt); -+ *oprnd = new_oprnd; -+ } -+ -+ *half_type = new_type; -+ return true; -+} -+ -+ - /* Function vect_recog_widen_mult_pattern - - Try to find the following pattern: -@@ -361,28 +433,47 @@ - S3 a_T = (TYPE) a_t; - S5 prod_T = a_T * CONST; - -- Input: -+ A special case of multiplication by constants is when 'TYPE' is 4 times -+ bigger than 'type', but CONST fits an intermediate type 2 times smaller -+ than 'TYPE'. In that case we create an additional pattern stmt for S3 -+ to create a variable of the intermediate type, and perform widen-mult -+ on the intermediate type as well: -+ -+ type a_t; -+ interm_type a_it; -+ TYPE a_T, prod_T, prod_T'; -+ -+ S1 a_t = ; -+ S3 a_T = (TYPE) a_t; -+ '--> a_it = (interm_type) a_t; -+ S5 prod_T = a_T * CONST; -+ '--> prod_T' = a_it w* CONST; -+ -+ Input/Output: - -- * LAST_STMT: A stmt from which the pattern search begins. In the example, -- when this function is called with S5, the pattern {S3,S4,S5,(S6)} is -- detected. -+ * STMTS: Contains a stmt from which the pattern search begins. In the -+ example, when this function is called with S5, the pattern {S3,S4,S5,(S6)} -+ is detected. In case of unsigned widen-mult, the original stmt (S5) is -+ replaced with S6 in STMTS. In case of multiplication by a constant -+ of an intermediate type (the last case above), STMTS also contains S3 -+ (inserted before S5). - -- Output: -+ Output: - -- * TYPE_IN: The type of the input arguments to the pattern. -+ * TYPE_IN: The type of the input arguments to the pattern. - -- * TYPE_OUT: The type of the output of this pattern. -+ * TYPE_OUT: The type of the output of this pattern. - -- * Return value: A new stmt that will be used to replace the sequence of -- stmts that constitute the pattern. In this case it will be: -- WIDEN_MULT <a_t, b_t> -- */ -+ * Return value: A new stmt that will be used to replace the sequence of -+ stmts that constitute the pattern. In this case it will be: -+ WIDEN_MULT <a_t, b_t> -+*/ - - static gimple --vect_recog_widen_mult_pattern (gimple *last_stmt, -- tree *type_in, -- tree *type_out) -+vect_recog_widen_mult_pattern (VEC (gimple, heap) **stmts, -+ tree *type_in, tree *type_out) - { -+ gimple last_stmt = VEC_pop (gimple, *stmts); - gimple def_stmt0, def_stmt1; - tree oprnd0, oprnd1; - tree type, half_type0, half_type1; -@@ -395,27 +486,27 @@ - VEC (tree, heap) *dummy_vec; - bool op0_ok, op1_ok; - -- if (!is_gimple_assign (*last_stmt)) -+ if (!is_gimple_assign (last_stmt)) - return NULL; - -- type = gimple_expr_type (*last_stmt); -+ type = gimple_expr_type (last_stmt); - - /* Starting from LAST_STMT, follow the defs of its uses in search - of the above pattern. */ - -- if (gimple_assign_rhs_code (*last_stmt) != MULT_EXPR) -+ if (gimple_assign_rhs_code (last_stmt) != MULT_EXPR) - return NULL; - -- oprnd0 = gimple_assign_rhs1 (*last_stmt); -- oprnd1 = gimple_assign_rhs2 (*last_stmt); -+ oprnd0 = gimple_assign_rhs1 (last_stmt); -+ oprnd1 = gimple_assign_rhs2 (last_stmt); - if (!types_compatible_p (TREE_TYPE (oprnd0), type) - || !types_compatible_p (TREE_TYPE (oprnd1), type)) - return NULL; - - /* Check argument 0. */ -- op0_ok = widened_name_p (oprnd0, *last_stmt, &half_type0, &def_stmt0, false); -+ op0_ok = widened_name_p (oprnd0, last_stmt, &half_type0, &def_stmt0, false); - /* Check argument 1. */ -- op1_ok = widened_name_p (oprnd1, *last_stmt, &half_type1, &def_stmt1, false); -+ op1_ok = widened_name_p (oprnd1, last_stmt, &half_type1, &def_stmt1, false); - - /* In case of multiplication by a constant one of the operands may not match - the pattern, but not both. */ -@@ -429,29 +520,21 @@ - } - else if (!op0_ok) - { -- if (CONSTANT_CLASS_P (oprnd0) -- && TREE_CODE (half_type1) == INTEGER_TYPE -- && tree_int_cst_lt (oprnd0, TYPE_MAXVAL (half_type1)) -- && tree_int_cst_lt (TYPE_MINVAL (half_type1), oprnd0)) -- { -- /* OPRND0 is a constant of HALF_TYPE1. */ -- half_type0 = half_type1; -- oprnd1 = gimple_assign_rhs1 (def_stmt1); -- } -+ if (TREE_CODE (oprnd0) == INTEGER_CST -+ && TREE_CODE (half_type1) == INTEGER_TYPE -+ && vect_handle_widen_mult_by_const (oprnd0, &oprnd1, stmts, type, -+ &half_type1, def_stmt1)) -+ half_type0 = half_type1; - else - return NULL; - } - else if (!op1_ok) - { -- if (CONSTANT_CLASS_P (oprnd1) -+ if (TREE_CODE (oprnd1) == INTEGER_CST - && TREE_CODE (half_type0) == INTEGER_TYPE -- && tree_int_cst_lt (oprnd1, TYPE_MAXVAL (half_type0)) -- && tree_int_cst_lt (TYPE_MINVAL (half_type0), oprnd1)) -- { -- /* OPRND1 is a constant of HALF_TYPE0. */ -- half_type1 = half_type0; -- oprnd0 = gimple_assign_rhs1 (def_stmt0); -- } -+ && vect_handle_widen_mult_by_const (oprnd1, &oprnd0, stmts, type, -+ &half_type0, def_stmt0)) -+ half_type1 = half_type0; - else - return NULL; - } -@@ -461,7 +544,7 @@ - Use unsigned TYPE as the type for WIDEN_MULT_EXPR. */ - if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (half_type0)) - { -- tree lhs = gimple_assign_lhs (*last_stmt), use_lhs; -+ tree lhs = gimple_assign_lhs (last_stmt), use_lhs; - imm_use_iterator imm_iter; - use_operand_p use_p; - int nuses = 0; -@@ -491,7 +574,7 @@ - return NULL; - - type = use_type; -- *last_stmt = use_stmt; -+ last_stmt = use_stmt; - } - - if (!types_compatible_p (half_type0, half_type1)) -@@ -506,7 +589,7 @@ - vectype_out = get_vectype_for_scalar_type (type); - if (!vectype - || !vectype_out -- || !supportable_widening_operation (WIDEN_MULT_EXPR, *last_stmt, -+ || !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt, - vectype_out, vectype, - &dummy, &dummy, &dummy_code, - &dummy_code, &dummy_int, &dummy_vec)) -@@ -524,6 +607,7 @@ - if (vect_print_dump_info (REPORT_DETAILS)) - print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM); - -+ VEC_safe_push (gimple, heap, *stmts, last_stmt); - return pattern_stmt; - } - -@@ -555,16 +639,17 @@ - */ - - static gimple --vect_recog_pow_pattern (gimple *last_stmt, tree *type_in, tree *type_out) -+vect_recog_pow_pattern (VEC (gimple, heap) **stmts, tree *type_in, tree *type_out) - { -+ gimple last_stmt = VEC_index (gimple, *stmts, 0); - tree fn, base, exp = NULL; - gimple stmt; - tree var; - -- if (!is_gimple_call (*last_stmt) || gimple_call_lhs (*last_stmt) == NULL) -+ if (!is_gimple_call (last_stmt) || gimple_call_lhs (last_stmt) == NULL) - return NULL; - -- fn = gimple_call_fndecl (*last_stmt); -+ fn = gimple_call_fndecl (last_stmt); - if (fn == NULL_TREE || DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL) - return NULL; - -@@ -574,8 +659,8 @@ - case BUILT_IN_POWI: - case BUILT_IN_POWF: - case BUILT_IN_POW: -- base = gimple_call_arg (*last_stmt, 0); -- exp = gimple_call_arg (*last_stmt, 1); -+ base = gimple_call_arg (last_stmt, 0); -+ exp = gimple_call_arg (last_stmt, 1); - if (TREE_CODE (exp) != REAL_CST - && TREE_CODE (exp) != INTEGER_CST) - return NULL; -@@ -667,21 +752,23 @@ - inner-loop nested in an outer-loop that us being vectorized). */ - - static gimple --vect_recog_widen_sum_pattern (gimple *last_stmt, tree *type_in, tree *type_out) -+vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in, -+ tree *type_out) - { -+ gimple last_stmt = VEC_index (gimple, *stmts, 0); - gimple stmt; - tree oprnd0, oprnd1; -- stmt_vec_info stmt_vinfo = vinfo_for_stmt (*last_stmt); -+ stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); - tree type, half_type; - gimple pattern_stmt; - loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - struct loop *loop = LOOP_VINFO_LOOP (loop_info); - tree var; - -- if (!is_gimple_assign (*last_stmt)) -+ if (!is_gimple_assign (last_stmt)) - return NULL; - -- type = gimple_expr_type (*last_stmt); -+ type = gimple_expr_type (last_stmt); - - /* Look for the following pattern - DX = (TYPE) X; -@@ -693,25 +780,25 @@ - /* Starting from LAST_STMT, follow the defs of its uses in search - of the above pattern. */ - -- if (gimple_assign_rhs_code (*last_stmt) != PLUS_EXPR) -+ if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) - return NULL; - - if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def) - return NULL; - -- oprnd0 = gimple_assign_rhs1 (*last_stmt); -- oprnd1 = gimple_assign_rhs2 (*last_stmt); -+ oprnd0 = gimple_assign_rhs1 (last_stmt); -+ oprnd1 = gimple_assign_rhs2 (last_stmt); - if (!types_compatible_p (TREE_TYPE (oprnd0), type) - || !types_compatible_p (TREE_TYPE (oprnd1), type)) - return NULL; - -- /* So far so good. Since *last_stmt was detected as a (summation) reduction, -+ /* So far so good. Since last_stmt was detected as a (summation) reduction, - we know that oprnd1 is the reduction variable (defined by a loop-header - phi), and oprnd0 is an ssa-name defined by a stmt in the loop body. - Left to check that oprnd0 is defined by a cast from type 'type' to type - 'TYPE'. */ - -- if (!widened_name_p (oprnd0, *last_stmt, &half_type, &stmt, true)) -+ if (!widened_name_p (oprnd0, last_stmt, &half_type, &stmt, true)) - return NULL; - - oprnd0 = gimple_assign_rhs1 (stmt); -@@ -732,8 +819,9 @@ - - /* We don't allow changing the order of the computation in the inner-loop - when doing outer-loop vectorization. */ -- gcc_assert (!nested_in_vect_loop_p (loop, *last_stmt)); -+ gcc_assert (!nested_in_vect_loop_p (loop, last_stmt)); - -+ VEC_safe_push (gimple, heap, *stmts, last_stmt); - return pattern_stmt; - } - -@@ -762,7 +850,7 @@ - - static void - vect_pattern_recog_1 ( -- gimple (* vect_recog_func) (gimple *, tree *, tree *), -+ gimple (* vect_recog_func) (VEC (gimple, heap) **, tree *, tree *), - gimple_stmt_iterator si) - { - gimple stmt = gsi_stmt (si), pattern_stmt; -@@ -774,12 +862,14 @@ - enum tree_code code; - int i; - gimple next; -+ VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1); - -- pattern_stmt = (* vect_recog_func) (&stmt, &type_in, &type_out); -+ VEC_quick_push (gimple, stmts_to_replace, stmt); -+ pattern_stmt = (* vect_recog_func) (&stmts_to_replace, &type_in, &type_out); - if (!pattern_stmt) - return; - -- si = gsi_for_stmt (stmt); -+ stmt = VEC_last (gimple, stmts_to_replace); - stmt_info = vinfo_for_stmt (stmt); - loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); - -@@ -849,6 +939,35 @@ - FOR_EACH_VEC_ELT (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next) - if (next == stmt) - VEC_ordered_remove (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i); -+ -+ /* In case of widen-mult by a constant, it is possible that an additional -+ pattern stmt is created and inserted in STMTS_TO_REPLACE. We create a -+ stmt_info for it, and mark the relevant statements. */ -+ for (i = 0; VEC_iterate (gimple, stmts_to_replace, i, stmt) -+ && (unsigned) i < (VEC_length (gimple, stmts_to_replace) - 1); -+ i++) -+ { -+ stmt_info = vinfo_for_stmt (stmt); -+ pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); -+ if (vect_print_dump_info (REPORT_DETAILS)) -+ { -+ fprintf (vect_dump, "additional pattern stmt: "); -+ print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM); -+ } -+ -+ set_vinfo_for_stmt (pattern_stmt, -+ new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL)); -+ gimple_set_bb (pattern_stmt, gimple_bb (stmt)); -+ pattern_stmt_info = vinfo_for_stmt (pattern_stmt); -+ -+ STMT_VINFO_RELATED_STMT (pattern_stmt_info) = stmt; -+ STMT_VINFO_DEF_TYPE (pattern_stmt_info) -+ = STMT_VINFO_DEF_TYPE (stmt_info); -+ STMT_VINFO_VECTYPE (pattern_stmt_info) = STMT_VINFO_VECTYPE (stmt_info); -+ STMT_VINFO_IN_PATTERN_P (stmt_info) = true; -+ } -+ -+ VEC_free (gimple, heap, stmts_to_replace); - } - - -@@ -896,10 +1015,8 @@ - - If vectorization succeeds, vect_transform_stmt will skip over {S1,S2,S3} - (because they are marked as irrelevant). It will vectorize S6, and record -- a pointer to the new vector stmt VS6 both from S6 (as usual), and also -- from S4. We do that so that when we get to vectorizing stmts that use the -- def of S4 (like S5 that uses a_0), we'll know where to take the relevant -- vector-def from. S4 will be skipped, and S5 will be vectorized as usual: -+ a pointer to the new vector stmt VS6 from S6 (as usual). -+ S4 will be skipped, and S5 will be vectorized as usual: - - in_pattern_p related_stmt vec_stmt - S1: a_i = .... - - - -@@ -915,7 +1032,21 @@ - elsewhere), and we'll end up with: - - VS6: va_new = .... -- VS5: ... = ..vuse(va_new).. */ -+ VS5: ... = ..vuse(va_new).. -+ -+ In case of more than one pattern statements, e.g., widen-mult with -+ intermediate type: -+ -+ S1 a_t = ; -+ S2 a_T = (TYPE) a_t; -+ '--> S3: a_it = (interm_type) a_t; -+ S4 prod_T = a_T * CONST; -+ '--> S5: prod_T' = a_it w* CONST; -+ -+ there may be other users of a_T outside the pattern. In that case S2 will -+ be marked as relevant (as well as S3), and both S2 and S3 will be analyzed -+ and vectorized. The vector stmt VS2 will be recorded in S2, and VS3 will -+ be recorded in S3. */ - - void - vect_pattern_recog (loop_vec_info loop_vinfo) -@@ -925,7 +1056,7 @@ - unsigned int nbbs = loop->num_nodes; - gimple_stmt_iterator si; - unsigned int i, j; -- gimple (* vect_recog_func_ptr) (gimple *, tree *, tree *); -+ gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "=== vect_pattern_recog ==="); -Index: gcc-4_6-branch/gcc/tree-vect-slp.c -=================================================================== ---- gcc-4_6-branch.orig/gcc/tree-vect-slp.c 2012-01-09 15:02:15.000000000 -0800 -+++ gcc-4_6-branch/gcc/tree-vect-slp.c 2012-01-09 15:03:29.160918806 -0800 -@@ -152,7 +152,9 @@ - if (loop && def_stmt && gimple_bb (def_stmt) - && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) - && vinfo_for_stmt (def_stmt) -- && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt))) -+ && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt)) -+ && !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt)) -+ && !STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt))) - { - if (!*first_stmt_dt0) - *pattern0 = true; -Index: gcc-4_6-branch/gcc/tree-vect-stmts.c -=================================================================== ---- gcc-4_6-branch.orig/gcc/tree-vect-stmts.c 2012-01-09 15:02:15.000000000 -0800 -+++ gcc-4_6-branch/gcc/tree-vect-stmts.c 2012-01-09 15:06:23.636927250 -0800 -@@ -126,33 +126,72 @@ - - static void - vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt, -- enum vect_relevant relevant, bool live_p) -+ enum vect_relevant relevant, bool live_p, -+ bool used_in_pattern) - { - stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info); - bool save_live_p = STMT_VINFO_LIVE_P (stmt_info); -+ gimple pattern_stmt; - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p); - -+ /* If this stmt is an original stmt in a pattern, we might need to mark its -+ related pattern stmt instead of the original stmt. However, such stmts -+ may have their own uses that are not in any pattern, in such cases the -+ stmt itself should be marked. */ - if (STMT_VINFO_IN_PATTERN_P (stmt_info)) - { -- gimple pattern_stmt; -+ bool found = false; -+ if (!used_in_pattern) -+ { -+ imm_use_iterator imm_iter; -+ use_operand_p use_p; -+ gimple use_stmt; -+ tree lhs; -+ -+ if (is_gimple_assign (stmt)) -+ lhs = gimple_assign_lhs (stmt); -+ else -+ lhs = gimple_call_lhs (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 (vinfo_for_stmt (use_stmt) -+ && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) -+ { -+ found = true; -+ break; -+ } -+ } -+ } -+ -+ if (!found) -+ { -+ /* This is the last stmt in a sequence that was detected as a -+ pattern that can potentially be vectorized. Don't mark the stmt -+ as relevant/live because it's not going to be vectorized. -+ Instead mark the pattern-stmt that replaces it. */ -+ -+ pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - -- /* This is the last stmt in a sequence that was detected as a -- pattern that can potentially be vectorized. Don't mark the stmt -- as relevant/live because it's not going to be vectorized. -- Instead mark the pattern-stmt that replaces it. */ -- -- pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); -- -- if (vect_print_dump_info (REPORT_DETAILS)) -- fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live."); -- stmt_info = vinfo_for_stmt (pattern_stmt); -- gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); -- save_relevant = STMT_VINFO_RELEVANT (stmt_info); -- save_live_p = STMT_VINFO_LIVE_P (stmt_info); -- stmt = pattern_stmt; -+ if (vect_print_dump_info (REPORT_DETAILS)) -+ fprintf (vect_dump, "last stmt in pattern. don't mark" -+ " relevant/live."); -+ stmt_info = vinfo_for_stmt (pattern_stmt); -+ gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); -+ save_relevant = STMT_VINFO_RELEVANT (stmt_info); -+ save_live_p = STMT_VINFO_LIVE_P (stmt_info); -+ stmt = pattern_stmt; -+ } - } - - STMT_VINFO_LIVE_P (stmt_info) |= live_p; -@@ -437,7 +476,8 @@ - } - } - -- vect_mark_relevant (worklist, def_stmt, relevant, live_p); -+ vect_mark_relevant (worklist, def_stmt, relevant, live_p, -+ is_pattern_stmt_p (stmt_vinfo)); - return true; - } - -@@ -494,7 +534,7 @@ - } - - if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p)) -- vect_mark_relevant (&worklist, phi, relevant, live_p); -+ vect_mark_relevant (&worklist, phi, relevant, live_p, false); - } - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { -@@ -506,7 +546,7 @@ - } - - if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p)) -- vect_mark_relevant (&worklist, stmt, relevant, live_p); -+ vect_mark_relevant (&worklist, stmt, relevant, live_p, false); - } - } - -@@ -613,42 +653,55 @@ - if (is_gimple_assign (stmt)) - { - tree rhs = gimple_assign_rhs1 (stmt); -- if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) -- == GIMPLE_SINGLE_RHS) -+ unsigned int op_num; -+ tree op; -+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))) - { -- unsigned int op_num = TREE_OPERAND_LENGTH (gimple_assign_rhs1 -- (stmt)); -- for (i = 0; i < op_num; i++) -- { -- tree op = TREE_OPERAND (rhs, i); -- if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -- &worklist)) -+ case GIMPLE_SINGLE_RHS: -+ op_num = TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)); -+ for (i = 0; i < op_num; i++) - { -- VEC_free (gimple, heap, worklist); -- return false; -+ op = TREE_OPERAND (rhs, i); -+ if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -+ &worklist)) -+ { -+ VEC_free (gimple, heap, worklist); -+ return false; -+ } - } -- } -- } -- else if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) -- == GIMPLE_BINARY_RHS) -- { -- tree op = gimple_assign_rhs1 (stmt); -- if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -- &worklist)) -- { -- VEC_free (gimple, heap, worklist); -- return false; -- } -- op = gimple_assign_rhs2 (stmt); -- if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -- &worklist)) -- { -- VEC_free (gimple, heap, worklist); -- return false; -- } -+ break; -+ -+ case GIMPLE_BINARY_RHS: -+ op = gimple_assign_rhs1 (stmt); -+ if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -+ &worklist)) -+ { -+ VEC_free (gimple, heap, worklist); -+ return false; -+ } -+ op = gimple_assign_rhs2 (stmt); -+ if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -+ &worklist)) -+ { -+ VEC_free (gimple, heap, worklist); -+ return false; -+ } -+ break; -+ -+ case GIMPLE_UNARY_RHS: -+ op = gimple_assign_rhs1 (stmt); -+ if (!process_use (stmt, op, loop_vinfo, live_p, relevant, -+ &worklist)) -+ { -+ VEC_free (gimple, heap, worklist); -+ return false; -+ } -+ -+ break; -+ -+ default: -+ return false; - } -- else -- return false; - } - else if (is_gimple_call (stmt)) - { -@@ -1210,7 +1263,14 @@ - - /* Get the def from the vectorized stmt. */ - def_stmt_info = vinfo_for_stmt (def_stmt); -+ - vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info); -+ /* Get vectorized pattern statement. */ -+ if (!vec_stmt -+ && STMT_VINFO_IN_PATTERN_P (def_stmt_info) -+ && !STMT_VINFO_RELEVANT (def_stmt_info)) -+ vec_stmt = STMT_VINFO_VEC_STMT (vinfo_for_stmt ( -+ STMT_VINFO_RELATED_STMT (def_stmt_info))); - gcc_assert (vec_stmt); - if (gimple_code (vec_stmt) == GIMPLE_PHI) - vec_oprnd = PHI_RESULT (vec_stmt); -@@ -4894,6 +4954,7 @@ - enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info); - bool ok; - tree scalar_type, vectype; -+ gimple pattern_stmt; - - if (vect_print_dump_info (REPORT_DETAILS)) - { -@@ -4915,16 +4976,22 @@ - - any LABEL_EXPRs in the loop - - computations that are used only for array indexing or loop control. - In basic blocks we only analyze statements that are a part of some SLP -- instance, therefore, all the statements are relevant. */ -+ instance, therefore, all the statements are relevant. -+ -+ Pattern statement need to be analyzed instead of the original statement -+ if the original statement is not relevant. Otherwise, we analyze both -+ statements. */ - -+ pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - if (!STMT_VINFO_RELEVANT_P (stmt_info) - && !STMT_VINFO_LIVE_P (stmt_info)) - { -- gimple pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - if (STMT_VINFO_IN_PATTERN_P (stmt_info) -+ && pattern_stmt - && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) - || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) - { -+ /* Analyze PATTERN_STMT instead of the original stmt. */ - stmt = pattern_stmt; - stmt_info = vinfo_for_stmt (pattern_stmt); - if (vect_print_dump_info (REPORT_DETAILS)) -@@ -4941,6 +5008,21 @@ - return true; - } - } -+ else if (STMT_VINFO_IN_PATTERN_P (stmt_info) -+ && pattern_stmt -+ && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) -+ || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) -+ { -+ /* Analyze PATTERN_STMT too. */ -+ if (vect_print_dump_info (REPORT_DETAILS)) -+ { -+ fprintf (vect_dump, "==> examining pattern statement: "); -+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); -+ } -+ -+ if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node)) -+ return false; -+ } - - switch (STMT_VINFO_DEF_TYPE (stmt_info)) - { -@@ -5074,7 +5156,6 @@ - bool is_store = false; - gimple vec_stmt = NULL; - stmt_vec_info stmt_info = vinfo_for_stmt (stmt); -- gimple orig_stmt_in_pattern; - bool done; - - switch (STMT_VINFO_TYPE (stmt_info)) -@@ -5213,21 +5294,7 @@ - } - - if (vec_stmt) -- { - STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt; -- orig_stmt_in_pattern = STMT_VINFO_RELATED_STMT (stmt_info); -- if (orig_stmt_in_pattern) -- { -- stmt_vec_info stmt_vinfo = vinfo_for_stmt (orig_stmt_in_pattern); -- /* STMT was inserted by the vectorizer to replace a computation idiom. -- ORIG_STMT_IN_PATTERN is a stmt in the original sequence that -- computed this idiom. We need to record a pointer to VEC_STMT in -- the stmt_info of ORIG_STMT_IN_PATTERN. See more details in the -- documentation of vect_pattern_recog. */ -- if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) -- STMT_VINFO_VEC_STMT (stmt_vinfo) = vec_stmt; -- } -- } - - return is_store; - } -@@ -5605,8 +5672,12 @@ - || *dt == vect_nested_cycle) - { - stmt_vec_info stmt_info = vinfo_for_stmt (*def_stmt); -- if (STMT_VINFO_IN_PATTERN_P (stmt_info)) -+ -+ if (STMT_VINFO_IN_PATTERN_P (stmt_info) -+ && !STMT_VINFO_RELEVANT (stmt_info) -+ && !STMT_VINFO_LIVE_P (stmt_info)) - stmt_info = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); -+ - *vectype = STMT_VINFO_VECTYPE (stmt_info); - gcc_assert (*vectype != NULL_TREE); - } -Index: gcc-4_6-branch/gcc/tree-vectorizer.h -=================================================================== ---- gcc-4_6-branch.orig/gcc/tree-vectorizer.h 2012-01-09 15:02:15.000000000 -0800 -+++ gcc-4_6-branch/gcc/tree-vectorizer.h 2012-01-09 15:03:29.164918806 -0800 -@@ -890,7 +890,7 @@ - /* Pattern recognition functions. - Additional pattern recognition functions can (and will) be added - in the future. */ --typedef gimple (* vect_recog_func_ptr) (gimple *, tree *, tree *); -+typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); - #define NUM_PATTERNS 4 - void vect_pattern_recog (loop_vec_info); - |