Skip to content

Add lowering rules for {add,sub,or,and} mem, imm on x64 #11043

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

Merged
merged 3 commits into from
Jun 16, 2025

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Jun 14, 2025

No description provided.

@fitzgen fitzgen requested review from a team as code owners June 14, 2025 00:18
@fitzgen fitzgen requested review from abrown and alexcrichton and removed request for a team June 14, 2025 00:18
@fitzgen fitzgen force-pushed the x64-op-mem-imm branch 2 times, most recently from d108c4f to 4a8a20a Compare June 14, 2025 01:23
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:x64 Issues related to x64 codegen labels Jun 14, 2025
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

What do you think about blocking on the suggestion below to clean up lower.isle?

Also other instructions that might be interesting to add are xor (probably easy) and shifts (maybe harder? unsure)

Comment on lines +4296 to +4278
(rule 1 (x64_add_mem $I64 addr (i64_from_iconst val))
(if-let val2 (i32_try_from_i64 val))
Copy link
Member

Choose a reason for hiding this comment

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

This could replace i64_from_iconst with i32_from_iconst to avoid the if-let

Copy link
Member Author

Choose a reason for hiding this comment

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

We can't do that because i32_from_const will unconditionally truncate upper bits, but we need to only match this rule when the iconst bits will losslessly fit in an i32.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that's correct? The definition of i32_from_iconst uses try_from? (it very much should or we have a lot of incorrect lowering rules)

Copy link
Member Author

Choose a reason for hiding this comment

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

i32_from_iconst seems to do the checks but then we have these other cases that do not:

(decl u32_from_iconst (u32) Value)
(extractor (u32_from_iconst x)
           (u64_from_iconst (u64_as_u32 x)))

;; ...

(decl i8_from_iconst (i8) Value)
(extractor (i8_from_iconst x)
           (i32_from_iconst (i32_as_i8 x)))

Copy link
Member Author

Choose a reason for hiding this comment

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

So I guess this particular one can change, but I don't think we can blanket apply this reasoning to the other cases

Comment on lines +4299 to +4284
(rule 2 (x64_add_mem $I32 addr (i32_from_iconst (i8_try_from_i32 val)))
(x64_addl_mi_sxb_mem addr val))
(rule 2 (x64_add_mem $I64 addr (i64_from_iconst val))
(if-let val2 (i8_try_from_i64 val))
(x64_addq_mi_sxb_mem addr val2))
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to add i8_from_iconst to make these two cases one-liners too?

Copy link
Member Author

Choose a reason for hiding this comment

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

Similarly, this also needs to be fallible

Comment on lines +938 to +940
fn u64_as_u16_extractor(&mut self, val: u64) -> Option<u16> {
Some(val as u16)
}
Copy link
Member

Choose a reason for hiding this comment

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

Personally I'm always wary to discard the lower bits with as in lowering rules lest they accidentally get removed. Given that iconst extraction is generally signed could the above rules do (i16_from_iconst imm) and then the immediate to the instruction is (i16_as_u16 imm) to be clear that there's no data loss it's just reinterpreting the sign bit?

Copy link
Member Author

Choose a reason for hiding this comment

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

There is no i16_from_iconst and this is only used to implement u16_from_iconst and our existing foo_from_iconst extractors (such as u32_from_iconst) already use lossy as conversions and bring the assumption that the caller is choosing a value based on the correct width for their type context.

I don't think that is really the correct choice, but I also don't want to do something different and make it so we have multiple idioms here. We already have enough trouble from some things being extractors and some being pure partial constructors and not being able to reuse one kind of thing for the other. All of our iconst and numerics stuff could definitely be overhauled but, again, I don't really want to do it in this PR. I'd rather just follow the existing code conventions.

@alexcrichton
Copy link
Member

Extracting a comment out here since it's not particularly relevant in isolation: I suppose this is fine to land and while on one hand it's not making things worse on the other hand it's also making things worse because it's adding more places to update with a future refactoring. I'll start working on such a refactoring as this is something that's bothered me for quite some time. If you'd like to land this in the meantime I think that's ok too.

@fitzgen
Copy link
Member Author

fitzgen commented Jun 16, 2025

I was thinking it would be nice to automatically generate the full combinatorial set of fallible, infallible, checked, and truncating ISLE conversions for numeric types in the meta crate

@fitzgen
Copy link
Member Author

fitzgen commented Jun 16, 2025

But yeah, I'll land this now and then we can do the much needed clean up in follow ups.

@fitzgen fitzgen added this pull request to the merge queue Jun 16, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jun 16, 2025
@fitzgen fitzgen enabled auto-merge June 16, 2025 19:36
@fitzgen fitzgen added this pull request to the merge queue Jun 16, 2025
Merged via the queue into bytecodealliance:main with commit a4f8f8f Jun 16, 2025
53 checks passed
@fitzgen fitzgen deleted the x64-op-mem-imm branch June 16, 2025 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:x64 Issues related to x64 codegen cranelift Issues related to the Cranelift code generator
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants