https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119103
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #7) > So first of all the range info on the shift is lost, so > vect_recog_over_widening_pattern cannot do its work. The info is lost when > PRE moves the invariant (int) amount cast out of the loop - we've dropped > the unreachable() at that point, so we can't recover the lost info then. PRE has no good way to preserve the info, it would need to get ranges (and points-to info) attached to its expression representation. LIMs cost modeling is off here (given PRE will do all hoisting anyway). _6 = (int) amount_11(D); invariant up to level 1, cost 1. and we only hoist when cost is at least 20 (we accumulate this for a series of invariant stmts). We could do diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc index 225964c6215..5bc2898d5f4 100644 --- a/gcc/tree-ssa-loop-im.cc +++ b/gcc/tree-ssa-loop-im.cc @@ -687,6 +687,12 @@ stmt_cost (gimple *stmt) /* Comparisons are usually expensive. */ if (TREE_CODE_CLASS (code) == tcc_comparison) return LIM_EXPENSIVE; + /* Hoist all stmts with range info here if PRE would do so later + anyway. */ + if (flag_tree_pre + && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))) + && SSA_NAME_RANGE_INFO (gimple_assign_lhs (stmt))) + return LIM_EXPENSIVE; return 1; } } or alternatively diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc index 225964c6215..9d27afedc33 100644 --- a/gcc/tree-ssa-loop-im.cc +++ b/gcc/tree-ssa-loop-im.cc @@ -264,7 +264,7 @@ static bool ref_always_accessed_p (class loop *, im_mem_ref *, bool); static bool refs_independent_p (im_mem_ref *, im_mem_ref *, bool = true); /* Minimum cost of an expensive expression. */ -#define LIM_EXPENSIVE ((unsigned) param_lim_expensive) +#define LIM_EXPENSIVE (flag_tree_pre ? 1u : (unsigned) param_lim_expensive) /* The outermost loop for which execution of the header guarantees that the block will be executed. */