Optimize the if statement style such as in the floor function
This is a very common pattern:
elemental integer(i32) function dfloor_i32(x) result(r)
real(dp), intent(in) :: x
if (x >= 0) then
r = x
else
r = x-1
end if
end function
The if statement can be replaced with:
r = x - (1-sign(x))/2
Where the expression (1-sign(x))/2 is equal to 0 for x>0 and to 1 for x<0 (the x=0 case must also be handled, I am skipping it here). This can be obtained from the sign bit, so I think (1-sign(x))/2 = (x >> 63), so the above if statement can be replaced by just:
r = x - (x >> 63)
The x in x >> 63 might be needed to cast to integer first, and then back to float to subtract.
This is a general approach, that should work for cases like:
if (x >= 0) then
r = x
else
r = x-10
end if
where r is a real number (r = x - 10*(x >> 63)).
In the case above, it is also cast to integer (r is an integer) and I think there might be LLVM or assembly instructions for that directly, so the optimizer should also recognize the above special case as a floor operation and just replace it with a floor intrinsic function, just like we do with fma or flip_sign (all these the user can't enter directly, they are inserted by the optimizer).