We currently have two ways of informing the optimizer that the result of a load is never null: metadata and assume. This change converts the second in to the former. This avoids a need to implement optimizations using both forms.
We should probably extend this basic idea to metadata of other forms; in particular, range metadata. We view is that assumes should be considered a "last resort" for when there isn't a more canonical way to represent something.
It makes me so sad, but this is not correct :(
addr = load
function_that_might_throw()
assume(addr != null)
This has a control dependency on the potentially-throwing function. (Technically, this applies to any function because calling longjmp has the same effect, but LICM only checks mayThrow(), and I see no reason to be more strict anywhere else).
A second, less sad reason why this is not correct is that you need to check the parent of the assume, not the icmp, because they might be in different blocks (and often are after LICM).
In any case, dealing with this "for real" is actually easy: just call