WRONG: Missing strength reduction for `rem 2`
Please disregard, that is actually wrong for signed integers. I mixed up remainder and modulus - the current implementation correctly returns negative remainders for negative dividends and positive divisors.
Motivation
I saw a tweet referring to this blog post on how Clang/LLVM can optimize a silly "isEven" implementation. Another user posted a screenshot showing that rustc can compile this down to 3 instructions.
GHC can't seem to do that, but I was more surprised that it emits the full division etc code for the straight forward "isEven" implementation: isEven n = n
rem2 == 0
.
It emits shifts and adds and subs etc, even though you'd only need to test the least significant bit.
Here is the example with emitted assembly: https://gcc.godbolt.org/z/7MnrMhfrf
Proposal
Add a special case to GHC/Cmm/Opt.hs for MO_S_Rem with divisor being exactly 2.