Not sure which way to go here - a 'not' is considered a less complex op than arbitrary xor/add, and 'not' might be better for value tracking and subsequent instcombines. But the adds are reassociable/commutable.
This might warrant a DAGCombiner patch to avoid regressions before we make the IR decision.
x86 scalar looks better with add+inc:
movl %edi, %eax notl %esi subl %esi, %eax
leal 1(%rsi,%rdi), %eax
But AArch64 and PowerPC64LE appear to benefit from the 'not' with vector code:
mvn v1.16b, v1.16b sub v0.4s, v0.4s, v1.4s
add v0.4s, v1.4s, v0.4s movi v1.4s, #1 add v0.4s, v0.4s, v1.4s
xxlnor 35, 35, 35 vsubuwm 2, 2, 3
vspltisw 4, 1 vadduwm 2, 3, 2 vadduwm 2, 2, 4
If we do go in this direction, do we want to increment 1st to reduce the burden on -reassociation? Assuming it will do:
(x + y) + 1 --> (x + 1) + y
...we might as well produce that directly?
cc'ing Eli in case he sees any other motivations to consider.
Yes, we should probably teach DAGCombine to choose the right form for each target/type.
It seems reasonable to prefer x+(y+1) over x-(-1-y), for reassociation etc. It's possible there could be some bad interaction at the interface between logical and arithmetic operations, which makes us miss some important optimization, but that doesn't seem likely to me.
Great, thank you for the feedback!
I will look into backend stuff; if there are no other concerns here please feel free to accept,
i'm not going to land until after the backend stuff is done.