Extend LoopVectorize's SelectCmp pattern for non-invariant statements,
and get LoopUtils' createCmpSelectTargetReduction to CodeGen for this
case. Consider the following example:
int src[n] = {4, 5, 2}; int r = 331; for (int i = 0; i < n; i++) { if (src[i] > 3) r = i; } return r;
Here, r = i is non-invariant, and CodeGen'ing for this case involves the
following:
- Create a Splat with the int_min/int_max values, depending on the loop direction.
- The Src is filled with values: {0, 1, 2, 3, 4, ...}.
- The Right is filled with values: {0, 1, 331, 331, 331, ...}.
- The CmpVector is filled with values: {1, 1, 0, 0, 0, ...}.
- Select using this CmpVector between Src and the Splat with int_min/int_max values.
- Use a max-reduce/min-reduce on the result of the Select.
- Use the exising Cmp which determines whether or not any assignment took place in the loop to select between the result of the max-reduce/min-reduce, and the initial value (InitVal).
Hence, the above case is vectorized.
For the following case, the final value might not be able to pick by the min/max reduction.
Extra checking of NonPhi might be needed. So the reduction can generate min/max.
Would it need to check AR->hasNoUnsignedWrap?