LLVM's auto-vectorizer sometimes generates silly reverse loops, where a value is reversed by a shuffle, followed by some arithmetic, and then get reversed back.
For example, LLVM compiles this code sequence:
do { if (*--p == '.') *p = '_'; } while (p != name);
into
%1 = shufflevector <32 x i8> %0, poison, <31, 30, 29, 28, 27, ... 4, 3, 2, 1, 0> %2 = icmp eq <32 x i8> %1, <46, 46, 46, 46, 46, ... 46, 46, 46, 46, 46> %3 = shufflevector <32 x i1> %2, poison, <31, 30, 29, 28, 27, ... 4, 3, 2, 1, 0>
Obviously reverse shuffle %1 and %3 are redundant, and the sequence can be optimized into
%1 = icmp eq <32 x i8> %0, <46, 46, 46, 46, 46, ... 46, 46, 46, 46, 46>
This sequence is found in gzip's make_simple_name function.
This patch implements this rule in VectorCombine. Currently it works when %2 is a cmp instruction comparing with an splat constant. I will add other cases if this patch is approved.
The test cases in this patch are validated with Alive2.
This rewrite pattern is found by the Minotaur superoptimizer (https://github.com/minotaur-toolkit/minotaur).
Why does this need to be a splat? If its constant we can just constant fold with the outer shuffle