As an example optimization, consider this C code:
do {
if (*--p == '.') *p = '_';
} while (p != name);
LLVM originally produced this bitcode for AVX-2 instructions: %1 = shufflevector %0, <31, 30, 29, ... , 0>
%2 = icmp eq %1, <46, 46, 46, ... , 46>
%3 = shufflevector %2, <31, 30, 29, ... , 0>
Minotaur instead produced: %1 = icmp eq %0, <46, 46, 46, ... , 46>
Both compare the register to ASCII 46 ('.'), but LLVM originally produced an unnecessary pair of vector reversals. Minotaur removed it.Super-optimizers always strike me with the same feeling when seeing examples like this. On the one hand, it's awesome to be able to have truly-optimal (under chosen assumptions) code sequences for certain operations. On the other hand, so many of the examples just hammer home how many missed practical opportunities there are for peephole optimizations (in this case) and other traditional, local optimization techniques. I almost feel like the most valuable use of a super-optimizer would be to run it against a bunch of real world code patterns, and then use the optimization results to feed back in to simple traditional optimizations.
> Souper is a superoptimizer for LLVM IR. It uses an SMT solver to help identify missing peephole optimizations in LLVM's midend optimizers.