Uh oh!
There was an error while loading. Please reload this page.
Optimize away BitAnd and BitOr when possible - #74491
Conversation
rust-highfive
commented
Jul 18, 2020
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
estebank
commented
Jul 19, 2020
The code looks fine but I can't take a good look right now. r? @oli-obk for final review. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
f52e125 to
7894f9fComparexldenis
commented
Jul 20, 2020
I don't understand why CI is failing: I have no idea what to do about this? It doesn't seem related to my changes but it's also not flakiness from what I can tell |
estebank
commented
Jul 20, 2020
@xldenis can you try rebasing on top of a recent master? This doesn't seem like something caused by your PR and doing that might be enough to get CI to pass. Otherwise you might be introducing a bug in this PR and it's triggered in |
|
oli-obk
commented
Jul 21, 2020
it seems to work now on CI, you just need to |
Uh oh!
There was an error while loading. Please reload this page.
this optimization causes a failure for a testcase, that I am unsure how to handle: previously it seems like this code would compile. What is the correct behavior here? Remove the optimization for multiplication? Or should this code not compile because it was a EDIT: that test was supposed to fail, my opt just changes where the error is raised. I fixed the test output. |
aa4b013 to
060c9eeCompareThere was a problem hiding this comment.
please add #![warn(unconditional_panic)] to this file so we test the original thing again. This line can the be changed to
| //~| ERROR this operation will panic at runtime [unconditional_panic] | |
| //~| WARN this operation will panic at runtime [unconditional_panic] |
oli-obk
commented
Jul 21, 2020
cc @lcnr this will make things worse for "some functions that depend on CTFE will evaluate successfully if that generic thing is not needed/used". We already have this situation elsewhere, but we may need to be more aggressive in putting things into the "unevaluated const" list. Right now it's just about generic constants, but after this PR we may need to put function calls of generic functions into it, too. |
oli-obk
commented
Jul 21, 2020
@xldenis this is not a blocker for this PR in general, We may should probably just move your optimization under mir-opt-level 3 until we have the scheme for function calls. What do you think? |
lcnr
commented
Jul 21, 2020
@oli-obk because now So the main problem here is probably something like fntest<T>(){let _ = [0;SOME_MONOMORPHIC_CONST* std::mem::size_of::<T>()];}That means we can't really fix this by just not looking into It's probably cleaner to add a flag to mir which indicates if it depends on type parameters (during mir_built), so we don't have to care about this while optimizing 🤔 |
bors
commented
Jul 23, 2020
💔 Test failed - checks-actions |
rust-log-analyzer
commented
Jul 23, 2020
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
ehuss
commented
Jul 23, 2020
Manishearth
commented
Jul 23, 2020
@bors rollup=iffy may have perf implications |
xldenis
commented
Jul 23, 2020
it doesn't do anything unless |
Manishearth
commented
Jul 23, 2020
@bors rollup- Okay, thanks. @nnethercote we don't perf-check mir-opt=3, yes? |
nnethercote
commented
Jul 24, 2020
|
Optimize away BitAnd and BitOr when possible This PR lets `const_prop` optimize away `a | true == true` , `a & false == false` and `a * 0 = 0`. While I was writing this I've realized that constant propagation misses a lot of opportunities. For example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2a4b45e772f214210a36749b27223bb0 Constant propagation doesn't seem to... propagate constants, additionally the way constant propagation is currently setup makes it tricky to add cases like `a | false == a`. I tried to organize `eval_rvalue_with_identities` to make the pattern of the optimizations easier to see but it still obscurs what should be a simple peephole optmization. cc @oli-obk
…arth Rollup of 8 pull requests Successful merges: - rust-lang#72954 (revise RwLock for HermitCore) - rust-lang#74367 (Rearrange the pipeline of `pow` to gain efficiency) - rust-lang#74491 (Optimize away BitAnd and BitOr when possible) - rust-lang#74639 (Downgrade glibc to 2.11.1 for ppc, ppc64 and s390x) - rust-lang#74661 (Refactor `region_name`: add `RegionNameHighlight`) - rust-lang#74692 (delay_span_bug instead of silent ignore) - rust-lang#74698 (fixed error reporting for mismatched traits) - rust-lang#74715 (Add a system for creating diffs across multiple mir optimizations.) Failed merges: r? @ghost
xldenis
commented
Jul 24, 2020
@nnethercote is there anyway to specify flags for a perf run? I'm curious how much |
Manishearth
commented
Jul 24, 2020
Perf runs just do regular try builds, so I don't think that's possible. You could, however, edit the CI files to use a different set of flags, you just have to do it twice to get the "before" test results. |
…li-obk make `ConstEvaluatable` more strict relevant zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/topic/.60ConstEvaluatable.60.20generic.20functions/near/204125452 Let's see how much this impacts. Depending on how this goes this should probably be a future compat warning. Short explanation: we currently forbid anonymous constants which depend on generic types, e.g. `[0; std::mem::size_of::<T>]` currently errors. We previously checked this by evaluating the constant and returned an error if that failed. This however allows things like ```rust const fn foo<T>() -> usize { if std::mem::size_of::<*mut T>() < 8 { // size of *mut T does not depend on T std::mem::size_of::<T>() } else { 8 } } fn test<T>() { let _ = [0; foo::<T>()]; } ``` which is a backwards compatibility hazard. This also has worrying interactions with mir optimizations (rust-lang#74491 (comment)) and intrinsics (rust-lang#74538). r? `@oli-obk` `@eddyb`
Always permit ConstProp to exploit arithmetic identities Fixesrust-lang#72751 Initially, I thought I would need to enable operand propagation then do something else, but actually rust-lang#74491 already has the fix for the issue in question! It looks like this optimization was put under MIR opt level 3 due to possible soundness/stability implications, then demoted further to MIR opt level 4 when MIR opt level 2 became associated with `--release`. Perhaps in the past we were doing CTFE on optimized MIR? We aren't anymore, so this optimization has no stability implications. r? `@oli-obk`
Always permit ConstProp to exploit arithmetic identities Fixesrust-lang/rust#72751 Initially, I thought I would need to enable operand propagation then do something else, but actually rust-lang/rust#74491 already has the fix for the issue in question! It looks like this optimization was put under MIR opt level 3 due to possible soundness/stability implications, then demoted further to MIR opt level 4 when MIR opt level 2 became associated with `--release`. Perhaps in the past we were doing CTFE on optimized MIR? We aren't anymore, so this optimization has no stability implications. r? `@oli-obk`
This PR lets
const_propoptimize awaya | true == true,a & false == falseanda * 0 = 0. While I was writing this I've realized that constant propagation misses a lot of opportunities. For example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2a4b45e772f214210a36749b27223bb0Constant propagation doesn't seem to... propagate constants, additionally the way constant propagation is currently setup makes it tricky to add cases like
a | false == a.I tried to organize
eval_rvalue_with_identitiesto make the pattern of the optimizations easier to see but it still obscurs what should be a simple peephole optmization.cc @oli-obk