Skip to content

Conversation

@bjorn3
Copy link
Member

@bjorn3 bjorn3 commented Nov 5, 2025

LLVM intrinsics have weird requirements like requiring the fake "unadjusted" abi, not being callable through function pointers and for all codegen backends other than cg_llvm requiring special cases to redirect them to the correct backend specific intrinsic (or directly codegen their implementation inline without any intrinsic call). By splitting the LLVM intrinsic handling it becomes easier for backends to special case them and should in the future allow getting rid of the abi calculation for extern "unadjusted" in favor of computing the correct abi directly in the backend without depending on the exact way cg_ssa lowers types.

@rustbot
Copy link
Collaborator

rustbot commented Nov 5, 2025

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 5, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 5, 2025

r? @SparrowLii

rustbot has assigned @SparrowLii.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 5, 2025

cc @sayantn This should make #140763 much less intrusive for the non-intrinsic call handling and should allow you to localize all changes to cg_llvm without having to touch cg_ssa and cg_gcc.

@sayantn
Copy link
Contributor

sayantn commented Nov 5, 2025

this is awesome, thanks ❤️. I tested compiling stdarch with this branch (for x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu and riscv64gc-unknown-linux-gnu targets), it doesn't generate any errors

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 5, 2025

Thanks for testing! I hadn't thought about testing this on stdarch. Did you also test compiling the stdarch tests? Otherwise no llvm intrinsic calls are actually getting codegened I think due to all #[inline(always)].

@sayantn
Copy link
Contributor

sayantn commented Nov 5, 2025

yes, I did cargo build -p core_arch --tests, which will compile all intrinsics in x86 (due to all intrinsics having corresponding tests), I am not so sure about aarch64, there can be some intrinsics that are not tested.

@sayantn
Copy link
Contributor

sayantn commented Nov 10, 2025

@bjorn3 could you see if it's possible to split the function declaration of LLVM intrinsics too - after inspecting my PR I noticed that it modifies declaration more than calling. Thanks

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 10, 2025

I figured I would do that after this PR gets merged, but I can do it somewhere in the next couple of days too. In this PR if it hasn't been reviewed by then and otherwise in a separate PR.

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 10, 2025

Something like this @sayantn?

@antoyo @GuillaumeGomez would you mind reviewing the cg_gcc changes?

@sayantn
Copy link
Contributor

sayantn commented Nov 10, 2025

Thanks, It's nice, but do we need to cache the intrinsic instances? get_fn should be called only when declaring an intrinsic, and that's mostly one-time for an intrinsic

@antoyo
Copy link
Contributor

antoyo commented Nov 10, 2025

@antoyo @GuillaumeGomez would you mind reviewing the cg_gcc changes?

This does look good to me, but I would need to run the tests of cg_gcc to confirm.
@GuillaumeGomez: Is there an easy way to run all of cg_gcc's tests in the Rust repo?

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 10, 2025

It's nice, but do we need to cache the intrinsic instances?

codegen_llvm_intrinsic_call is called once per intrinsic call, not once per intrinsic declaration.

@GuillaumeGomez
Copy link
Member

@GuillaumeGomez: Is there an easy way to run all of cg_gcc's tests in the Rust repo?

./x.py test --test-codegen-backend=gcc should do it.

@antoyo
Copy link
Contributor

antoyo commented Nov 10, 2025

./x.py test --test-codegen-backend=gcc should do it.

Isn't that only running UI tests?

@GuillaumeGomez
Copy link
Member

No, any testsuite with this argument will use the GCC backend.

@antoyo
Copy link
Contributor

antoyo commented Nov 10, 2025

No, any testsuite with this argument will use the GCC backend.

I meant that this won't run the stdarch tests or other tests we have in the CI of the cg_gcc repo.
We need a test that uses LLVM intrinsics and I'm not sure if those we can run in the Rust repo has any.

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 10, 2025

Maybe you could build rustc with cg_gcc as default backend and then manually run the stdarch test suite using it?

@sayantn
Copy link
Contributor

sayantn commented Nov 10, 2025

Ah sorry, the current design looks nice. I will test it on stdarch locally when I get some time

@antoyo
Copy link
Contributor

antoyo commented Nov 10, 2025

Maybe you could build rustc with cg_gcc as default backend and then manually run the stdarch test suite using it?

I tried to build your branch locally and it seems it broke a stage-2 build with cg_gcc.
I get this error:

libgccjit.so: error: : bitcast with types of different sizes
input expression (size: 8):
 <integer_cst 0x7f9ff9560348 type <integer_type 0x7f9ff954b498 unsigned char> constant visited 0>
requested type (size: 32):
 <integer_type 0x7f9ff954bc78 int public SI
    size <integer_cst 0x7f9ff9560468 type <integer_type 0x7f9ff954b690 bitsizetype> constant 32>
    unit-size <integer_cst 0x7f9ff9560480 type <integer_type 0x7f9ff954b5e8 sizetype> constant 4>
    align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7f9ff954bc78 precision:32 min <integer_cst 0x7f9ff9560420 -2147483648> max <integer_cst 0x7f9ff9560438 2147483647>
    pointer_to_this <pointer_type 0x7f9ff95691f8>>

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 10, 2025

Does it work with the last commit reverted?

@bjorn3 bjorn3 force-pushed the split_llvm_intrinsic_abi_handling branch from 0563b07 to 6d4eb0e Compare November 11, 2025 11:05
@bjorn3
Copy link
Member Author

