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).

Edited by Ondřej Čertík