Skip to content

Sync from rust 2026/03/13#862

Open
antoyo wants to merge 33 commits intomasterfrom
sync_from_rust_2026_03_13
Open

Sync from rust 2026/03/13#862
antoyo wants to merge 33 commits intomasterfrom
sync_from_rust_2026_03_13

Conversation

@antoyo
Copy link
Contributor

@antoyo antoyo commented Mar 13, 2026

No description provided.

flip1995 and others added 30 commits February 12, 2026 16:55
Clippy subtree update

r? @Manishearth 

1 week late, due to vacation and some technical issues.
It was just a dummy implementation to workarround the fact that thin
local lto is the default in rustc. By adding a thin_lto_supported thin
local lto can be automatically disabled for cg_gcc, removing the need
for this dummy implementation. This makes improvements to the LTO
handling on the cg_ssa side a lot easier.
This allows us to get rid of box_new entirely
This allows removing the Metadata associated type from BackendTypes.
In Cranelift the regular Type enum can't represent function signatures.
Function pointers are represented as plain pointer sized integer.
Previously this was not correctly implemented. Each funclet may need its own terminate
block, so this changes the `terminate_block` into a `terminate_blocks` `IndexVec` which
can have a terminate_block for each funclet. We key on the first basic block of the
funclet -- in particular, this is the start block for the old case of the top level
terminate function.

Rather than using a catchswitch/catchpad pair, I used a cleanuppad. The reason for the
pair is to avoid catching foreign exceptions on MSVC. On wasm, it seems that the
catchswitch/catchpad pair is optimized back into a single cleanuppad and a catch_all
instruction is emitted which will catch foreign exceptions. Because the new logic is
only used on wasm, it seemed better to take the simpler approach seeing as they do the
same thing.
In Cranelift a Value can't hold arbitrarily sized values.
Fix: On wasm targets, call `panic_in_cleanup` if panic occurs in cleanup

Previously this was not correctly implemented. Each funclet may need its own terminate block, so this changes the `terminate_block` into a `terminate_blocks` `IndexVec` which can have a terminate_block for each funclet. We key on the first basic block of the funclet -- in particular, this is the start block for the old case of the top level terminate function.

I also fixed the `terminate` handler to not be invoked when a foreign exception is raised, mimicking the behavior from msvc. On wasm, in order to avoid generating a `catch_all` we need to call `llvm.wasm.get.exception` and `llvm.wasm.get.ehselector`.
Couple of cg_ssa refactorings

