This patch introduces a new module-level pass which does a top-down traversal of the call graph, inferring when possible for local functions, parameter attributes: noalias, dereferenceable and nonnull. It does this based on an examination of all call sites.
Inference on nonnull is straightforward (all callers must pass an argument we know is nonnull). noalias requires two things at all call sites: that the parameter not alias with any other parameter, and that it not have been captured prior to the call site. dereferenceability requires that we know the pointer is derefenceable at all call sites, obviously, but then we also need to get the size. We use the type size (which is fine b/c we've already verified that a load of that type is safe), but we also use getObjectSize to see if we can do better. We don't always know that the size that getObjectSize returns is valid (because the malloc could have failed, for example), but it will be valid if there is also an access, and isSafeToLoadUnconditionally checks for that.
There is a quirk about scheduling this in the current pass manager: Inference of noalias requires a capturing analysis which greatly benefits from running after the existing FunctionAttrs pass which will infer nocapture parameters. However, the existing FunctionAttrs pass is a CGSCC pass that runs in the main CGSCC pass manager after the inliner. But this being a top-down traversal of the call graph (and thus a module pass), and one that should run early, needs to run before the inliner's CGSCC pass manager. As a result, I think the best option is to insert an extra run of the regular FunctionAttrs pass just prior to this one, and these just prior to the main CGSCC pass manager. Since both preserve the call graph, it should not cause it to be recomputed.
I see no compile-time impact (either from the extra run on functionattrs or from this new pass). Compiling sqlite, for example, both passes take less than 0.1% of the total time.
Stylistically, I'd prefer this separated into two checks. Your combining correctness and profitability criteria. Also, rather than "return MadeChange", just "return false" for the early exits. It makes the flow clearer.