https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119103
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
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.
With --param lim-expensive=1 and the following patch it works (not sure
if we can really just take the max-shift, but I think so - we should
possibly check the min to be ges_p zero).
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 4f0a7ea162b..38256039c04 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -6544,10 +6544,17 @@ vect_determine_precisions_from_users (stmt_vec_info
stmt_info, gassign *stmt)
case RSHIFT_EXPR:
{
tree shift = gimple_assign_rhs2 (stmt);
- if (TREE_CODE (shift) != INTEGER_CST
- || !wi::ltu_p (wi::to_widest (shift), precision))
+ unsigned int const_shift;
+ wide_int min_shift, max_shift;
+ if (TREE_CODE (shift) == SSA_NAME
+ && vect_get_range_info (shift, &min_shift, &max_shift)
+ && wi::ltu_p (max_shift, TYPE_PRECISION (type)))
+ const_shift = max_shift.to_uhwi ();
+ else if (TREE_CODE (shift) == INTEGER_CST
+ && wi::ltu_p (wi::to_widest (shift), precision))
+ const_shift = TREE_INT_CST_LOW (shift);
+ else
return;
- unsigned int const_shift = TREE_INT_CST_LOW (shift);
if (code == LSHIFT_EXPR)
{
/* Avoid creating an undefined shift.