foldSelectICmpAndOr handled turning (select (icmp eq (and X, C1), 0), Y, (or Y, C2)) into (or (shl (and X, C1), C3), Y)
But there was no reason reason the binary operator we're folding should be limited to Or. It should also work for xor, add, sub, etc.
Conceptually the code was a combination of foldSelectICmpAnd which takes care of turning bit test compares used to select constants into logic. And foldSelectIntoOp which tries to create a select on the input to a binary operator but stops if it would create a select of constants that isn't selecting between 0 and 1/-1.
So this patch teaches foldSelectIntoOp that if it would create a select of constants, but the condition is a bit test we can still handle it.
I've disable this if the binop is a shift because that seemed a little weirder.
I've added test for xor here but I can add more for other operators.
This also broke all the one use protections that existed in foldSelectICmpAndOr. This patch is already pretty large. So I can either fix them in foldSelectICmpAnd ahead of this or do it after this.
I can split up some of the refactorings and function reorderings out if we want.