Starting work at splitting out float cases from float complex optimizations

Currently float complex optimizations work on floats and assume that the imaginary part is 0.0, this is incorrect as it is actually 0. This leads to optimizer bugs. These changes push where we do this to the edge of the float-complex optizations to make it easier for later changes to fix them.