Open
Description
Copying this here from #101210 (comment) cc @veber-alex
Demo: https://rust.godbolt.org/z/96W4h87Yn
The currently-optimized form isn't allowed to be transformed into the better one: https://alive2.llvm.org/ce/z/DXXRPX
A couple thoughts on things that might help in the codegen:
- The parameters should be marked
noundef
(this will hopefully be addressed by Array-as-Immediate array ABI is missingnoundef
parameter metadata #123183 ) - While we do seem to emit the
!range
metadata (https://rust.godbolt.org/z/KKTKTa1qs), we're hitting the classic problem of us emitting
%4 = load i8, ptr %opta, align 1, !range !3, !noundef !4
%5 = trunc i8 %4 to i1
%_3 = zext i1 %5 to i64
switch i64 %_3, label %bb1 [
i64 0, label %bb2
i64 1, label %bb3
]
And LLVM forgetting both different ways that we told it that inputs like 0x00_05
(the one Alive found) are UB.
Maybe us emitting trunc nuw
will be the eventual solution here? If the trunc nuw
+zext
could fold to just zext
rather than and
+zext
maybe it'd be enough...
Adding some assumes does give LLVM enough information to be allowed to optimize again (https://alive2.llvm.org/ce/z/e6NWxA) though seemingly it doesn't from that starting point
%discr0 = and i16 %0, 255
%discr1 = and i16 %1, 255
%discr0bound = icmp ult i16 %discr0, 2
%discr1bound = icmp ult i16 %discr1, 2
call void @llvm.assume(i1 %discr0bound)
call void @llvm.assume(i1 %discr1bound)