These should help a bit with using cg_ssa in cg_clif at some point in the future.
This is already CodegenResults without CrateInfo. The driver can
calculate the CrateInfo and pass it by-ref to the backend. Using
CompiledModules makes it a bit easier to move some other things out of
the backend as will be necessary for moving LTO to the link phase.
Make `size`/`align` always correct rather than conditionally on the
`safe` field. This makes it less error prone and easier to work with for
`MaybeDangling` / potential future pointer kinds like `Aligned<_>`.
Instead of defaulting to `None` it now defaults to `Align::ONE` i.e.
no alignment restriction. Codegen test changes are due to us now skipping
`align 1` annotations (they are useless; not skipping them makes all the
raw pointers gain an `align 1` annotation which doesn't seem any good)
…Jung

Implement `MaybeDangling` compiler support



Tracking issue: rust-lang/rust#118166



cc @RalfJung
Renaming to remove any ambiguity as to what "vector" refers to in this
context
It's defined in `rustc_span::source_map` which doesn't make any sense
because it has nothing to do with source maps. This commit moves it to
the crate root, a more sensible spot for something this basic.
…uwer

Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#153560 (Introduce granular tidy_ctx's check in extra_checks)
 - rust-lang/rust#153666 (Add a regression test for rust-lang/rust#153599)
 - rust-lang/rust#153493 (Remove `FromCycleError` trait)
 - rust-lang/rust#153549 (tests/ui/binop: add annotations for reference rules)
 - rust-lang/rust#153641 (Move `Spanned`.)
 - rust-lang/rust#153663 (Remove `TyCtxt::node_lint` method and `rustc_middle::lint_level` function)
 - rust-lang/rust#153664 (Add test for rust-lang/rust#109804)
@antoyo
Copy link
Contributor Author

antoyo commented Mar 13, 2026

@bjorn3: We still get the same error.
Does rustc provide the main function differently when doing LTO?

@bjorn3
Copy link
Member

bjorn3 commented Mar 18, 2026

It now correctly uses fat LTO for cg_gcc afaict. Something seems to have broken fat LTO. There are two .o files being produced one which is effectively empty and one with .o.lto as extension that contains the actual machine code. The former is being passed to the linker. The following diff seems to work for me. I don't know why that extra compilation step was there.

diff --git a/src/back/write.rs b/src/back/write.rs
index 24ea2b66..540472ec 100644
--- a/src/back/write.rs
+++ b/src/back/write.rs
@@ -148,7 +148,6 @@ pub(crate) fn codegen(
                     let path = obj_out.to_str().expect("path to str");
 
                     if fat_lto {
-                        let lto_path = format!("{}.lto", path);
                         // cSpell:disable
                         // FIXME(antoyo): The LTO frontend generates the following warning:
                         // ../build_sysroot/sysroot_src/library/core/src/num/dec2flt/lemire.rs:150:15: warning: type of ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ does not match original declaration [-Wlto-type-mismatch]
@@ -161,24 +160,7 @@ pub(crate) fn codegen(
                         context.add_driver_option("-Wno-lto-type-mismatch");
                         // NOTE: this doesn't actually generate an executable. With the above
                         // flags, it combines the .o files together in another .o.
-                        context.compile_to_file(OutputKind::Executable, &lto_path);
-
-                        let context = Context::default();
-                        if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" {
-                            // NOTE: it seems we need to use add_driver_option instead of
-                            // add_command_line_option here because we use the LTO frontend via gcc.
-                            context.add_driver_option("-masm=intel");
-                        }
-
-                        // NOTE: these two options are needed to invoke LTO to produce an object file.
-                        // We need to initiate a second compilation because the arguments "-x lto"
-                        // needs to be at the very beginning.
-                        context.add_driver_option("-x");
-                        context.add_driver_option("lto");
-                        add_pic_option(&context, module.module_llvm.relocation_model);
-                        context.add_driver_option(lto_path);
-
-                        context.compile_to_file(OutputKind::ObjectFile, path);
+                        context.compile_to_file(OutputKind::Executable, &path);
                     } else {
                         // NOTE: this doesn't actually generate an executable. With the above
                         // flags, it combines the .o files together in another .o.

I did have to also apply the following patch (with paths adjusted): https://github.com/rust-lang/rustc_codegen_cranelift/blob/main/patches/0030-sysroot_tests-Add-missing-feature-gate.patch Still need to upstream that one.

With those two changes I eventually get an ICE that the logf16 intrinsic needs to be overridden.

@antoyo antoyo force-pushed the sync_from_rust_2026_03_13 branch from 7d49787 to cacf74a Compare March 20, 2026 17:06
@antoyo
Copy link
Contributor Author

antoyo commented Mar 20, 2026

The following diff seems to work for me. I don't know why that extra compilation step was there.

This seems to break actual Fat LTO as the CI shows.

I don't know why that extra compilation step was there.

This code calls the LTO frontend (via -x lto) to perform LTO.

Any idea how to fix Thin LTO while keeping this code?

@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

This seems to break actual Fat LTO as the CI shows.

For me fat LTO was actually broken without that change. The hello-world test failed with lto=fat. I don't recall having changed anything in the fat lto implementation on the rustc side that could break cg_gcc.

@antoyo
Copy link
Contributor Author

antoyo commented Mar 20, 2026

For me fat LTO was actually broken without that change. The hello-world test failed with lto=fat.

It does work for me. Maybe you forgot the -Cembed-bitcode=yes flag when building the sysroot?
The full command to build the sysroot is for Fat LTO is:

CG_RUSTFLAGS="-Cembed-bitcode=yes" ./y.sh build --sysroot --release-sysroot

I don't recall having changed anything in the fat lto implementation on the rustc side that could break cg_gcc.

Fat LTO is not broken by the changes on the rustc side: it does work for me.
What I meant is that the patch you proposed here does break Fat LTO.
So, that doesn't look like the correct solution to fix Thin LTO.
Any idea how we could properly fix Thin LTO here?
Thanks.

@bjorn3
Copy link
Member

bjorn3 commented Mar 23, 2026

I missed that CG_RUSTFLAGS="-Cembed-bitcode=yes" is necessary. With that for me locally both fat LTO and thin LTO work just fine without the patch in #862 (comment)

$ CG_RUSTFLAGS="-Cembed-bitcode=yes" ./y.sh build --sysroot --release-sysroot
[BUILD] build system
   Compiling boml v0.3.1
   Compiling y v0.1.0 (/mnt/build_system)
    Finished `release` profile [optimized] target(s) in 1.70s
GCC path retrieved from `config.toml`. Using `/usr/lib` as path for libgccjit
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s
[BUILD] sysroot
   Compiling compiler_builtins v0.1.160 (/mnt/build/build_sysroot/sysroot_src/library/compiler-builtins/compiler-builtins)
   Compiling core v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/core)
   Compiling libc v0.2.178
   Compiling object v0.37.3
   Compiling std v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/std)
   Compiling test v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/test)
   Compiling rustc-std-workspace-core v1.99.0 (/mnt/build/build_sysroot/sysroot_src/library/rustc-std-workspace-core)
   Compiling alloc v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/alloc)
   Compiling memchr v2.7.6
   Compiling adler2 v2.0.1
   Compiling rustc-demangle v0.1.27
   Compiling panic_abort v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/panic_abort)
   Compiling cfg-if v1.0.4
   Compiling rustc-literal-escaper v0.0.7
   Compiling unwind v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/unwind)
   Compiling rustc-std-workspace-alloc v1.99.0 (/mnt/build/build_sysroot/sysroot_src/library/rustc-std-workspace-alloc)
   Compiling panic_unwind v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/panic_unwind)
   Compiling gimli v0.32.3
   Compiling miniz_oxide v0.8.9
   Compiling hashbrown v0.16.1
   Compiling std_detect v0.1.5 (/mnt/build/build_sysroot/sysroot_src/library/std_detect)
   Compiling addr2line v0.25.1
   Compiling rustc-std-workspace-std v1.99.0 (/mnt/build/build_sysroot/sysroot_src/library/rustc-std-workspace-std)
   Compiling proc_macro v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/proc_macro)
   Compiling getopts v0.2.24
   Compiling sysroot v0.0.0 (/mnt/build/build_sysroot/sysroot_src/library/sysroot)
    Finished `release` profile [optimized] target(s) in 3m 11s
