https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98849
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- For #c2 I've tried: --- gcc/tree-vect-generic.c.jj 2021-01-04 10:25:38.289239984 +0100 +++ gcc/tree-vect-generic.c 2021-01-27 13:53:28.457752505 +0100 @@ -2147,16 +2147,21 @@ expand_vector_operations_1 (gimple_stmt_ || code == LROTATE_EXPR || code == RROTATE_EXPR) { - optab opv; + optab opv = optab_for_tree_code (code, type, optab_vector); /* Check whether we have vector <op> {x,x,x,x} where x could be a scalar variable or a constant. Transform - vector <op> {x,x,x,x} ==> vector <op> scalar. */ + vector <op> {x,x,x,x} ==> vector <op> scalar, unless + the backend only supports vector <op> by vector and not + vecot <op> by scalar. */ if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2))) { tree first; - if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE) + op = optab_for_tree_code (code, type, optab_scalar); + if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE + && (get_compute_type (code, opv, type) != type + || get_compute_type (code, op, type) == type)) { gimple_assign_set_rhs2 (stmt, first); update_stmt (stmt); @@ -2164,7 +2169,6 @@ expand_vector_operations_1 (gimple_stmt_ } } - opv = optab_for_tree_code (code, type, optab_vector); if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2))) op = opv; else but that doesn't really help, because while veclower21 doesn't undo what the vectorizer carefully did, match.pd during fre5 breaks it again: /* Prefer vector1 << scalar to vector1 << vector2 if vector2 is uniform. */ (for vec (VECTOR_CST CONSTRUCTOR) (simplify (shiftrotate @0 vec@1) (with { tree tem = uniform_vector_p (@1); } (if (tem) (shiftrotate @0 { tem; })))))) So, does ARM really only have vector shifts and not scalar? Though, PowerPC seems to have that too, I'll check out what it does on these testcases.