Benjamin fixed an issue with the r+r -> r+i transform where we materialized an incorrect constant using ANDIo - thanks Ben.
However the fix is very conservative. It will only do the transform if AND-ing the input with the new constant produces the same new constant. This is of course correct, but not necessarily required.
- If the input constant isn't used by any other instructions, the immediate can be changed to the new constant. Even if the new constant would end up producing a negative value for the defining load-immediate, this isn't a problem because the only user will be the ANDIo
- If the GPR output from the instruction being replaced isn't used, it isn't relevant what constant is materialized in the GPR (as long as a zero is correctly identified). So the immediate operand of the ANDIo can just be zero or whatever the immediate operand is to the defining load-immediate.
- If neither of the above apply (or we don't know about uses due to being in the late peephole), we only transform if all bits of the new immediate are also set in the input constant (as Ben's fix currently ensures).
Examples:
Case 1:
li 3, 1 rlwinm. 4, 3, 2, 0, 31 # use CR0 and possibly GPR4 but not GPR3 ### Transforms to: li 3, 4 andi. 4, 3, 4
Case 2 (non-zero):
li 3, 1 rlwinm. 4, 3, 2, 0, 31 # Use CR0 and possibly GPR3, but not GPR4 li 3, 1 andi. 4, 3, 1
Case 2 (zero):
li 3, 1 rlwinm. 4, 3, 20, 21, 31 # Use CR0 and possibly GPR3, but not GPR4 li 3, 1 andi. 4, 3, 0