bjorn3 commented Nov 11, 2025

Managed to reproduce it locally. I've added 4f4812f, split out be36d2f, removed all cg_gcc changes from 915af4f and finally changed 6d4eb0e to use a function pointer + bx.call() rather than a direct function call. It seems that there is some function signature casting logic in bx.call() that is load bearing here. I didn't manage to figure out exactly what though.

@antoyo
Copy link
Contributor

antoyo commented Nov 11, 2025

Nice. Were you able to also run the stdarch tests or do you want me to do it?

@bjorn3
Copy link
Member Author

bjorn3 commented Nov 11, 2025

I haven't tried. I ran out of memory when building stage 2 rustc_middle several times forcing me to reboot.

@antoyo
Copy link
Contributor

antoyo commented Nov 11, 2025

Oh, let's hope that the next sync that reduced memory usage considerably in some cases would help here as well.
I'll try to run those tests locally.

Copy link
Contributor

@antoyo antoyo left a comment

Choose a reason for hiding this comment

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

The stdarch tests pass with this branch.

View changes since this review

@rustbot rustbot assigned WaffleLapkin and unassigned SparrowLii Dec 10, 2025
@WaffleLapkin
Copy link
Member

What's the status with #149141? Is this PR no longer blocked on it? (I couldn't quite figure out what's the problem with it by reading the comments...)

@bjorn3
Copy link
Member Author

bjorn3 commented Dec 10, 2025

The last commit in this PR makes #149141 no longer necessary. I will close #149141 if the approach in that commit is considered acceptable.

@WaffleLapkin
Copy link
Member

@bjorn3 my understanding was that the last commit here is a temporary hack that will be later replaced with something proper, is that not the case?

@bjorn3
Copy link
Member Author

bjorn3 commented Dec 22, 2025

Maybe a proper way can be found in the future, but for now I think this hack will stay. Wasm has exactly two llvm intrinsics which need it (llvm.wasm.throw and llvm.wasm.rethrow the latter of which we don't use) and I don't think any other architecture has unwinding llvm intrinsics.

@WaffleLapkin
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented Dec 26, 2025

📌 Commit 4eb6e1c has been approved by WaffleLapkin

It is now in the queue for this repository.

@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 Dec 26, 2025
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Dec 26, 2025
…ndling, r=WaffleLapkin

Split LLVM intrinsic abi handling from the rest of the abi handling

LLVM intrinsics have weird requirements like requiring the fake "unadjusted" abi, not being callable through function pointers and for all codegen backends other than cg_llvm requiring special cases to redirect them to the correct backend specific intrinsic (or directly codegen their implementation inline without any intrinsic call). By splitting the LLVM intrinsic handling it becomes easier for backends to special case them and should in the future allow getting rid of the abi calculation for `extern "unadjusted"` in favor of computing the correct abi directly in the backend without depending on the exact way cg_ssa lowers types.
bors added a commit that referenced this pull request Dec 26, 2025
…uwer

Rollup of 3 pull requests

Successful merges:

 - #147717 (compiler/middle/lint: Suggest `#[expect(dead_code)]` instead of `#[allow(dead_code)]`)
 - #148533 (Split LLVM intrinsic abi handling from the rest of the abi handling)
 - #150236 (Port `#[rustc_must_implement_one_of]` to attribute parser)

r? `@ghost`
`@rustbot` modify labels: rollup
@JonathanBrouwer
Copy link
Contributor

@bors r-
#150404 (comment)

@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 Dec 26, 2025
Intrinsics only need a fraction of the functionality offered by
BuilderMethods::call and in particular don't need the FnAbi to be
computed other than (currently) as step towards computing the function
value type.
This moves all LLVM intrinsic handling out of the regular call path for
cg_gcc and makes it easier to hook into this code for future cg_llvm
changes.
As this is the only unwinding intrinsic we use and
codegen_llvm_intrinsic_call currently doesn't handle unwinding
intrinsics, this uses the conventional call path for llvm.wasm.throw.
@bjorn3 bjorn3 force-pushed the split_llvm_intrinsic_abi_handling branch from 4eb6e1c to 7712c1a Compare December 26, 2025 21:08
@rustbot
Copy link
Collaborator

rustbot commented Dec 26, 2025

This PR was rebased onto a different main 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.

@bjorn3
Copy link
Member Author

bjorn3 commented Dec 26, 2025

I can't reproduce this locally after a rebase.

@rust-log-analyzer
Copy link
Collaborator

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    |
    = help: items from traits can only be used if the trait is in scope
help: one of the expressions' fields has a method of the same name
    |
627 |                 let fn_abi = self.cx.tcx.fn_abi_of_instance(instance, ty::List::empty());
    |                                   +++++++
help: one of the expressions' fields has a method of the same name
    |
627 |                 let fn_abi = self.tcx.fn_abi_of_instance(instance, ty::List::empty());
    |                                   ++++
help: trait `FnAbiOf` which provides `fn_abi_of_instance` is implemented but not in scope; perhaps you want to import it
    |
  1 + use crate::rustc_middle::ty::layout::FnAbiOf;
    |
help: there is a method `fn_abi_of_fn_ptr` with a similar name
    |

@bjorn3
Copy link
Member Author

bjorn3 commented Dec 26, 2025

I think it is because of the master cargo feature being different between CI and locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.