-
Notifications
You must be signed in to change notification settings - Fork 13.3k
black_box(f())
in scope 'b gets optimized away, unless f
is ||:'a -> T
and 'a > 'b
#14367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't think this is a bug, at least, the only "bug" here is the non-KILL_SWITCH version not being optimised. In particular, calling %1 = call i64 @_ZN15precise_time_ns20h53df8191405a33f50pa11v0.11.0.preE()
%2 = bitcast i64* %dummy.i.i to i8*
br label %match_else.i
match_else.i: ; preds = %match_else.i, %entry-block
%3 = phi i64 [ 0, %entry-block ], [ %4, %match_else.i ]
%4 = add i64 %3, 1
%5 = call fastcc i64 @_ZN3fib20hebff6027c68c44a7iaa4v0.0E(i64 20)
call void @llvm.lifetime.start(i64 8, i8* %2) #3
store i64 %5, i64* %dummy.i.i, align 8
call void asm "", "r,~{dirflag},~{fpsr},~{flags}"(i64* %dummy.i.i) #3
call void @llvm.lifetime.end(i64 8, i8* %2) #3
%exitcond.i = icmp eq i64 %4, 1000
br i1 %exitcond.i, label %_ZN5bench20h269af04030408b87Jaa4v0.0E.exit, label %match_else.i
_ZN5bench20h269af04030408b87Jaa4v0.0E.exit: ; preds = %match_else.i
%6 = call i64 @_ZN15precise_time_ns20h53df8191405a33f50pa11v0.11.0.preE() but the "bad" KILL_SWITCH version looks like %1 = call i64 @_ZN15precise_time_ns20h53df8191405a33f50pa11v0.11.0.preE()
%2 = call fastcc i64 @_ZN3fib20hc787ae08bc88b138iaa4v0.0E(i64 20) #3
%3 = bitcast i64* %dummy.i.i to i8*
br label %match_else.i
match_else.i: ; preds = %match_else.i, %entry-block
%4 = phi i64 [ 0, %entry-block ], [ %5, %match_else.i ]
%5 = add i64 %4, 1
call void @llvm.lifetime.start(i64 8, i8* %3) #3
store i64 %2, i64* %dummy.i.i, align 8
call void asm "", "r,~{dirflag},~{fpsr},~{flags}"(i64* %dummy.i.i) #3
call void @llvm.lifetime.end(i64 8, i8* %3) #3
%exitcond.i = icmp eq i64 %5, 1000
br i1 %exitcond.i, label %_ZN5bench20hd83cb69b9731384fJaa4v0.0E.exit, label %match_else.i
_ZN5bench20hd83cb69b9731384fJaa4v0.0E.exit: ; preds = %match_else.i
%6 = call i64 @_ZN15precise_time_ns20h53df8191405a33f50pa11v0.11.0.preE() In particular, the To get this to reliably do what you want, without us disabling optimisations (which is a nonstarter), you can pass the argument to || {
let mut n = 20;
black_box(&mut n); // doesn't change it, but LLVM can't tell.
fib(n)
} This makes the IR slightly less nice, but it preserves the |
@huonw Thanks a lot for the detailed explanation! This cleared my doubts about how I'm closing this because my hypothesis have been invalidated. |
…rent-types, r=HKalbasi Fixup path fragments upon MBE transcription Fixes rust-lang#14367 There are roughly two types of paths: paths in expression context, where a separator `::` between an identifier and its following generic argument list is mandatory, and paths in type context, where `::` can be omitted. Unlike rustc, we need to transform the parsed fragments back into tokens during transcription. When the matched path fragment is a type-context path and is transcribed as an expression-context path, verbatim transcription would cause a syntax error. This PR fixes up path fragments by inserting `::` to make sure they are syntactically correct in all contexts. Note that this works because expression-context paths are a strict superset of type-context paths.
…ust-lang#14367) There were two bugs here. Let's assume `T` is a singleton type implementing `Default` and that `f()` takes a `T`: - `f(<T>::default())` cannot be replaced by `f(<T)` as it was (incorrect spans – this is tricky because the type relative path uses a base span covering only `T`, not `<T>`) (third commit) - The argument of `f(<_>::default())` is inferred correctly, but cannot be replaced by `<_>` or `_`, as this cannot be used to infer an instance of a singleton type (first commit). The second commit offers better error messages by pointing at the whole expression. Fix rust-lang#12654 changelog: [`default_constructed_unit_struct`]: do not suggest incorrect fix when using a type surrounded by brackets
Script to reproduce:
I found this issue because I tried to benchmark directly in
main
without the auxiliarbench
function, by callingblack_box(fib(20))
in a loop, butblack_box
got optimized away and I got results like shown above.My hypothesis is that
black_box
only seems to only work with closures whose capturedenv
outlive the scope whereblack_box
is used. The above example supports this hypothesis.This issue doesn't (seem to) affect the
Bencher
framework right now. ButIi/when we get unboxed closures, the example above would pass an unboxed closure that captures nothing (a unit-like struct?), wouldblack_box
still work in that case?cc @huonw
The text was updated successfully, but these errors were encountered: