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

Be somewhat clearer about upper bits in the codegen. #1555

Merged
merged 1 commit into from
Jan 22, 2025

Conversation

ltratt
Copy link
Contributor

@ltratt ltratt commented Jan 20, 2025

This is a bit of a hodgepodge of changes, but there are three major things:

  1. Get rid of all the "weird" sized ints, none of which we see in practise, and which we thus have low confidence are correct.
  2. Simplify some of the zero extension stuff.
  3. Zero extend all values to 64 bits before a call. We do this crudely for now.

//! FIXME: the code generator clobbers registers willy-nilly because at the time of writing we have
//! a register allocator that doesn't actually use any registers. Later we will have to audit the
//! backend and insert register save/restore for clobbered registers.
//! * When a value is in a register, we make no guarantees about what the upper bits are set to.
Copy link
Contributor

Choose a reason for hiding this comment

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

I know what you mean here, but we should be clear that the upper undefined bits are unused by the value, and that the value is encoded in the lower order bits.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should also give an example of a typical scenario where zero/sign extend is necessary. That would help us check we are on the same page and help newcomers to understand what we mean.

My understaning is that:

  • inputs to operations (where the result would be incorrect if we didn't) must define the undefined bits with sign/zero extend (or equivalent).
  • outputs of operations may leave the undefined bits undefined: they may assume that any operation consuming the value will define the upper bits appropriately for the operation in question.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The phrasing I'm using is a fairly standard phrasing from specifications. I would prefer to follow that lead rather than introduce our own phrasing that people will not be familiar with.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. I would have liked a bit more explanation, but i suppose we have bigger fish to fry.

@@ -1662,6 +1649,26 @@ impl<'a> Assemble<'a> {
Ok(())
}

/// When we're about to make a call, we need to clear upper bits in registers.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we document who/what imposes this on us? Did you say it was SysV?

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 point.

@@ -1844,7 +1856,7 @@ impl Inst {
Ok(inst)
}

/// Returns the size of the local variable that this instruction defines (if any).
/// Returns the size in bytes of the local variable that this instruction defines (if any).
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the function be called def_bytew for consistency?

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 would actually prefer it to be just bytew but I have several renaming PRs to do :)

@vext01
Copy link
Contributor

vext01 commented Jan 21, 2025

LGTM. Just a few doc/naming suggestions.

@vext01
Copy link
Contributor

vext01 commented Jan 21, 2025

Please squash.

@ltratt ltratt force-pushed the more_undefined_bits branch from 0d413ba to a6a42fe Compare January 21, 2025 20:31
@ltratt
Copy link
Contributor Author

ltratt commented Jan 21, 2025

Squashed.

@vext01 vext01 added this pull request to the merge queue Jan 22, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 22, 2025
@ltratt ltratt force-pushed the more_undefined_bits branch from a6a42fe to 4b3b0ca Compare January 22, 2025 10:01
@ltratt
Copy link
Contributor Author

ltratt commented Jan 22, 2025

Force pushed a Clippy update.

@vext01 vext01 added this pull request to the merge queue Jan 22, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 22, 2025
This is a bit of a hodgepodge of changes, but there are three major
things:

  1. Get rid of all the "weird" sized ints, none of which we see in
     practise, and which we thus have low confidence are correct.
  2. Simplify some of the zero extension stuff.
  3. Zero extend all values to 64 bits before a call. We do this
     crudely for now.
@ltratt ltratt force-pushed the more_undefined_bits branch from 4b3b0ca to a980d52 Compare January 22, 2025 10:29
@ltratt
Copy link
Contributor Author

ltratt commented Jan 22, 2025

Force pushed a bit of extra code needed for havlak. Note: the new code correctly masks off upper bits when we spill, which we didn't do before, so this is another case where we now handle i1 correctly. [Note: bounce doesn't hit this case, so it won't help there. But still...]

@vext01
Copy link
Contributor

vext01 commented Jan 22, 2025

Nice catch.

My initial thought was "would it not be the responsibility of the operation using the unspilled value to ensure the undefined bits are sanitised?", but I'm not really sure what the rules are.

@ltratt
Copy link
Contributor Author

ltratt commented Jan 22, 2025

deopt, for example, doesn't consider undefined bits, so we want to deal with them here. At least for now.

@vext01
Copy link
Contributor

vext01 commented Jan 22, 2025

deopt, for example, doesn't consider undefined bits, so we want to deal with them here. At least for now.

That's an interesting observation that I've not considered before: We don't know the assumptions the AOT code generator makes regarding undefined bits. I wonder if our assumptions are compatible with those assumptions.

I'll merge this for now, but I think we may have to think hard about this at some point.

@vext01 vext01 added this pull request to the merge queue Jan 22, 2025
Merged via the queue into ykjit:master with commit 5341355 Jan 22, 2025
2 checks passed
@ltratt ltratt deleted the more_undefined_bits branch January 24, 2025 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants