When a G_BRCOND is fed by an eq or ne G_ICMP, it may be possible to fold a G_AND into the branch by producing a tbnz/tbz instead.
This happens when
- We have a ne/eq G_ICMP feeding into the G_BRCOND
- The G_ICMP is a comparison against 0
- One of the operands of the G_AND is a power of 2 constant
This is very similar to the code in AArch64TargetLowering::LowerBR_CC.
Add opt-and-tbnz-tbz to test this.
(I think that we can probably factor out all the CB(N)Z into a function like this, but I want to finish implementing the other parts of AArch64TargetLowering::LowerBR_CC first.)
Nit: when you take the log2 of the mask value, it's no longer a mask but more of a bit position. So this should be named something like Bit or TestedBit etc. It'll help make things clearer when we come to folding in more things like shifts (which I assume is going to be done between here and the branch construction below).