ensure llvm gets bounds for size_of_val on slices with an element size of one - #159921
ensure llvm gets bounds for size_of_val on slices with an element size of one#159921asquared31415 wants to merge 2 commits into
Conversation
|
r? @fee1-dead rustbot has assigned @fee1-dead. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
Let's see if perf gives us any evidence that this assume is useful in real code: @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ensure llvm gets bounds for size_of_val on slices with an element size of one
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (3831952): comparison URL. Overall result: ❌✅ regressions and improvements - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary 2.5%, secondary -2.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary 2.4%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (secondary 0.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 489.346s -> 487.704s (-0.34%) |
|
Interesting, the regression looks like the assume does unlock some more optimizations -- slightly more time spent in LLVM and slight decrease in linked_artifact and object_file sizes. Although I'm a bit confused why, from poking at the generated LLVM IR. The only mentions of |
|
Oh, the implementation here is shared with ; test_size_val::s
; Function Attrs: noinline nonlazybind uwtable
define noundef i64 @_RNvCslj8j6VNIQG1_13test_size_val1s(ptr noalias nofree noundef nonnull readonly captures(address, read_provenance) %x.0, i64 noundef range(i64 0, -9223372036854775808) %x.1) unnamed_addr #0 {
start:
%0 = icmp ule i64 %x.1, 9223372036854775807
call void @llvm.assume(i1 %0)
ret i64 %x.1
}Or, at opt-level=0: ; core::mem::size_of_val::<[u8]>
; Function Attrs: inlinehint nonlazybind uwtable
define i64 @_RINvNtCs3cghN7566d9_4core3mem11size_of_valShECslj8j6VNIQG1_13test_size_val(ptr %val.0, i64 %val.1) unnamed_addr #0 {
start:
%0 = icmp ule i64 %val.1, 9223372036854775807
ret i64 %val.1
}That's silly. We should not add assumes to code paths that already have the same information via range metadata. |
|
What code reproduces that case? |
#[inline(never)]
pub fn s(x: &[u8]) -> usize {
size_of_val(x)
} |
|
It appears that the range information is several calls up the call stack, in that it's only on |
|
Hypothetically, you could split the existing intrinsic into two, mirroring the stable |
|
I expect that the only major perf impact would be if more precise range info helps with proving layout calculations cannot overflow. Something like I understand this question is probably only Vibes Based, but do you believe that there would be an appreciable improvement if we did somehow omit the |
|
Oh that's fun, apparently the length field of |
That sounds like part of #152788, cc @scottmcm maybe you have input for this PR and/or the original issue #159754
I think for head + tail calculations the equally or more important part (which we're currently missing) is no-wrap flags on the addition.
At this point my main concern is why would we even invest any more effort into this when there's no clear evidence of it helping. The original issue doesn't have any, rust-perf is a mixed bag but mostly neutral, and the one benchmark that improved may be due to other reasons than the assumes being actually useful, e.g.:
I don't want to just go and close this PR, because then you can't easily reopen it if you find a reviewer who's more optimistic about this. But I would encourage you to find other issues to contribute to which are less of a tar pit and have a clearer value proposition. |
|
So, for fun, I looked into putting range metadata on lengths of Agreed that it's probably not worth pursuing range info even on the most simple cases though, since it's not showing any significant improvements, has minor regressions, and complicates the compiler code. I even looked into doing the two intrinsics approach, and it potentially might fix the regression, but it wouldn't necessarily gain anything. And of course it makes the compiler code even more complicated. |
|
Thank you for looking into this, negative results are still results :) |
|
I think this probably doesn't show up in perf because #148350 means that |
Yeah, really the core problem is that there's no That boils down to the same problem as layout-based niches in references, though, which is hard. |
|
For Reasons(tm) that data gets added in backends, later after layout calculations. |
If someone wants to pick up #152843 and push it over the line, that should help for some of it. It looks like it got stalled out. |
Yup, I wrote the PR that hacked it in there :P |
View all comments
fixes #159754
Also simplifies the zero size element case to return 0 without a multiplication.