Description
We use metadata attached to LLVM instructions to tell LLVM passes about the range of possible integers that a value can take on. This allows additional optimizations. For example, when loading from a &NonZeroU32
, the LLVM IR looks like this:
%2 = load i32, i32* %1, align 4, !range !33
where !33
refers to a module-level entry like this (usually located near the end of the module source code):
!33 = !{i32 1, i32 0}
This tells LLVM that it's UB if the load returns anything that is not in the range ">= 1, < 0" (with wrap-around, i.e. it includes all values except 0). This allows x.get() != 0
(where x: &NonZeroU32
) to be optimized to true
, for example.
Unfortunately LLVM does not have a way to attach this information to function arguments, which leads to missed optimizations (e.g. #49572, #49420 (comment)). Adding this capability has been discussed before on llvm-dev and received positively, but was never actually implemented. If we want to use this in Rust, we're likely going to have to implement (& upstream) it outselves.
This issue tracks:
- Implementing metadata-on-arguments in LLVM (mentoring instructions)
- Upstreaming / backporting that LLVM patch
- Emitting range metadata on arguments from rustc