[BUILD] build system
    Finished `release` profile [optimized] target(s) in 0.01s
$ ./y.sh cargo run --manifest-path tests/hello-world/Cargo.toml
GCC path retrieved from `config.toml`. Using `/usr/lib` as path for libgccjit
   Compiling mylib v0.1.0 (/mnt/tests/hello-world/mylib)
   Compiling hello_world v0.0.0 (/mnt/tests/hello-world)
warning: ThinLTO is not supported by the codegen backend, using fat LTO instead

warning: `hello_world` (bin "hello_world") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 49.16s
     Running `tests/hello-world/target/debug/hello_world`
40

I just noticed that the CI failure is on a job that doesn't support LTO at all. So the testwould never have worked with fat LTO. The only reason it worked with thin LTO previously is because that was effectively disabling LTO. I think the proper fix is to just disable LTO for this test with CARGO_PROFILE_DEV_LTO=no.

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 840c0940..2b4a5db5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -101,7 +101,7 @@ jobs:
 
     - name: Run y.sh cargo build
       run: |
-        ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
+        CARGO_PROFILE_DEV_LTO=no ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
 
     - name: Clean
       run: |

@bjorn3
Copy link
Member

bjorn3 commented Mar 23, 2026

#864 fixes CI. You may want to squash away the revert commit.

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.