Isn't abs(INT_MIN) undefined?
expensive div is removed:
_Z4fooai: # @_Z4fooai mov eax, edi mov ecx, edi neg ecx cmovl ecx, edi cdq idiv ecx ret _Z5fooari: # @_Z5fooari mov eax, edi sar eax, 31 or eax, 1 ret
GCC knows this trick too.
Taking this even farther. Can't we do
X / (select C, A, X) -> select C, X / A, 1
I assume if A happens to be X or -X it would continue folding on its own when the new nodes are processed in the worklist
Seems like we should maybe teach InstCombiner::FoldOpIntoSelect to handle cases where one of the select operands becomes a constant if we fold. But we might only call FoldOpIntoSelect when one of the operands of the binop is a constant today.
I think we also miss
x + (c ? -x : y) -> c ? 0 : x + y
x - (c ? x : y) -> c ? 0 : x - y
Also does InstSimplify know X / -X -> -1 when the neg has NSW?