Open
Description
Original Rust example: https://rust.godbolt.org/z/xze3vEx8E
pub unsafe fn extend_packed_unchecked(a: Layout, b: Layout) -> usize {
a.extend_packed(b).unwrap_unchecked().size()
}
Actual output (-) and what I'd hope to get instead (+):
define noundef i64 @extend_packed_unchecked(i64 noundef range(i64 1, -9223372036854775807) %0, i64 noundef %1, i64 noundef range(i64 1, -9223372036854775807) %b.0, i64 noundef %b.1) unnamed_addr {
start:
- %new_size = add nuw i64 %b.1, %1
+ %new_size = add nuw nsw i64 %b.1, %1
%_11 = sub nuw i64 -9223372036854775808, %0
%_10 = icmp ule i64 %new_size, %_11
tail call void @llvm.assume(i1 %_10)
ret i64 %new_size
}
Note that %_11 sgt -1
, thanks to the range attribute on the %0
parameter.
Alive proof that this is allowed: https://alive2.llvm.org/ce/z/Dn2P8R
Repro that more opt
on trunk doesn't do it: https://llvm.godbolt.org/z/Kr8n37s41
Oh, turns out the simpler case of just
define noundef i64 @demo_b(i64 noundef %1, i64 noundef %b.1) unnamed_addr {
start:
%new_size = add nuw i64 %b.1, %1
%_10 = icmp ule i64 %new_size, 9223372036854775807
tail call void @llvm.assume(i1 %_10)
ret i64 %new_size
}
doesn't add the nsw
either.
And that'd be allowed too: https://alive2.llvm.org/ce/z/PeC7No
Context: I've been looking at layout and pondering whether we need separate unchecked methods, or can just trust LLVM to optimize to the same things anyway when unwrap_unchecked
is used.
PRs like rust-lang/rust#136575 have me thinking about nuw
/nsw
.