This removes the use of the bogus number_of_exit_cond_executions function from loop-distribution.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2013-11-21 Richard Biener <rguent...@suse.de> PR tree-optimization/59058 * tree-loop-distribution.c (struct partition_s): Add plus_one member. (build_size_arg_loc): Apply niter adjustment here. (generate_memset_builtin): Adjust. (generate_memcpy_builtin): Likewise. (classify_partition): Do not use number_of_exit_cond_executions but record whether niter needs to be adjusted. Index: gcc/tree-loop-distribution.c =================================================================== *** gcc/tree-loop-distribution.c (revision 205118) --- gcc/tree-loop-distribution.c (working copy) *************** typedef struct partition_s *** 480,485 **** --- 480,486 ---- data_reference_p main_dr; data_reference_p secondary_dr; tree niter; + bool plus_one; } *partition_t; *************** generate_loops_for_partition (struct loo *** 703,715 **** /* Build the size argument for a memory operation call. */ static tree ! build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter) { ! tree size; ! size = fold_build2_loc (loc, MULT_EXPR, sizetype, ! fold_convert_loc (loc, sizetype, nb_iter), TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)))); ! return fold_convert_loc (loc, size_type_node, size); } /* Build an address argument for a memory operation call. */ --- 704,719 ---- /* Build the size argument for a memory operation call. */ static tree ! build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter, ! bool plus_one) { ! tree size = fold_convert_loc (loc, sizetype, nb_iter); ! if (plus_one) ! size = size_binop (PLUS_EXPR, size, size_one_node); ! size = fold_build2_loc (loc, MULT_EXPR, sizetype, size, TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)))); ! size = fold_convert_loc (loc, size_type_node, size); ! return size; } /* Build an address argument for a memory operation call. */ *************** generate_memset_builtin (struct loop *lo *** 781,787 **** /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); ! nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); mem = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); --- 785,792 ---- /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); ! nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter, ! partition->plus_one); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); mem = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); *************** generate_memcpy_builtin (struct loop *lo *** 837,843 **** /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); ! nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); dest = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); --- 842,849 ---- /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); ! nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter, ! partition->plus_one); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); dest = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); *************** classify_partition (loop_p loop, struct *** 980,990 **** --- 986,998 ---- tree nb_iter; data_reference_p single_load, single_store; bool volatiles_p = false; + bool plus_one = false; partition->kind = PKIND_NORMAL; partition->main_dr = NULL; partition->secondary_dr = NULL; partition->niter = NULL_TREE; + partition->plus_one = false; EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi) { *************** classify_partition (loop_p loop, struct *** 1047,1059 **** if (!single_store) return; ! if (!dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src, ! gimple_bb (DR_STMT (single_store)))) ! nb_iter = number_of_latch_executions (loop); ! else ! nb_iter = number_of_exit_cond_executions (loop); if (!nb_iter || nb_iter == chrec_dont_know) return; if (single_store && !single_load) { --- 1055,1066 ---- if (!single_store) return; ! nb_iter = number_of_latch_executions (loop); if (!nb_iter || nb_iter == chrec_dont_know) return; + if (dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src, + gimple_bb (DR_STMT (single_store)))) + plus_one = true; if (single_store && !single_load) { *************** classify_partition (loop_p loop, struct *** 1075,1080 **** --- 1082,1088 ---- partition->kind = PKIND_MEMSET; partition->main_dr = single_store; partition->niter = nb_iter; + partition->plus_one = plus_one; } else if (single_store && single_load) { *************** classify_partition (loop_p loop, struct *** 1132,1137 **** --- 1140,1146 ---- partition->main_dr = single_store; partition->secondary_dr = single_load; partition->niter = nb_iter; + partition->plus_one = plus_one; } }