-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Fix passing/returning structs with the 64-bit SPARC ABI #142680
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
base: master
Are you sure you want to change the base?
Conversation
|
r? @bjorn3 |
Note that there are currently two places that Clang and GCC disagree AFAIK:
|
Thank you for doing this! My knowledge in this area is rather limited. I was able to build latest Rust sources with your fix on top on Solaris 11.4 SPARC. Then I used this version to build Firefox on Solaris. There was no problem. Firefox also worked as expected. I also tested some problematic cases which I was handling few years ago (https://github.com/psumbera/rust-sparc64-abi-tests). All seemed to be ok. |
I don't have time to properly review this right now. r? compiler |
β The latest upstream changes (presumably #143521) made this pull request unmergeable. Please resolve the merge conflicts. |
4eb3ce5
to
9e4a7bc
Compare
Rebased |
β The latest upstream changes (presumably #144249) made this pull request unmergeable. Please resolve the merge conflicts. |
9e4a7bc
to
b7b3ed7
Compare
Hi @workingjubilee, are you still interested in reviewing this? If not, we can reroll for a different reviewer. Thanks! |
Looks like there is a Clang fix in llvm/llvm-project#155829 |
Sorry about that, currently in catchup mode so I am going to delegate, yes. r? @tgross35 |
b7b3ed7
to
7cba46f
Compare
This comment has been minimized.
This comment has been minimized.
7cba46f
to
b2e4ee9
Compare
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is neededβthis note is just to help reviewers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, thanks for the updates. I requested a few more comments for things that weren't obvious, r=me after those.
if let [Some(reg), None, ..] = regs { | ||
arg.cast_to_and_pad_i32(CastTarget::from(reg).with_attrs(attrs.into()), pad); | ||
} else { | ||
arg.cast_to_and_pad_i32( | ||
CastTarget::prefixed(regs, Uniform::new(Reg::i8(), Size::ZERO)) | ||
.with_attrs(attrs.into()), | ||
pad, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a note about why the Some(reg), None
case is special?
_ => { | ||
if let BackendRepr::ScalarPair(scalar1, scalar2) = &layout.backend_repr { | ||
data = arg_scalar_pair(cx, scalar1, scalar2, offset, data); | ||
_ => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in the fallback case where offset isn't aligned?
// Match Clang by ignoring whether a struct is packed and just considering | ||
// whether individual fields are aligned. GCC currently uses only integer | ||
// registers when passing packed structs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has come up a couple of times; it may be worth noting in a comment for the module that GCC and Clang have disagreements that the ABI doesn't resolve, and we match Clang's behavior in these cases.
}, | ||
Size::ZERO, | ||
); | ||
let mut double_words = [DoubleWord::Words([Word::Integer; 2]); 4]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you note where the length 4 comes from? Assuming 8 word-sized registers for arg passing.
classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32)); | ||
classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32), &mut 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you mention the significance of 32 bytes?
continue; | ||
} | ||
classify_arg(cx, arg, Size::from_bytes(16)); | ||
classify_arg(cx, arg, Size::from_bytes(16), &mut double_word_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly for 16 here
Reminder, once the PR becomes ready for a review, use |
@psumbera if you have access to a sparc machine, any chance you could run https://github.com/Gankra/abi-cafe with and without this PR as a sanity check? You should be able to clone the repo and run It picks the first rustc/gcc/cc/clang so I think it needs to be run with Edit: looks like packed structs may not work yet Gankra/abi-cafe#33. Still a valuable test._ |
The LLVM fix llvm/llvm-project#155829 has gone into main and I am going to see about backporting to 21. |
Not sure how to analyze it. But Generally I would suggest to use for tests: https://portal.cfarm.net/machines/list/ (cfarm216). This is latest Solaris (SPARC-M8). I'm ready to help and provide full logs somewhere or anything. Here are just few tests which are newly failing:
|
Fixes the 64-bit SPARC part of #115609 by replacing the current implementation with a new implementation modelled on the RISC-V calling convention code (SPARC ABI reference).
Pinging
sparcv9-sun-solaris
target maintainers: @psumbera @kulikjakFixes #115336
Fixes #115399
Fixes #122620
r? @workingjubilee