Yes please! Rust would use this all over the place because Option
and Result
have exactly the “we want an i1
for select but have to load/store it as i8
to meet other rules” problem. Making it obvious in the instruction stream — without depending on optimizations looking deeply enough to find !range
on a load or soon parameter attributes — would I hope have it be much simpler for common 2-variant enum patterns to optimize well.
One thing the proposal might want to address directly:
It has seemed to me like opt today prefers to change trunc i8 %x to i1
to something involving icmp ne i8 %x, 0
https://llvm.godbolt.org/z/WKPTev64T – even if there’s !range
metadata that the value is already in [0, 2)
https://llvm.godbolt.org/z/3P3E6vc8P.
Once we have nowrap truncation, I wonder if the preferred canonicalization of that should be to trunc nuw
instead of the icmp
. That would presumably take backend work, but once there’s an icmp
there it’s lost the information needed to undo it again, such as if it’s passed/returned in an register where it’s extended anyway.