Skip to content
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

Emit range metadata on calls returning scalars (fixes #50157) #50164

Merged
merged 1 commit into from
Apr 28, 2018

Conversation

nox
Copy link
Contributor

@nox nox commented Apr 22, 2018

No description provided.

@rust-highfive
Copy link
Collaborator

r? @estebank

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 22, 2018
@@ -1055,6 +1055,27 @@ impl<'a, 'tcx> FnType<'tcx> {
PassMode::Indirect(ref attrs) => apply(attrs),
_ => {}
}
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@nox nox Apr 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially yes, there are two differences:

  • no nonnull metadata is ever emitted for calls, because that's illegal;
  • boolean scalars don't get range metadata because they end up as i1 with a
    !{i1 false, i1 false} range otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I could make the range extraction and masking its own method on Scalar, would you prefer that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point about nonnull, but the calculation of the range (and the relevant comments) should still be de-duplicated.

The i1 part confuses me though. Surely the same problem applies to range metadata on loads? If it is a problem at all, that is: the max_next & mask != min & mask guard should rule that out already, I think? Did something break without the extra check for bools?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the i1 part: https://botbot.me/mozilla/rustc/2018-04-22/?msg=99259759&page=3

I'll add some comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I could make the range extraction and masking its own method on Scalar, would you prefer that?

I still don't know the layout code well enough for my opinion on this to carry much weight, but this is really an LLVM concept, so maybe it should be in rustc_trans. No real clue where, though.

Note that LLVM ranges with max_next & mask == min & mask are inherently invalid, so the helper function could return Option<Range<_>> to avoid duplicating that check as well.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

layout::Int(..) => {
bx.range_metadata(load, range);
}
layout::Pointer if 0 < range.start && range.start < range.end => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether this matters, but this comparison changed. range.end is equal to the old max_next, not max

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many things can I inadvertently change in a single piece of code? I think this actually disables a bunch of nonnull metadata by mistake, but it shouldn't be causing that type checking failure. Will fix anyway.

@nox
Copy link
Contributor Author

nox commented Apr 24, 2018

@bors-servo try

Let's see if this actually works for LLVM >3.9.

@bors
Copy link
Contributor

bors commented Apr 24, 2018

⌛ Trying commit c7c292b with merge c4ba253...

bors added a commit that referenced this pull request Apr 24, 2018
Emit range metadata on calls returning scalars (fixes #50157)
@bors
Copy link
Contributor

bors commented Apr 24, 2018

☀️ Test successful - status-travis
State: approved= try=True

@@ -648,6 +648,25 @@ impl Scalar {
false
}
}

/// Returns a range suitable to be passed to LLVM for range metadata.
pub fn range_metadata<C: HasDataLayout>(&self, cx: C) -> Option<Range<u128>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off, please do not put LLVM special-cases outside of librustc_trans. Secondly, could the check be performed by having a way to get the full range for the size of the primitive in question?

We should really assert, somewhere, that start & mask == start and end & mask == end, because niche computation relies on it - #49981 already fixed an instance of this invariant not being upheld.

Because then you can just go prim.value.full_valid_range(cx) == prim.valid_range and that's your check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off, please do not put LLVM special-cases outside of librustc_trans.

Where should I put that in librustc_trans, and how? A free-standing function? A method on some C defined in librustc_trans? A trait implemented for Scalar?

Secondly, could the check be performed by having a way to get the full range for the size of the primitive in question?

Nope, 0..=255 isn't equal to 1..=0, so I doubt this is a good idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, could this function be named valid_range_exclusive instead, and have the Option replaced with a r.start == r.end in rustc_trans?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

