There is an opportunity in instCombine for following instruction pattern:
%mul = mul nsw i32 %b, %a %cmp = icmp sgt i32 %mul, -1 %sub = sub i32 0, %a %mul2 = mul nsw i32 %sub, %b %cond = select i1 %cmp, i32 %mul, i32 %mul2
Source code for above pattern:
return (a*b) >=0 ? (a*b) : -a*b;
Currently, llvm(-O3) can not recognize this as abs(a*b).
Got help from @spatel in llvm-dev:
"
it looks like we are missing an IR canonicalization for 'mul' like this:
https://rise4fun.com/Alive/ARs
%neg = sub i8 0, %x %r = mul i8 %neg, %y
-->
%mul2 = mul i8 %x, %y %r = sub i8 0, %mul2
"
Testcases are already add in https://reviews.llvm.org/rL349847.
Thanks @jsji, i have updated the testcases according to his comment to the above nfc patch.
That || looks confusing. Maybe just keep that as two lines?