gcc generates less instructions than llvm from below example.
float foo(int state) { return (float)state / 2; }
gcc output
foo: scvtf s0, w0, #1 ret
llvm output
foo: scvtf s0, w0 fmov s1, #0.50000000 fmul s0, s0, s1 ret
gcc converts the float division to float multiplication like X / C --> X * (1 / C), and it has a pattern aarch64_scvtfsisf2_mult with float multiplication for scvtf.
llvm also converts fdiv to fmul in InstCombine pass like X / C --> X * (1 / C) but it does not have ISel codes with fmul for scvtf.
If fmul's constant operand is the reciprocal of a power of 2 like (1/2^n) and the other operand is SINT_TO_FP, we can try X * (1 / C) --> X / C because it will be matched with scvtf patterns with fixed-point.
With this patch, the llvm's output is as below.
foo: scvtf s0, w0, #1 ret
Could this be shared with SelectCVTFixedPosOperand? Maybe with a flag to specify whether the getExactInverse needs to be performed. If not them maybe the ConstantFPSDNode/ConstantPoolSDNode stuff can be pulled out and shared?