layout::Int(..) if !scalar.is_bool() => {
if let Some(range) = scalar.range_metadata(bx.cx) {
// FIXME(nox): This causes very weird type errors about
// SHL operators in constants in stage 2 with LLVM 3.9.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really retire LLVM 3.9, sigh.

assert!(bits <= 128);
let mask = !0u128 >> (128 - bits);
let start = self.valid_range.start;
let end = self.valid_range.end.wrapping_add(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, wait, this is turning it into an exclusive range. Whereas the storage uses inclusive. I wonder if we could store exclusive ranges throughout, but that sucks for wrap-around ranges because you end up with 0..0 - we should really have some wrap-around range type for layout specifically.

@estebank
Copy link
Contributor

r? @eddyb

@rust-highfive rust-highfive assigned eddyb and unassigned estebank Apr 24, 2018
/// Returns the valid range as a `x..y` range.
///
/// If `x` and `y` are equal, the range is full, not empty.
pub fn range_metadata_exclusive<C: HasDataLayout>(&self, cx: C) -> Range<u128> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please name this valid_range_exclusive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed and squashed everything.

}
layout::Pointer if 0 < min && min < max => {
layout::Pointer
if (1..scalar.valid_range.end).contains(&scalar.valid_range.start) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not !scalar.valid_range.contains(&0)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! Fixed.

@eddyb
Copy link
Member

eddyb commented Apr 25, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 25, 2018

📌 Commit cc77dc4 has been approved by eddyb

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 25, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:24:37]    Compiling atty v0.2.8
[00:24:37]    Compiling backtrace-sys v0.1.16
[00:24:41]    Compiling miniz-sys v0.1.10
[00:24:41]    Compiling rustc_cratesio_shim v0.0.0 (file:///checkout/src/librustc_cratesio_shim)
[00:24:41] error: failed to run custom build command for `syntax v0.0.0 (file:///checkout/src/libsyntax)`
[00:24:41] process didn't exit successfully: `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-rustc/release/build/syntax-5f3de57df7d70275/build-script-build` (signal: 11, SIGSEGV: invalid memory reference)
[00:24:46] error: build failed
[00:24:46] error: build failed
[00:24:46] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "--release" "--locked" "--color" "always" "--features" " jemalloc" "--manifest-path" "/checkout/src/rustc/Cargo.toml" "--message-format" "json"
[00:24:46] expected success, got: exit code: 101
[00:24:46] thread 'main' panicked at 'cargo must succeed', bootstrap/compile.rs:1091:9
[00:24:46] travis_fold:end:stage1-rustc

[00:24:46] travis_time:end:stage1-rustc:start=1524662791826013199,finish=1524662812586433926,duration=20760420727


[00:24:46] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:24:46] Build completed unsuccessfully in 0:19:52
[00:24:46] Makefile:28: recipe for target 'all' failed
[00:24:46] make: *** [all] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:02fafc58
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

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 @TimNN. (Feature Requests)

@eddyb
Copy link
Member

eddyb commented Apr 25, 2018

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 25, 2018
@nox nox force-pushed the rval-range-metadata branch 4 times, most recently from 682ef23 to 55d1cf4 Compare April 25, 2018 16:26
@eddyb
Copy link
Member

eddyb commented Apr 25, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 25, 2018

📌 Commit 55d1cf4 has been approved by eddyb

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 25, 2018
@bors
Copy link
Contributor

bors commented Apr 26, 2018

☔ The latest upstream changes (presumably #50228) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 26, 2018
@eddyb
Copy link
Member

eddyb commented Apr 26, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 26, 2018

📌 Commit 9065644 has been approved by eddyb

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 26, 2018
@bors
Copy link
Contributor

bors commented Apr 28, 2018

⌛ Testing commit 9065644 with merge 68a09fc...

bors added a commit that referenced this pull request Apr 28, 2018
Emit range metadata on calls returning scalars (fixes #50157)
@bors
Copy link
Contributor

bors commented Apr 28, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing 68a09fc to master...

@bors bors merged commit 9065644 into rust-lang:master Apr 28, 2018
@nox nox deleted the rval-range-metadata branch April 28, 2018 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants