Why isn't this VHDL falling edge detector reliable?
"signal_in" is not timed by the development tools until it is brought into a clocked element (i.e. register). Because of this there is nothing that says "not signal_in" has to be valid before/after "last" is updated. 

Therefore, when "last" and "not signal_in" are ANDed together there is essentially a race condition, where the final result can vary (between builds due to routing and between FPGAs due to variations in the specific fabric). This is why signals should always be brought onto a clock before being used in calculations.