https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65947
--- Comment #3 from alalaw01 at gcc dot gnu.org --- Yeah, you're right, it's not commutative, but then, it doesn't need to be. If f(x,y) is "(a[x] ? 7 : y)", then f(0, f(1, ...)) = f(1, f(0, ...)) (associative but not commutative), which is all we need to reorder the iterations of the loop? So if at the end of the loop we have a vector v_tmp_result = { f(8, f(4, f(0, <init>))), f(9, f(5, f(1, <init>))), f(10, f(6, f(2, <init>))), f(11, f(7, f(3, <init>))) } obtained by standard technique for reductions, we then need to reduce the vector to a scalar, which could be (a) if any of the vector elements are equal to the constant 7, then return the constant 7, else the initial value: cond_expr (vec_reduc_or (vec_equals (v_tmp_result, 7)), 7, <init>) indeed you might just vectorize to get the predicates v_tmp2 = { a[8] | a[4] | a[0], a[9] | a[5] | a[1], a[10] | a[6] | a[2], a[11] | a[7] | a[3] } and then reduce to scalar with cond_expr (vec_reduc_or (v_tmp2), 7, 3) (b) alternatively one could exploit the initial value (3) also being a constant and choose an appropriate operator from {max, min, or, and}, e.g. for 3 and 7 either reduc_max_expr(3,7) or reduc_or_expr(3,7) would work.