From b3f16fde9c7bf426228ae3ab78664f280e6825b9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 4 Nov 2025 16:01:49 +0100 Subject: [PATCH 01/27] Merge commit 'e785c50dad2944c7b4fb2d929de531f859db1e99' into subtree-update_cg_gcc_2025-11-04 --- .github/workflows/release.yml | 28 ++++-- .github/workflows/stdarch.yml | 2 +- Cargo.lock | 8 +- Cargo.toml | 2 +- Readme.md | 18 ++-- build_system/src/build.rs | 3 + build_system/src/clean.rs | 9 +- build_system/src/prepare.rs | 72 ++++++++++---- build_system/src/test.rs | 64 +++++++------ build_system/src/utils.rs | 9 +- example/mini_core.rs | 26 +++++- example/mini_core_hello_world.rs | 13 +-- libgccjit.version | 2 +- rust-toolchain | 2 +- src/abi.rs | 2 +- src/back/lto.rs | 13 ++- src/back/write.rs | 103 +++++++------------- src/base.rs | 10 +- src/builder.rs | 61 +++++++----- src/int.rs | 17 ++-- src/intrinsic/archs.rs | 156 +++++++++++++++++++++++++++++++ src/intrinsic/mod.rs | 4 - src/lib.rs | 42 +++++++-- tests/cross_lang_lto/Cargo.lock | 7 ++ tests/cross_lang_lto/Cargo.toml | 6 ++ tests/cross_lang_lto/add.c | 5 + tests/cross_lang_lto/src/main.rs | 18 ++++ tests/failing-lto-tests.txt | 33 ------- tests/failing-run-make-tests.txt | 24 ----- tests/failing-ui-tests.txt | 13 +-- 30 files changed, 481 insertions(+), 291 deletions(-) create mode 100644 tests/cross_lang_lto/Cargo.lock create mode 100644 tests/cross_lang_lto/Cargo.toml create mode 100644 tests/cross_lang_lto/add.c create mode 100644 tests/cross_lang_lto/src/main.rs delete mode 100644 tests/failing-lto-tests.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7e2583aad39f..52f94dc2970a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,7 +62,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - EMBED_LTO_BITCODE=1 ./y.sh build --sysroot --release --release-sysroot + ./y.sh build --sysroot --release --release-sysroot ./y.sh test --cargo-tests ./y.sh clean all @@ -72,19 +72,14 @@ jobs: git config --global user.name "User" ./y.sh prepare - - name: Add more failing tests because of undefined symbol errors (FIXME) - run: cat tests/failing-lto-tests.txt >> tests/failing-ui-tests.txt - - name: Run tests run: | # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. - # FIXME(antoyo): this should probably not be needed since we embed the LTO bitcode. - printf '[profile.release]\nlto = "fat"\n' >> build/build_sysroot/sysroot_src/library/Cargo.toml - EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot --keep-lto-tests ${{ matrix.commands }} + CG_RUSTFLAGS="-Cembed-bitcode=yes" ./y.sh test --release --clean --release-sysroot --build-sysroot --keep-lto-tests ${{ matrix.commands }} - - name: Run y.sh cargo build + - name: LTO test run: | - EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml + CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml call_found=$(objdump -dj .text tests/hello-world/target/release/hello_world | grep -c "call .*mylib.*my_func" ) ||: if [ $call_found -gt 0 ]; then echo "ERROR: call my_func found in asm" @@ -92,6 +87,21 @@ jobs: exit 1 fi + - name: Cross-language LTO test + run: | + pushd tests/cross_lang_lto + gcc -c -flto add.c -masm=intel -fPIC -O3 + ar rcs libadd.a add.o + popd + + CHANNEL="release" CG_RUSTFLAGS="-L native=. -Clinker-plugin-lto -Clinker=gcc" ./y.sh cargo build --release --manifest-path tests/cross_lang_lto/Cargo.toml + call_found=$(objdump -dj .text tests/cross_lang_lto/target/release/cross_lang_lto | grep -c "call .*my_add" ) ||: + if [ $call_found -gt 0 ]; then + echo "ERROR: call my_add found in asm" + echo "Test is done with cross-language LTO enabled, hence inlining should occur across object files" + exit 1 + fi + # Summary job for the merge queue. # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! success_release: diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 20d009f08a798..184f122cc1c17 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -41,7 +41,7 @@ jobs: # TODO: remove when we have binutils version 2.43 in the repo. - name: Install more recent binutils run: | - echo "deb http://archive.ubuntu.com/ubuntu oracular main universe" | sudo tee /etc/apt/sources.list.d/oracular-copies.list + echo "deb http://archive.ubuntu.com/ubuntu plucky main universe" | sudo tee /etc/apt/sources.list.d/plucky-copies.list sudo apt-get update sudo apt-get install binutils diff --git a/Cargo.lock b/Cargo.lock index a5b972baf98e3..181d3aa89bc89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0e310ef75f396cd11b2443b353d55376656ca92c13cba36f92b7aff346ac1a" +checksum = "60362e038e71e4bdc1a5b23fb45e1aba587b5947fe0db58f4871d95608f89eca" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed7572b30cd32430294dde6fb70822d58e67c6846a548647e8739776a0125b" +checksum = "ddd542c8414e122217551c6af6b7d33acf51a227aee85276f218c087525e01bb" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 6031933bd2d2b..d3ff2757857b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" -gccjit = "2.8" +gccjit = "2.10" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } # Local copy. diff --git a/Readme.md b/Readme.md index 859bb1568f4eb..cd6aeae4b42ea 100644 --- a/Readme.md +++ b/Readme.md @@ -70,11 +70,17 @@ $ ../gcc/configure \ $ make -j4 # You can replace `4` with another number depending on how many cores you have. ``` -If you want to run libgccjit tests, you will need to also enable the C++ language in the `configure`: +If you want to run libgccjit tests, you will need to +* Enable the C++ language in the `configure` step: ```bash --enable-languages=jit,c++ ``` +* Install [dejagnu](https://www.gnu.org/software/dejagnu/#downloading) to run the tests: + +```bash +$ sudo apt install dejagnu +``` Then to run libgccjit tests: @@ -135,16 +141,6 @@ $ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run If you compiled cg_gccjit in debug mode (aka you didn't pass `--release` to `./y.sh test`) you should use `CHANNEL="debug"` instead or omit `CHANNEL="release"` completely. -### LTO - -To use LTO, you need to set the variable `EMBED_LTO_BITCODE=1` in addition to setting `lto = "fat"` in the `Cargo.toml`. - -Failing to set `EMBED_LTO_BITCODE` will give you the following error: - -``` -error: failed to copy bitcode to object file: No such file or directory (os error 2) -``` - ### Rustc If you want to run `rustc` directly, you can do so with: diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 94b40319f4a77..6aa5faec4c81e 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -149,6 +149,9 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Copy files to sysroot let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); + // To avoid errors like "multiple candidates for `rmeta` dependency `core` found", we clean the + // sysroot directory before copying the sysroot build artifacts. + let _ = fs::remove_dir_all(&sysroot_path); create_dir(&sysroot_path)?; let mut copier = |dir_to_copy: &Path| { // FIXME: should not use shell command! diff --git a/build_system/src/clean.rs b/build_system/src/clean.rs index a441ed613f949..43f01fdf35ecb 100644 --- a/build_system/src/clean.rs +++ b/build_system/src/clean.rs @@ -69,8 +69,13 @@ fn clean_all() -> Result<(), String> { } fn clean_ui_tests() -> Result<(), String> { - let path = Path::new(crate::BUILD_DIR).join("rust/build/x86_64-unknown-linux-gnu/test/ui/"); - run_command(&[&"find", &path, &"-name", &"stamp", &"-delete"], None)?; + let directories = ["run-make", "run-make-cargo", "ui"]; + for directory in directories { + let path = Path::new(crate::BUILD_DIR) + .join("rust/build/x86_64-unknown-linux-gnu/test/") + .join(directory); + run_command(&[&"find", &path, &"-name", &"stamp", &"-delete"], None)?; + } Ok(()) } diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index 35a6e20fb86bb..1e97e8d932746 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -1,5 +1,7 @@ +use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; +use std::process::Output; use crate::rustc_info::get_rustc_path; use crate::utils::{ @@ -7,6 +9,41 @@ use crate::utils::{ run_command_with_output, walk_dir, }; +// This is needed on systems where nothing is configured. +// git really needs something here, or it will fail. +// Even using --author is not enough. +const GIT_CMD: [&dyn AsRef; 9] = [ + &"git", + &"-c", + &"user.name=None", + &"-c", + &"user.email=none@example.com", + &"-c", + &"core.autocrlf=false", + &"-c", + &"commit.gpgSign=false", +]; + +fn run_git_command( + command: &dyn AsRef, + input: &[&dyn AsRef], + cwd: Option<&Path>, +) -> Result { + let git_cmd = + &GIT_CMD.into_iter().chain([command]).chain(input.iter().cloned()).collect::>()[..]; + run_command(git_cmd, cwd) +} + +fn run_git_command_with_output( + command: &dyn AsRef, + input: &[&dyn AsRef], + cwd: Option<&Path>, +) -> Result<(), String> { + let git_cmd = + &GIT_CMD.into_iter().chain([command]).chain(input.iter().cloned()).collect::>()[..]; + run_command_with_output(git_cmd, cwd) +} + fn prepare_libcore( sysroot_path: &Path, libgccjit12_patches: bool, @@ -55,19 +92,12 @@ fn prepare_libcore( run_command(&[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], None)?; println!("[GIT] init (cwd): `{}`", sysroot_dir.display()); - run_command(&[&"git", &"init"], Some(&sysroot_dir))?; + run_git_command(&"init", &[], Some(&sysroot_dir))?; println!("[GIT] add (cwd): `{}`", sysroot_dir.display()); - run_command(&[&"git", &"add", &"."], Some(&sysroot_dir))?; + run_git_command(&"add", &[&"."], Some(&sysroot_dir))?; println!("[GIT] commit (cwd): `{}`", sysroot_dir.display()); - // This is needed on systems where nothing is configured. - // git really needs something here, or it will fail. - // Even using --author is not enough. - run_command(&[&"git", &"config", &"user.email", &"none@example.com"], Some(&sysroot_dir))?; - run_command(&[&"git", &"config", &"user.name", &"None"], Some(&sysroot_dir))?; - run_command(&[&"git", &"config", &"core.autocrlf", &"false"], Some(&sysroot_dir))?; - run_command(&[&"git", &"config", &"commit.gpgSign", &"false"], Some(&sysroot_dir))?; - run_command(&[&"git", &"commit", &"-m", &"Initial commit", &"-q"], Some(&sysroot_dir))?; + run_git_command(&"commit", &[&"-m", &"Initial commit", &"-q"], Some(&sysroot_dir))?; let mut patches = Vec::new(); walk_dir( @@ -105,10 +135,11 @@ fn prepare_libcore( for file_path in patches { println!("[GIT] apply `{}`", file_path.display()); let path = Path::new("../../..").join(file_path); - run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?; - run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?; - run_command_with_output( - &[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())], + run_git_command_with_output(&"apply", &[&path], Some(&sysroot_dir))?; + run_git_command_with_output(&"add", &[&"-A"], Some(&sysroot_dir))?; + run_git_command_with_output( + &"commit", + &[&"-m", &format!("Patch {}", path.display())], Some(&sysroot_dir), )?; } @@ -124,10 +155,11 @@ fn prepare_rand() -> Result<(), String> { let rand_dir = Path::new("build/rand"); println!("[GIT] apply `{file_path}`"); let path = Path::new("../..").join(file_path); - run_command_with_output(&[&"git", &"apply", &path], Some(rand_dir))?; - run_command_with_output(&[&"git", &"add", &"-A"], Some(rand_dir))?; - run_command_with_output( - &[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())], + run_git_command_with_output(&"apply", &[&path], Some(rand_dir))?; + run_git_command_with_output(&"add", &[&"-A"], Some(rand_dir))?; + run_git_command_with_output( + &"commit", + &[&"-m", &format!("Patch {}", path.display())], Some(rand_dir), )?; @@ -154,8 +186,8 @@ where println!("`{}` has already been cloned", clone_result.repo_name); } let repo_path = Path::new(crate::BUILD_DIR).join(&clone_result.repo_name); - run_command(&[&"git", &"checkout", &"--", &"."], Some(&repo_path))?; - run_command(&[&"git", &"checkout", &checkout_commit], Some(&repo_path))?; + run_git_command(&"checkout", &[&"--", &"."], Some(&repo_path))?; + run_git_command(&"checkout", &[&checkout_commit], Some(&repo_path))?; if let Some(extra) = extra { extra(&repo_path)?; } diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 1823aa71f408e..dbdaf2a63ef29 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -910,6 +910,7 @@ fn test_rustc_inner( prepare_files_callback: F, run_error_pattern_test: bool, test_type: &str, + run_ignored_tests: bool, ) -> Result<(), String> where F: Fn(&Path) -> Result, @@ -944,17 +945,7 @@ where rust_path.join("tests/ui"), &mut |dir| { let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); - if [ - "abi", - "extern", - "unsized-locals", - "proc-macro", - "threads-sendsync", - "borrowck", - "test-attrs", - ] - .contains(&dir_name) - { + if ["abi", "extern", "proc-macro", "threads-sendsync"].contains(&dir_name) { remove_dir_all(dir).map_err(|error| { format!("Failed to remove folder `{}`: {:?}", dir.display(), error) })?; @@ -1061,30 +1052,34 @@ where env.get_mut("RUSTFLAGS").unwrap().clear(); - run_command_with_output_and_env( - &[ - &"./x.py", - &"test", - &"--run", - &"always", - &"--stage", - &"0", - &"--set", - &"build.compiletest-allow-stage0=true", - &format!("tests/{test_type}"), - &"--compiletest-rustc-args", - &rustc_args, - ], - Some(&rust_path), - Some(&env), - )?; + let test_dir = format!("tests/{test_type}"); + let mut command: Vec<&dyn AsRef> = vec![ + &"./x.py", + &"test", + &"--run", + &"always", + &"--stage", + &"0", + &"--set", + &"build.compiletest-allow-stage0=true", + &test_dir, + &"--compiletest-rustc-args", + &rustc_args, + ]; + + if run_ignored_tests { + command.push(&"--"); + command.push(&"--ignored"); + } + + run_command_with_output_and_env(&command, Some(&rust_path), Some(&env))?; Ok(()) } fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?; - test_rustc_inner(env, args, |_| Ok(false), false, "run-make-cargo")?; - test_rustc_inner(env, args, |_| Ok(false), false, "ui") + test_rustc_inner(env, args, |_| Ok(false), false, "run-make", false)?; + test_rustc_inner(env, args, |_| Ok(false), false, "run-make-cargo", false)?; + test_rustc_inner(env, args, |_| Ok(false), false, "ui", false) } fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { @@ -1094,6 +1089,7 @@ fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { retain_files_callback("tests/failing-run-make-tests.txt", "run-make"), false, "run-make", + true, ); let run_make_cargo_result = test_rustc_inner( @@ -1102,6 +1098,7 @@ fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { retain_files_callback("tests/failing-run-make-tests.txt", "run-make-cargo"), false, "run-make", + true, ); let ui_result = test_rustc_inner( @@ -1110,6 +1107,7 @@ fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { retain_files_callback("tests/failing-ui-tests.txt", "ui"), false, "ui", + true, ); run_make_result.and(run_make_cargo_result).and(ui_result) @@ -1122,6 +1120,7 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { remove_files_callback("tests/failing-ui-tests.txt", "ui"), false, "ui", + false, )?; test_rustc_inner( env, @@ -1129,6 +1128,7 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { remove_files_callback("tests/failing-run-make-tests.txt", "run-make"), false, "run-make", + false, )?; test_rustc_inner( env, @@ -1136,6 +1136,7 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { remove_files_callback("tests/failing-run-make-tests.txt", "run-make-cargo"), false, "run-make-cargo", + false, ) } @@ -1146,6 +1147,7 @@ fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String remove_files_callback("tests/failing-ice-tests.txt", "ui"), true, "ui", + false, ) } diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index fc948c54b24aa..112322f8688c1 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -112,8 +112,7 @@ pub fn run_command_with_output( cwd: Option<&Path>, ) -> Result<(), String> { let exit_status = exec_command(input, cwd, None)?; - check_exit_status(input, cwd, exit_status, None, true)?; - Ok(()) + check_exit_status(input, cwd, exit_status, None, true) } pub fn run_command_with_output_and_env( @@ -122,8 +121,7 @@ pub fn run_command_with_output_and_env( env: Option<&HashMap>, ) -> Result<(), String> { let exit_status = exec_command(input, cwd, env)?; - check_exit_status(input, cwd, exit_status, None, true)?; - Ok(()) + check_exit_status(input, cwd, exit_status, None, true) } #[cfg(not(unix))] @@ -133,8 +131,7 @@ pub fn run_command_with_output_and_env_no_err( env: Option<&HashMap>, ) -> Result<(), String> { let exit_status = exec_command(input, cwd, env)?; - check_exit_status(input, cwd, exit_status, None, false)?; - Ok(()) + check_exit_status(input, cwd, exit_status, None, false) } pub fn cargo_install(to_install: &str) -> Result<(), String> { diff --git a/example/mini_core.rs b/example/mini_core.rs index 9dfb12be24363..64a5b431bd07e 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -603,7 +603,7 @@ impl, U: ?Sized, A: Allocator> CoerceUnsized> fo impl Box { pub fn new(val: T) -> Box { unsafe { - let size = intrinsics::size_of::(); + let size = size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) @@ -657,11 +657,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn abort() -> !; #[rustc_intrinsic] - pub fn size_of() -> usize; + pub const fn size_of() -> usize; #[rustc_intrinsic] pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub fn align_of() -> usize; + pub const fn align_of() -> usize; #[rustc_intrinsic] pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] @@ -671,7 +671,7 @@ pub mod intrinsics { #[rustc_intrinsic] pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] - pub fn needs_drop() -> bool; + pub const fn needs_drop() -> bool; #[rustc_intrinsic] pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] @@ -699,6 +699,24 @@ pub mod libc { } } +pub const fn size_of() -> usize { + ::SIZE +} + +pub const fn align_of() -> usize { + ::ALIGN +} + +trait SizedTypeProperties: Sized { + #[lang = "mem_size_const"] + const SIZE: usize = intrinsics::size_of::(); + + #[lang = "mem_align_const"] + const ALIGN: usize = intrinsics::align_of::(); +} + +impl SizedTypeProperties for T {} + #[lang = "index"] pub trait Index { type Output: ?Sized; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 85489f850e248..d5c386ffb3dd1 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -90,8 +90,8 @@ fn start( ) -> isize { if argc == 3 { unsafe { puts(*argv); } - unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); } - unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); } + unsafe { puts(*((argv as usize + size_of::<*const u8>()) as *const *const u8)); } + unsafe { puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const u8)); } } main().report(); @@ -154,7 +154,7 @@ fn main() { let slice = &[0, 1] as &[i32]; let slice_ptr = slice as *const [i32] as *const i32; - let align = intrinsics::align_of::<*const i32>(); + let align = align_of::<*const i32>(); assert_eq!(slice_ptr as usize % align, 0); //return; @@ -195,11 +195,9 @@ fn main() { assert_eq!(intrinsics::size_of_val(a) as u8, 8); assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); - assert_eq!(intrinsics::align_of::() as u8, 2); - assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8); + assert_eq!(align_of::() as u8, 2); + assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8); - /* - * TODO: re-enable in the next sync. let u8_needs_drop = const { intrinsics::needs_drop::() }; assert!(!u8_needs_drop); let slice_needs_drop = const { intrinsics::needs_drop::<[u8]>() }; @@ -208,7 +206,6 @@ fn main() { assert!(noisy_drop); let noisy_unsized_drop = const { intrinsics::needs_drop::() }; assert!(noisy_unsized_drop); - */ Unique { pointer: 0 as *const &str, diff --git a/libgccjit.version b/libgccjit.version index dc9a00128646e..b8d4166542bcd 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -4e995bd73c4490edfe5080ec6014d63aa9abed5f +28b84db392ac0a572f1a2a2a1317aa5f2bc742cb diff --git a/rust-toolchain b/rust-toolchain index 04d33dfb116ce..9813bbea00c41 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-08-25" +channel = "nightly-2025-11-04" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/abi.rs b/src/abi.rs index 0b359f1c5c81b..93862a6b00ba7 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -88,7 +88,7 @@ impl GccType for Reg { 64 => cx.type_f64(), _ => bug!("unsupported float: {:?}", self), }, - RegKind::Vector => unimplemented!(), //cx.type_vector(cx.type_i8(), self.size.bytes()), + RegKind::Vector => cx.type_vector(cx.type_i8(), self.size.bytes()), } } } diff --git a/src/back/lto.rs b/src/back/lto.rs index 598bbe74007d0..404064fb7a060 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -21,6 +21,7 @@ use std::ffi::{CStr, CString}; use std::fs::{self, File}; use std::path::{Path, PathBuf}; use std::sync::Arc; +use std::sync::atomic::Ordering; use gccjit::{Context, OutputKind}; use object::read::archive::ArchiveFile; @@ -39,7 +40,7 @@ use tempfile::{TempDir, tempdir}; use crate::back::write::save_temp_bitcode; use crate::errors::LtoBitcodeFromRlib; -use crate::{GccCodegenBackend, GccContext, SyncContext, to_gcc_opt_level}; +use crate::{GccCodegenBackend, GccContext, LTO_SUPPORTED, LtoMode, SyncContext, to_gcc_opt_level}; struct LtoData { // TODO(antoyo): use symbols_below_threshold. @@ -229,7 +230,7 @@ fn fat_lto( info!("linking {:?}", name); match bc_decoded { SerializedModule::Local(ref module_buffer) => { - module.module_llvm.should_combine_object_files = true; + module.module_llvm.lto_mode = LtoMode::Fat; module .module_llvm .context @@ -534,7 +535,7 @@ pub fn optimize_thin_module( // that LLVM Context and Module. //let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); //let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &dcx)? as *const _; - let mut should_combine_object_files = false; + let mut lto_mode = LtoMode::None; let context = match thin_module.shared.thin_buffers.get(thin_module.idx) { Some(thin_buffer) => Arc::clone(&thin_buffer.context), None => { @@ -545,7 +546,7 @@ pub fn optimize_thin_module( SerializedModule::Local(ref module_buffer) => { let path = module_buffer.0.to_str().expect("path"); context.add_driver_option(path); - should_combine_object_files = true; + lto_mode = LtoMode::Thin; /*module.module_llvm.should_combine_object_files = true; module .module_llvm @@ -560,11 +561,13 @@ pub fn optimize_thin_module( Arc::new(SyncContext::new(context)) } }; + let lto_supported = LTO_SUPPORTED.load(Ordering::SeqCst); let module = ModuleCodegen::new_regular( thin_module.name().to_string(), GccContext { context, - should_combine_object_files, + lto_mode, + lto_supported, // TODO(antoyo): use the correct relocation model here. relocation_model: RelocModel::Pic, temp_dir: None, diff --git a/src/back/write.rs b/src/back/write.rs index 8ba730e325029..eae0f2aa00f6a 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -11,7 +11,7 @@ use rustc_target::spec::SplitDebuginfo; use crate::base::add_pic_option; use crate::errors::CopyBitcode; -use crate::{GccCodegenBackend, GccContext}; +use crate::{GccCodegenBackend, GccContext, LtoMode}; pub(crate) fn codegen( cgcx: &CodegenContext, @@ -25,12 +25,8 @@ pub(crate) fn codegen( { let context = &module.module_llvm.context; - let should_combine_object_files = module.module_llvm.should_combine_object_files; - - // NOTE: Only generate object files with GIMPLE when this environment variable is set for - // now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit). - // TODO(antoyo): remove this environment variable. - let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); + let lto_mode = module.module_llvm.lto_mode; + let lto_supported = module.module_llvm.lto_supported; let bc_out = cgcx.output_filenames.temp_path_for_cgu( OutputType::Bitcode, @@ -44,80 +40,46 @@ pub(crate) fn codegen( ); if config.bitcode_needed() { - if fat_lto { + let _timer = cgcx + .prof + .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); + + // TODO(antoyo) + /*if let Some(bitcode_filename) = bc_out.file_name() { + cgcx.prof.artifact_size( + "llvm_bitcode", + bitcode_filename.to_string_lossy(), + data.len() as u64, + ); + }*/ + + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { let _timer = cgcx .prof - .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); - - // TODO(antoyo) - /*if let Some(bitcode_filename) = bc_out.file_name() { - cgcx.prof.artifact_size( - "llvm_bitcode", - bitcode_filename.to_string_lossy(), - data.len() as u64, - ); - }*/ - - if config.emit_bc || config.emit_obj == EmitObj::Bitcode { - let _timer = cgcx.prof.generic_activity_with_arg( - "GCC_module_codegen_emit_bitcode", - &*module.name, - ); + .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name); + if lto_supported { context.add_command_line_option("-flto=auto"); context.add_command_line_option("-flto-partition=one"); - // TODO(antoyo): remove since we don't want fat objects when it is for Bitcode only. - context.add_command_line_option("-ffat-lto-objects"); - context.compile_to_file( - OutputKind::ObjectFile, - bc_out.to_str().expect("path to str"), - ); } + context + .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); + } - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - let _timer = cgcx.prof.generic_activity_with_arg( - "GCC_module_codegen_embed_bitcode", - &*module.name, - ); + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + let _timer = cgcx + .prof + .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name); + if lto_supported { // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); context.add_command_line_option("-flto=auto"); context.add_command_line_option("-flto-partition=one"); context.add_command_line_option("-ffat-lto-objects"); - // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). - context.compile_to_file( - OutputKind::ObjectFile, - bc_out.to_str().expect("path to str"), - ); - } - } else { - if config.emit_bc || config.emit_obj == EmitObj::Bitcode { - let _timer = cgcx.prof.generic_activity_with_arg( - "GCC_module_codegen_emit_bitcode", - &*module.name, - ); - context.compile_to_file( - OutputKind::ObjectFile, - bc_out.to_str().expect("path to str"), - ); - } - - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - // TODO(antoyo): we might want to emit to emit an error here, saying to set the - // environment variable EMBED_LTO_BITCODE. - let _timer = cgcx.prof.generic_activity_with_arg( - "GCC_module_codegen_embed_bitcode", - &*module.name, - ); - // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? - //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); - - // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). - context.compile_to_file( - OutputKind::ObjectFile, - bc_out.to_str().expect("path to str"), - ); } + // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). + context + .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); } } @@ -166,7 +128,10 @@ pub(crate) fn codegen( context.set_debug_info(true); context.dump_to_file(path, true); } - if should_combine_object_files { + if lto_mode != LtoMode::None { + let fat_lto = lto_mode == LtoMode::Fat; + // We need to check if we're doing LTO since this code is also used for the + // dummy ThinLTO implementation to combine the object files. if fat_lto { context.add_command_line_option("-flto=auto"); context.add_command_line_option("-flto-partition=one"); diff --git a/src/base.rs b/src/base.rs index e8672f49580b6..7cf3a2375879c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -21,7 +21,7 @@ use rustc_target::spec::SymbolVisibility; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::{GccContext, LockedTargetInfo, SyncContext, gcc_util, new_context}; +use crate::{GccContext, LockedTargetInfo, LtoMode, SyncContext, gcc_util, new_context}; #[cfg(feature = "master")] pub fn visibility_to_gcc(visibility: Visibility) -> gccjit::Visibility { @@ -74,6 +74,7 @@ pub fn compile_codegen_unit( tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: LockedTargetInfo, + lto_supported: bool, ) -> (ModuleCodegen, u64) { let prof_timer = tcx.prof.generic_activity("codegen_module"); let start_time = Instant::now(); @@ -82,7 +83,7 @@ pub fn compile_codegen_unit( let (module, _) = tcx.dep_graph.with_task( dep_node, tcx, - (cgu_name, target_info), + (cgu_name, target_info, lto_supported), module_codegen, Some(dep_graph::hash_result), ); @@ -95,7 +96,7 @@ pub fn compile_codegen_unit( fn module_codegen( tcx: TyCtxt<'_>, - (cgu_name, target_info): (Symbol, LockedTargetInfo), + (cgu_name, target_info, lto_supported): (Symbol, LockedTargetInfo, bool), ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... @@ -247,7 +248,8 @@ pub fn compile_codegen_unit( GccContext { context: Arc::new(SyncContext::new(context)), relocation_model: tcx.sess.relocation_model(), - should_combine_object_files: false, + lto_supported, + lto_mode: LtoMode::None, temp_dir: None, }, ) diff --git a/src/builder.rs b/src/builder.rs index 5657620879ca1..481b12d842f44 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -668,32 +668,38 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn add(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_add(a, b) + self.assign_to_var(self.gcc_add(a, b)) } fn fadd(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - a + b + self.assign_to_var(a + b) } // TODO(antoyo): should we also override the `unchecked_` versions? fn sub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_sub(a, b) + self.assign_to_var(self.gcc_sub(a, b)) } fn fsub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - a - b + self.assign_to_var(a - b) } fn mul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_mul(a, b) + self.assign_to_var(self.gcc_mul(a, b)) } fn fmul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.cx.context.new_binary_op(self.location, BinaryOp::Mult, a.get_type(), a, b) + self.assign_to_var(self.cx.context.new_binary_op( + self.location, + BinaryOp::Mult, + a.get_type(), + a, + b, + )) } fn udiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_udiv(a, b) + self.assign_to_var(self.gcc_udiv(a, b)) } fn exactudiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -702,11 +708,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let a = self.gcc_int_cast(a, a_type); let b_type = b.get_type().to_unsigned(self); let b = self.gcc_int_cast(b, b_type); - self.gcc_udiv(a, b) + self.assign_to_var(self.gcc_udiv(a, b)) } fn sdiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_sdiv(a, b) + self.assign_to_var(self.gcc_sdiv(a, b)) } fn exactsdiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -715,19 +721,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // should be the same. let typ = a.get_type().to_signed(self); let b = self.gcc_int_cast(b, typ); - self.gcc_sdiv(a, b) + self.assign_to_var(self.gcc_sdiv(a, b)) } fn fdiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - a / b + self.assign_to_var(a / b) } fn urem(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_urem(a, b) + self.assign_to_var(self.gcc_urem(a, b)) } fn srem(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_srem(a, b) + self.assign_to_var(self.gcc_srem(a, b)) } fn frem(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -865,22 +871,26 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn fadd_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - set_rvalue_location(self, lhs + rhs) + let result = set_rvalue_location(self, lhs + rhs); + self.assign_to_var(result) } fn fsub_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - set_rvalue_location(self, lhs - rhs) + let result = set_rvalue_location(self, lhs - rhs); + self.assign_to_var(result) } fn fmul_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - set_rvalue_location(self, lhs * rhs) + let result = set_rvalue_location(self, lhs * rhs); + self.assign_to_var(result) } fn fdiv_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - set_rvalue_location(self, lhs / rhs) + let result = set_rvalue_location(self, lhs / rhs); + self.assign_to_var(result) } fn frem_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { @@ -892,22 +902,22 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn fadd_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs + rhs + self.assign_to_var(lhs + rhs) } fn fsub_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs - rhs + self.assign_to_var(lhs - rhs) } fn fmul_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs * rhs + self.assign_to_var(lhs * rhs) } fn fdiv_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs / rhs + self.assign_to_var(lhs / rhs) } fn frem_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { @@ -2409,6 +2419,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let res = then_vals | else_vals; self.bitcast_if_needed(res, result_type) } + + // GCC doesn't like deeply nested expressions. + // By assigning intermediate expressions to a variable, this allow us to avoid deeply nested + // expressions and GCC will use much less RAM. + fn assign_to_var(&self, value: RValue<'gcc>) -> RValue<'gcc> { + let var = self.current_func().new_local(self.location, value.get_type(), "opResult"); + self.llbb().add_assignment(self.location, var, value); + var.to_rvalue() + } } fn difference_or_zero<'gcc>( diff --git a/src/int.rs b/src/int.rs index 9fb7f6bad6844..aa1d3b6b091c6 100644 --- a/src/int.rs +++ b/src/int.rs @@ -83,12 +83,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let a_size = a_type.get_size(); let b_size = b_type.get_size(); match a_size.cmp(&b_size) { - std::cmp::Ordering::Less => { - let a = self.context.new_cast(self.location, a, b_type); - a >> b - } std::cmp::Ordering::Equal => a >> b, - std::cmp::Ordering::Greater => { + _ => { + // NOTE: it is OK to cast even if b has a type bigger than a because b has + // been masked by codegen_ssa before calling Builder::lshr or + // Builder::ashr. let b = self.context.new_cast(self.location, b, a_type); a >> b } @@ -692,12 +691,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let a_size = a_type.get_size(); let b_size = b_type.get_size(); match a_size.cmp(&b_size) { - std::cmp::Ordering::Less => { - let a = self.context.new_cast(self.location, a, b_type); - a << b - } std::cmp::Ordering::Equal => a << b, - std::cmp::Ordering::Greater => { + _ => { + // NOTE: it is OK to cast even if b has a type bigger than a because b has + // been masked by codegen_ssa before calling Builder::shl. let b = self.context.new_cast(self.location, b, a_type); a << b } diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index d1b2a93243d27..c51bcbcedd677 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -85,12 +85,41 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { fn amdgcn(name: &str, full_name: &str) -> &'static str { match name { // amdgcn + "add.max.i32" => "__builtin_amdgcn_add_max_i32", + "add.max.u32" => "__builtin_amdgcn_add_max_u32", + "add.min.i32" => "__builtin_amdgcn_add_min_i32", + "add.min.u32" => "__builtin_amdgcn_add_min_u32", "alignbyte" => "__builtin_amdgcn_alignbyte", "ashr.pk.i8.i32" => "__builtin_amdgcn_ashr_pk_i8_i32", "ashr.pk.u8.i32" => "__builtin_amdgcn_ashr_pk_u8_i32", "buffer.wbinvl1" => "__builtin_amdgcn_buffer_wbinvl1", "buffer.wbinvl1.sc" => "__builtin_amdgcn_buffer_wbinvl1_sc", "buffer.wbinvl1.vol" => "__builtin_amdgcn_buffer_wbinvl1_vol", + "cluster.id.x" => "__builtin_amdgcn_cluster_id_x", + "cluster.id.y" => "__builtin_amdgcn_cluster_id_y", + "cluster.id.z" => "__builtin_amdgcn_cluster_id_z", + "cluster.load.async.to.lds.b128" => { + "__builtin_amdgcn_cluster_load_async_to_lds_b128" + } + "cluster.load.async.to.lds.b32" => { + "__builtin_amdgcn_cluster_load_async_to_lds_b32" + } + "cluster.load.async.to.lds.b64" => { + "__builtin_amdgcn_cluster_load_async_to_lds_b64" + } + "cluster.load.async.to.lds.b8" => { + "__builtin_amdgcn_cluster_load_async_to_lds_b8" + } + "cluster.workgroup.flat.id" => "__builtin_amdgcn_cluster_workgroup_flat_id", + "cluster.workgroup.id.x" => "__builtin_amdgcn_cluster_workgroup_id_x", + "cluster.workgroup.id.y" => "__builtin_amdgcn_cluster_workgroup_id_y", + "cluster.workgroup.id.z" => "__builtin_amdgcn_cluster_workgroup_id_z", + "cluster.workgroup.max.flat.id" => { + "__builtin_amdgcn_cluster_workgroup_max_flat_id" + } + "cluster.workgroup.max.id.x" => "__builtin_amdgcn_cluster_workgroup_max_id_x", + "cluster.workgroup.max.id.y" => "__builtin_amdgcn_cluster_workgroup_max_id_y", + "cluster.workgroup.max.id.z" => "__builtin_amdgcn_cluster_workgroup_max_id_z", "cubeid" => "__builtin_amdgcn_cubeid", "cubema" => "__builtin_amdgcn_cubema", "cubesc" => "__builtin_amdgcn_cubesc", @@ -101,18 +130,36 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "cvt.f32.fp8" => "__builtin_amdgcn_cvt_f32_fp8", "cvt.f32.fp8.e5m3" => "__builtin_amdgcn_cvt_f32_fp8_e5m3", "cvt.off.f32.i4" => "__builtin_amdgcn_cvt_off_f32_i4", + "cvt.pk.bf8.f16" => "__builtin_amdgcn_cvt_pk_bf8_f16", "cvt.pk.bf8.f32" => "__builtin_amdgcn_cvt_pk_bf8_f32", "cvt.pk.f16.bf8" => "__builtin_amdgcn_cvt_pk_f16_bf8", "cvt.pk.f16.fp8" => "__builtin_amdgcn_cvt_pk_f16_fp8", "cvt.pk.f32.bf8" => "__builtin_amdgcn_cvt_pk_f32_bf8", "cvt.pk.f32.fp8" => "__builtin_amdgcn_cvt_pk_f32_fp8", + "cvt.pk.fp8.f16" => "__builtin_amdgcn_cvt_pk_fp8_f16", "cvt.pk.fp8.f32" => "__builtin_amdgcn_cvt_pk_fp8_f32", + "cvt.pk.fp8.f32.e5m3" => "__builtin_amdgcn_cvt_pk_fp8_f32_e5m3", "cvt.pk.i16" => "__builtin_amdgcn_cvt_pk_i16", "cvt.pk.u16" => "__builtin_amdgcn_cvt_pk_u16", "cvt.pk.u8.f32" => "__builtin_amdgcn_cvt_pk_u8_f32", "cvt.pknorm.i16" => "__builtin_amdgcn_cvt_pknorm_i16", "cvt.pknorm.u16" => "__builtin_amdgcn_cvt_pknorm_u16", "cvt.pkrtz" => "__builtin_amdgcn_cvt_pkrtz", + "cvt.scale.pk16.bf16.bf6" => "__builtin_amdgcn_cvt_scale_pk16_bf16_bf6", + "cvt.scale.pk16.bf16.fp6" => "__builtin_amdgcn_cvt_scale_pk16_bf16_fp6", + "cvt.scale.pk16.f16.bf6" => "__builtin_amdgcn_cvt_scale_pk16_f16_bf6", + "cvt.scale.pk16.f16.fp6" => "__builtin_amdgcn_cvt_scale_pk16_f16_fp6", + "cvt.scale.pk16.f32.bf6" => "__builtin_amdgcn_cvt_scale_pk16_f32_bf6", + "cvt.scale.pk16.f32.fp6" => "__builtin_amdgcn_cvt_scale_pk16_f32_fp6", + "cvt.scale.pk8.bf16.bf8" => "__builtin_amdgcn_cvt_scale_pk8_bf16_bf8", + "cvt.scale.pk8.bf16.fp4" => "__builtin_amdgcn_cvt_scale_pk8_bf16_fp4", + "cvt.scale.pk8.bf16.fp8" => "__builtin_amdgcn_cvt_scale_pk8_bf16_fp8", + "cvt.scale.pk8.f16.bf8" => "__builtin_amdgcn_cvt_scale_pk8_f16_bf8", + "cvt.scale.pk8.f16.fp4" => "__builtin_amdgcn_cvt_scale_pk8_f16_fp4", + "cvt.scale.pk8.f16.fp8" => "__builtin_amdgcn_cvt_scale_pk8_f16_fp8", + "cvt.scale.pk8.f32.bf8" => "__builtin_amdgcn_cvt_scale_pk8_f32_bf8", + "cvt.scale.pk8.f32.fp4" => "__builtin_amdgcn_cvt_scale_pk8_f32_fp4", + "cvt.scale.pk8.f32.fp8" => "__builtin_amdgcn_cvt_scale_pk8_f32_fp8", "cvt.scalef32.2xpk16.bf6.f32" => "__builtin_amdgcn_cvt_scalef32_2xpk16_bf6_f32", "cvt.scalef32.2xpk16.fp6.f32" => "__builtin_amdgcn_cvt_scalef32_2xpk16_fp6_f32", "cvt.scalef32.f16.bf8" => "__builtin_amdgcn_cvt_scalef32_f16_bf8", @@ -137,6 +184,12 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "cvt.scalef32.pk.fp8.bf16" => "__builtin_amdgcn_cvt_scalef32_pk_fp8_bf16", "cvt.scalef32.pk.fp8.f16" => "__builtin_amdgcn_cvt_scalef32_pk_fp8_f16", "cvt.scalef32.pk.fp8.f32" => "__builtin_amdgcn_cvt_scalef32_pk_fp8_f32", + "cvt.scalef32.pk16.bf6.bf16" => "__builtin_amdgcn_cvt_scalef32_pk16_bf6_bf16", + "cvt.scalef32.pk16.bf6.f16" => "__builtin_amdgcn_cvt_scalef32_pk16_bf6_f16", + "cvt.scalef32.pk16.bf6.f32" => "__builtin_amdgcn_cvt_scalef32_pk16_bf6_f32", + "cvt.scalef32.pk16.fp6.bf16" => "__builtin_amdgcn_cvt_scalef32_pk16_fp6_bf16", + "cvt.scalef32.pk16.fp6.f16" => "__builtin_amdgcn_cvt_scalef32_pk16_fp6_f16", + "cvt.scalef32.pk16.fp6.f32" => "__builtin_amdgcn_cvt_scalef32_pk16_fp6_f32", "cvt.scalef32.pk32.bf16.bf6" => "__builtin_amdgcn_cvt_scalef32_pk32_bf16_bf6", "cvt.scalef32.pk32.bf16.fp6" => "__builtin_amdgcn_cvt_scalef32_pk32_bf16_fp6", "cvt.scalef32.pk32.bf6.bf16" => "__builtin_amdgcn_cvt_scalef32_pk32_bf6_bf16", @@ -147,6 +200,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "cvt.scalef32.pk32.f32.fp6" => "__builtin_amdgcn_cvt_scalef32_pk32_f32_fp6", "cvt.scalef32.pk32.fp6.bf16" => "__builtin_amdgcn_cvt_scalef32_pk32_fp6_bf16", "cvt.scalef32.pk32.fp6.f16" => "__builtin_amdgcn_cvt_scalef32_pk32_fp6_f16", + "cvt.scalef32.pk8.bf8.bf16" => "__builtin_amdgcn_cvt_scalef32_pk8_bf8_bf16", + "cvt.scalef32.pk8.bf8.f16" => "__builtin_amdgcn_cvt_scalef32_pk8_bf8_f16", + "cvt.scalef32.pk8.bf8.f32" => "__builtin_amdgcn_cvt_scalef32_pk8_bf8_f32", + "cvt.scalef32.pk8.fp4.bf16" => "__builtin_amdgcn_cvt_scalef32_pk8_fp4_bf16", + "cvt.scalef32.pk8.fp4.f16" => "__builtin_amdgcn_cvt_scalef32_pk8_fp4_f16", + "cvt.scalef32.pk8.fp4.f32" => "__builtin_amdgcn_cvt_scalef32_pk8_fp4_f32", + "cvt.scalef32.pk8.fp8.bf16" => "__builtin_amdgcn_cvt_scalef32_pk8_fp8_bf16", + "cvt.scalef32.pk8.fp8.f16" => "__builtin_amdgcn_cvt_scalef32_pk8_fp8_f16", + "cvt.scalef32.pk8.fp8.f32" => "__builtin_amdgcn_cvt_scalef32_pk8_fp8_f32", "cvt.scalef32.sr.bf8.bf16" => "__builtin_amdgcn_cvt_scalef32_sr_bf8_bf16", "cvt.scalef32.sr.bf8.f16" => "__builtin_amdgcn_cvt_scalef32_sr_bf8_f16", "cvt.scalef32.sr.bf8.f32" => "__builtin_amdgcn_cvt_scalef32_sr_bf8_f32", @@ -156,6 +218,24 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "cvt.scalef32.sr.pk.fp4.bf16" => "__builtin_amdgcn_cvt_scalef32_sr_pk_fp4_bf16", "cvt.scalef32.sr.pk.fp4.f16" => "__builtin_amdgcn_cvt_scalef32_sr_pk_fp4_f16", "cvt.scalef32.sr.pk.fp4.f32" => "__builtin_amdgcn_cvt_scalef32_sr_pk_fp4_f32", + "cvt.scalef32.sr.pk16.bf6.bf16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_bf6_bf16" + } + "cvt.scalef32.sr.pk16.bf6.f16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_bf6_f16" + } + "cvt.scalef32.sr.pk16.bf6.f32" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_bf6_f32" + } + "cvt.scalef32.sr.pk16.fp6.bf16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_fp6_bf16" + } + "cvt.scalef32.sr.pk16.fp6.f16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_fp6_f16" + } + "cvt.scalef32.sr.pk16.fp6.f32" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk16_fp6_f32" + } "cvt.scalef32.sr.pk32.bf6.bf16" => { "__builtin_amdgcn_cvt_scalef32_sr_pk32_bf6_bf16" } @@ -174,10 +254,30 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "cvt.scalef32.sr.pk32.fp6.f32" => { "__builtin_amdgcn_cvt_scalef32_sr_pk32_fp6_f32" } + "cvt.scalef32.sr.pk8.bf8.bf16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk8_bf8_bf16" + } + "cvt.scalef32.sr.pk8.bf8.f16" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_bf8_f16", + "cvt.scalef32.sr.pk8.bf8.f32" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_bf8_f32", + "cvt.scalef32.sr.pk8.fp4.bf16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp4_bf16" + } + "cvt.scalef32.sr.pk8.fp4.f16" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp4_f16", + "cvt.scalef32.sr.pk8.fp4.f32" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp4_f32", + "cvt.scalef32.sr.pk8.fp8.bf16" => { + "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp8_bf16" + } + "cvt.scalef32.sr.pk8.fp8.f16" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp8_f16", + "cvt.scalef32.sr.pk8.fp8.f32" => "__builtin_amdgcn_cvt_scalef32_sr_pk8_fp8_f32", "cvt.sr.bf16.f32" => "__builtin_amdgcn_cvt_sr_bf16_f32", + "cvt.sr.bf8.f16" => "__builtin_amdgcn_cvt_sr_bf8_f16", "cvt.sr.bf8.f32" => "__builtin_amdgcn_cvt_sr_bf8_f32", "cvt.sr.f16.f32" => "__builtin_amdgcn_cvt_sr_f16_f32", + "cvt.sr.fp8.f16" => "__builtin_amdgcn_cvt_sr_fp8_f16", "cvt.sr.fp8.f32" => "__builtin_amdgcn_cvt_sr_fp8_f32", + "cvt.sr.fp8.f32.e5m3" => "__builtin_amdgcn_cvt_sr_fp8_f32_e5m3", + "cvt.sr.pk.bf16.f32" => "__builtin_amdgcn_cvt_sr_pk_bf16_f32", + "cvt.sr.pk.f16.f32" => "__builtin_amdgcn_cvt_sr_pk_f16_f32", "dispatch.id" => "__builtin_amdgcn_dispatch_id", "dot4.f32.bf8.bf8" => "__builtin_amdgcn_dot4_f32_bf8_bf8", "dot4.f32.bf8.fp8" => "__builtin_amdgcn_dot4_f32_bf8_fp8", @@ -297,8 +397,20 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "mqsad.u32.u8" => "__builtin_amdgcn_mqsad_u32_u8", "msad.u8" => "__builtin_amdgcn_msad_u8", "perm" => "__builtin_amdgcn_perm", + "perm.pk16.b4.u4" => "__builtin_amdgcn_perm_pk16_b4_u4", + "perm.pk16.b6.u4" => "__builtin_amdgcn_perm_pk16_b6_u4", + "perm.pk16.b8.u4" => "__builtin_amdgcn_perm_pk16_b8_u4", + "permlane.bcast" => "__builtin_amdgcn_permlane_bcast", + "permlane.down" => "__builtin_amdgcn_permlane_down", + "permlane.idx.gen" => "__builtin_amdgcn_permlane_idx_gen", + "permlane.up" => "__builtin_amdgcn_permlane_up", + "permlane.xor" => "__builtin_amdgcn_permlane_xor", "permlane16.var" => "__builtin_amdgcn_permlane16_var", "permlanex16.var" => "__builtin_amdgcn_permlanex16_var", + "pk.add.max.i16" => "__builtin_amdgcn_pk_add_max_i16", + "pk.add.max.u16" => "__builtin_amdgcn_pk_add_max_u16", + "pk.add.min.i16" => "__builtin_amdgcn_pk_add_min_i16", + "pk.add.min.u16" => "__builtin_amdgcn_pk_add_min_u16", "prng.b32" => "__builtin_amdgcn_prng_b32", "qsad.pk.u16.u8" => "__builtin_amdgcn_qsad_pk_u16_u8", "queue.ptr" => "__builtin_amdgcn_queue_ptr", @@ -306,11 +418,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "rcp.legacy" => "__builtin_amdgcn_rcp_legacy", "rsq.legacy" => "__builtin_amdgcn_rsq_legacy", "s.barrier" => "__builtin_amdgcn_s_barrier", + "s.barrier.init" => "__builtin_amdgcn_s_barrier_init", + "s.barrier.join" => "__builtin_amdgcn_s_barrier_join", + "s.barrier.leave" => "__builtin_amdgcn_s_barrier_leave", "s.barrier.signal" => "__builtin_amdgcn_s_barrier_signal", "s.barrier.signal.isfirst" => "__builtin_amdgcn_s_barrier_signal_isfirst", "s.barrier.signal.var" => "__builtin_amdgcn_s_barrier_signal_var", "s.barrier.wait" => "__builtin_amdgcn_s_barrier_wait", "s.buffer.prefetch.data" => "__builtin_amdgcn_s_buffer_prefetch_data", + "s.cluster.barrier" => "__builtin_amdgcn_s_cluster_barrier", "s.dcache.inv" => "__builtin_amdgcn_s_dcache_inv", "s.dcache.inv.vol" => "__builtin_amdgcn_s_dcache_inv_vol", "s.dcache.wb" => "__builtin_amdgcn_s_dcache_wb", @@ -1900,6 +2016,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vfneg.hf.128B" => "__builtin_HEXAGON_V6_vfneg_hf_128B", "V6.vfneg.sf" => "__builtin_HEXAGON_V6_vfneg_sf", "V6.vfneg.sf.128B" => "__builtin_HEXAGON_V6_vfneg_sf_128B", + "V6.vgather.vscattermh" => "__builtin_HEXAGON_V6_vgather_vscattermh", + "V6.vgather.vscattermh.128B" => "__builtin_HEXAGON_V6_vgather_vscattermh_128B", "V6.vgathermh" => "__builtin_HEXAGON_V6_vgathermh", "V6.vgathermh.128B" => "__builtin_HEXAGON_V6_vgathermh_128B", "V6.vgathermhq" => "__builtin_HEXAGON_V6_vgathermhq", @@ -2382,6 +2500,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vsub.hf.f8.128B" => "__builtin_HEXAGON_V6_vsub_hf_f8_128B", "V6.vsub.hf.hf" => "__builtin_HEXAGON_V6_vsub_hf_hf", "V6.vsub.hf.hf.128B" => "__builtin_HEXAGON_V6_vsub_hf_hf_128B", + "V6.vsub.hf.mix" => "__builtin_HEXAGON_V6_vsub_hf_mix", + "V6.vsub.hf.mix.128B" => "__builtin_HEXAGON_V6_vsub_hf_mix_128B", "V6.vsub.qf16" => "__builtin_HEXAGON_V6_vsub_qf16", "V6.vsub.qf16.128B" => "__builtin_HEXAGON_V6_vsub_qf16_128B", "V6.vsub.qf16.mix" => "__builtin_HEXAGON_V6_vsub_qf16_mix", @@ -2396,6 +2516,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vsub.sf.bf.128B" => "__builtin_HEXAGON_V6_vsub_sf_bf_128B", "V6.vsub.sf.hf" => "__builtin_HEXAGON_V6_vsub_sf_hf", "V6.vsub.sf.hf.128B" => "__builtin_HEXAGON_V6_vsub_sf_hf_128B", + "V6.vsub.sf.mix" => "__builtin_HEXAGON_V6_vsub_sf_mix", + "V6.vsub.sf.mix.128B" => "__builtin_HEXAGON_V6_vsub_sf_mix_128B", "V6.vsub.sf.sf" => "__builtin_HEXAGON_V6_vsub_sf_sf", "V6.vsub.sf.sf.128B" => "__builtin_HEXAGON_V6_vsub_sf_sf_128B", "V6.vsubb" => "__builtin_HEXAGON_V6_vsubb", @@ -4883,6 +5005,26 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "f2ull.rp.ftz" => "__nvvm_f2ull_rp_ftz", "f2ull.rz" => "__nvvm_f2ull_rz", "f2ull.rz.ftz" => "__nvvm_f2ull_rz_ftz", + "f32x4.to.e2m1x4.rs.relu.satfinite" => { + "__nvvm_f32x4_to_e2m1x4_rs_relu_satfinite" + } + "f32x4.to.e2m1x4.rs.satfinite" => "__nvvm_f32x4_to_e2m1x4_rs_satfinite", + "f32x4.to.e2m3x4.rs.relu.satfinite" => { + "__nvvm_f32x4_to_e2m3x4_rs_relu_satfinite" + } + "f32x4.to.e2m3x4.rs.satfinite" => "__nvvm_f32x4_to_e2m3x4_rs_satfinite", + "f32x4.to.e3m2x4.rs.relu.satfinite" => { + "__nvvm_f32x4_to_e3m2x4_rs_relu_satfinite" + } + "f32x4.to.e3m2x4.rs.satfinite" => "__nvvm_f32x4_to_e3m2x4_rs_satfinite", + "f32x4.to.e4m3x4.rs.relu.satfinite" => { + "__nvvm_f32x4_to_e4m3x4_rs_relu_satfinite" + } + "f32x4.to.e4m3x4.rs.satfinite" => "__nvvm_f32x4_to_e4m3x4_rs_satfinite", + "f32x4.to.e5m2x4.rs.relu.satfinite" => { + "__nvvm_f32x4_to_e5m2x4_rs_relu_satfinite" + } + "f32x4.to.e5m2x4.rs.satfinite" => "__nvvm_f32x4_to_e5m2x4_rs_satfinite", "fabs.d" => "__nvvm_fabs_d", "fabs.f" => "__nvvm_fabs_f", "fabs.ftz.f" => "__nvvm_fabs_ftz_f", @@ -4902,10 +5044,18 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ff.to.ue8m0x2.rz.satfinite" => "__nvvm_ff_to_ue8m0x2_rz_satfinite", "ff2bf16x2.rn" => "__nvvm_ff2bf16x2_rn", "ff2bf16x2.rn.relu" => "__nvvm_ff2bf16x2_rn_relu", + "ff2bf16x2.rs" => "__nvvm_ff2bf16x2_rs", + "ff2bf16x2.rs.relu" => "__nvvm_ff2bf16x2_rs_relu", + "ff2bf16x2.rs.relu.satfinite" => "__nvvm_ff2bf16x2_rs_relu_satfinite", + "ff2bf16x2.rs.satfinite" => "__nvvm_ff2bf16x2_rs_satfinite", "ff2bf16x2.rz" => "__nvvm_ff2bf16x2_rz", "ff2bf16x2.rz.relu" => "__nvvm_ff2bf16x2_rz_relu", "ff2f16x2.rn" => "__nvvm_ff2f16x2_rn", "ff2f16x2.rn.relu" => "__nvvm_ff2f16x2_rn_relu", + "ff2f16x2.rs" => "__nvvm_ff2f16x2_rs", + "ff2f16x2.rs.relu" => "__nvvm_ff2f16x2_rs_relu", + "ff2f16x2.rs.relu.satfinite" => "__nvvm_ff2f16x2_rs_relu_satfinite", + "ff2f16x2.rs.satfinite" => "__nvvm_ff2f16x2_rs_satfinite", "ff2f16x2.rz" => "__nvvm_ff2f16x2_rz", "ff2f16x2.rz.relu" => "__nvvm_ff2f16x2_rz_relu", "floor.d" => "__nvvm_floor_d", @@ -5129,6 +5279,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "read.ptx.sreg.envreg8" => "__nvvm_read_ptx_sreg_envreg8", "read.ptx.sreg.envreg9" => "__nvvm_read_ptx_sreg_envreg9", "read.ptx.sreg.globaltimer" => "__nvvm_read_ptx_sreg_globaltimer", + "read.ptx.sreg.globaltimer.lo" => "__nvvm_read_ptx_sreg_globaltimer_lo", "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_gridid", // [DUPLICATE]: "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_laneid", @@ -5803,6 +5954,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "altivec.vupklsw" => "__builtin_altivec_vupklsw", "bcdadd" => "__builtin_ppc_bcdadd", "bcdadd.p" => "__builtin_ppc_bcdadd_p", + "bcdcopysign" => "__builtin_ppc_bcdcopysign", + "bcdsetsign" => "__builtin_ppc_bcdsetsign", "bcdsub" => "__builtin_ppc_bcdsub", "bcdsub.p" => "__builtin_ppc_bcdsub_p", "bpermd" => "__builtin_bpermd", @@ -6160,6 +6313,9 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "aes64im" => "__builtin_riscv_aes64im", "aes64ks1i" => "__builtin_riscv_aes64ks1i", "aes64ks2" => "__builtin_riscv_aes64ks2", + "mips.ehb" => "__builtin_riscv_mips_ehb", + "mips.ihb" => "__builtin_riscv_mips_ihb", + "mips.pause" => "__builtin_riscv_mips_pause", "sha512sig0" => "__builtin_riscv_sha512sig0", "sha512sig0h" => "__builtin_riscv_sha512sig0h", "sha512sig0l" => "__builtin_riscv_sha512sig0l", diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 99a4f9b9f7e7e..8225df5686417 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -308,10 +308,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc .or_else(|| get_simple_function_f128(self, name)) .or_else(|| get_simple_function_f128_2args(self, name)); - // FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved: - // https://github.com/rust-lang/rust-clippy/issues/12497 - // and leave `else if use_integer_compare` to be placed "as is". - #[allow(clippy::suspicious_else_formatting)] let value = match name { _ if simple.is_some() => { let func = simple.expect("simple intrinsic function"); diff --git a/src/lib.rs b/src/lib.rs index 71500ded02038..5d84ba854bb3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,10 +75,7 @@ use std::any::Any; use std::fmt::Debug; use std::ops::Deref; use std::path::PathBuf; -#[cfg(not(feature = "master"))] -use std::sync::atomic::AtomicBool; -#[cfg(not(feature = "master"))] -use std::sync::atomic::Ordering; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use back::lto::{ThinBuffer, ThinData}; @@ -170,8 +167,11 @@ impl LockedTargetInfo { #[derive(Clone)] pub struct GccCodegenBackend { target_info: LockedTargetInfo, + lto_supported: Arc, } +static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); + impl CodegenBackend for GccCodegenBackend { fn locale_resource(&self) -> &'static str { crate::DEFAULT_LOCALE_RESOURCE @@ -196,7 +196,13 @@ impl CodegenBackend for GccCodegenBackend { } #[cfg(feature = "master")] - gccjit::set_global_personality_function_name(b"rust_eh_personality\0"); + { + let lto_supported = gccjit::is_lto_supported(); + LTO_SUPPORTED.store(lto_supported, Ordering::SeqCst); + self.lto_supported.store(lto_supported, Ordering::SeqCst); + + gccjit::set_global_personality_function_name(b"rust_eh_personality\0"); + } #[cfg(not(feature = "master"))] { @@ -279,10 +285,12 @@ impl ExtraBackendMethods for GccCodegenBackend { module_name: &str, methods: &[AllocatorMethod], ) -> Self::Module { + let lto_supported = self.lto_supported.load(Ordering::SeqCst); let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), relocation_model: tcx.sess.relocation_model(), - should_combine_object_files: false, + lto_mode: LtoMode::None, + lto_supported, temp_dir: None, }; @@ -297,7 +305,12 @@ impl ExtraBackendMethods for GccCodegenBackend { tcx: TyCtxt<'_>, cgu_name: Symbol, ) -> (ModuleCodegen, u64) { - base::compile_codegen_unit(tcx, cgu_name, self.target_info.clone()) + base::compile_codegen_unit( + tcx, + cgu_name, + self.target_info.clone(), + self.lto_supported.load(Ordering::SeqCst), + ) } fn target_machine_factory( @@ -311,12 +324,20 @@ impl ExtraBackendMethods for GccCodegenBackend { } } +#[derive(Clone, Copy, PartialEq)] +pub enum LtoMode { + None, + Thin, + Fat, +} + pub struct GccContext { context: Arc, /// This field is needed in order to be able to set the flag -fPIC when necessary when doing /// LTO. relocation_model: RelocModel, - should_combine_object_files: bool, + lto_mode: LtoMode, + lto_supported: bool, // Temporary directory used by LTO. We keep it here so that it's not removed before linking. temp_dir: Option, } @@ -428,7 +449,10 @@ pub fn __rustc_codegen_backend() -> Box { supports_128bit_integers: AtomicBool::new(false), }))); - Box::new(GccCodegenBackend { target_info: LockedTargetInfo { info } }) + Box::new(GccCodegenBackend { + lto_supported: Arc::new(AtomicBool::new(false)), + target_info: LockedTargetInfo { info }, + }) } fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { diff --git a/tests/cross_lang_lto/Cargo.lock b/tests/cross_lang_lto/Cargo.lock new file mode 100644 index 0000000000000..a0c9d2df383d8 --- /dev/null +++ b/tests/cross_lang_lto/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "cross_lang_lto" +version = "0.1.0" diff --git a/tests/cross_lang_lto/Cargo.toml b/tests/cross_lang_lto/Cargo.toml new file mode 100644 index 0000000000000..777e6548df2b7 --- /dev/null +++ b/tests/cross_lang_lto/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cross_lang_lto" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/tests/cross_lang_lto/add.c b/tests/cross_lang_lto/add.c new file mode 100644 index 0000000000000..cc59f113bc192 --- /dev/null +++ b/tests/cross_lang_lto/add.c @@ -0,0 +1,5 @@ +#include + +uint32_t my_add(uint32_t a, uint32_t b) { + return a + b; +} diff --git a/tests/cross_lang_lto/src/main.rs b/tests/cross_lang_lto/src/main.rs new file mode 100644 index 0000000000000..3c64248ba2a05 --- /dev/null +++ b/tests/cross_lang_lto/src/main.rs @@ -0,0 +1,18 @@ +/* + * Compile the C code with: + * gcc -c -flto add.c -ffat-lto-objects + * ar rcs libadd.a add.o + * + * Compile the Rust code with: + * CG_RUSTFLAGS="-L native=. -Clinker-plugin-lto -Clinker=gcc" y cargo run --release + */ + +#[link(name="add")] +unsafe extern "C" { + fn my_add(a: u32, b: u32) -> u32; +} + +fn main() { + let res = unsafe { my_add(30, 12) }; + println!("{}", res); +} diff --git a/tests/failing-lto-tests.txt b/tests/failing-lto-tests.txt deleted file mode 100644 index bf0633f732000..0000000000000 --- a/tests/failing-lto-tests.txt +++ /dev/null @@ -1,33 +0,0 @@ -tests/ui/lint/unsafe_code/forge_unsafe_block.rs -tests/ui/lint/unused-qualification-in-derive-expansion.rs -tests/ui/macros/macro-quote-test.rs -tests/ui/macros/proc_macro.rs -tests/ui/panic-runtime/lto-unwind.rs -tests/ui/resolve/derive-macro-1.rs -tests/ui/resolve/derive-macro-2.rs -tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs -tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs -tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs -tests/ui/rust-2018/suggestions-not-always-applicable.rs -tests/ui/rust-2021/reserved-prefixes-via-macro.rs -tests/ui/underscore-imports/duplicate.rs -tests/ui/async-await/issues/issue-60674.rs -tests/ui/attributes/main-removed-2/main.rs -tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs -tests/ui/crate-loading/cross-compiled-proc-macro.rs -tests/ui/derives/derive-marker-tricky.rs -tests/ui/diagnostic_namespace/existing_proc_macros.rs -tests/ui/fmt/format-args-capture-issue-106408.rs -tests/ui/fmt/indoc-issue-106408.rs -tests/ui/hygiene/issue-77523-def-site-async-await.rs -tests/ui/inherent-impls-overlap-check/no-overlap.rs -tests/ui/enum-discriminant/issue-46519.rs -tests/ui/issues/issue-45731.rs -tests/ui/lint/test-allow-dead-extern-static-no-warning.rs -tests/ui/macros/macro-comma-behavior-rpass.rs -tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs -tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs -tests/ui/macros/stringify.rs -tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs -tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs -tests/ui/lto/debuginfo-lto-alloc.rs diff --git a/tests/failing-run-make-tests.txt b/tests/failing-run-make-tests.txt index c5e22970c6605..822aaec0edeb5 100644 --- a/tests/failing-run-make-tests.txt +++ b/tests/failing-run-make-tests.txt @@ -1,35 +1,11 @@ -tests/run-make/a-b-a-linker-guard/ -tests/run-make/CURRENT_RUSTC_VERSION/ tests/run-make/cross-lang-lto/ tests/run-make/cross-lang-lto-upstream-rlibs/ -tests/run-make/doctests-keep-binaries/ -tests/run-make/doctests-runtool/ -tests/run-make/emit-shared-files/ -tests/run-make/exit-code/ tests/run-make/llvm-ident/ tests/run-make/native-link-modifier-bundle/ tests/run-make/remap-path-prefix-dwarf/ -tests/run-make/repr128-dwarf/ tests/run-make/rlib-format-packed-bundled-libs/ tests/run-make/rlib-format-packed-bundled-libs-2/ -tests/run-make/rustdoc-determinism/ -tests/run-make/rustdoc-error-lines/ -tests/run-make/rustdoc-map-file/ -tests/run-make/rustdoc-output-path/ -tests/run-make/rustdoc-scrape-examples-invalid-expr/ -tests/run-make/rustdoc-scrape-examples-multiple/ -tests/run-make/rustdoc-scrape-examples-ordering/ -tests/run-make/rustdoc-scrape-examples-remap/ -tests/run-make/rustdoc-scrape-examples-test/ -tests/run-make/rustdoc-scrape-examples-whitespace/ -tests/run-make/rustdoc-scrape-examples-macros/ -tests/run-make/rustdoc-with-out-dir-option/ -tests/run-make/rustdoc-verify-output-files/ -tests/run-make/rustdoc-themes/ -tests/run-make/rustdoc-with-short-out-dir-option/ -tests/run-make/rustdoc-with-output-option/ tests/run-make/arguments-non-c-like-enum/ -tests/run-make/c-link-to-rust-staticlib/ tests/run-make/foreign-double-unwind/ tests/run-make/foreign-exceptions/ tests/run-make/glibc-staticlib-args/ diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index e2615bce190e0..cc00432ceb54e 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -1,5 +1,3 @@ -tests/ui/allocator/no_std-alloc-error-handler-custom.rs -tests/ui/allocator/no_std-alloc-error-handler-default.rs tests/ui/asm/may_unwind.rs tests/ui/asm/x86_64/may_unwind.rs tests/ui/drop/dynamic-drop-async.rs @@ -17,7 +15,6 @@ tests/ui/panic-runtime/link-to-abort.rs tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/consts/missing_span_in_backtrace.rs tests/ui/drop/dynamic-drop.rs -tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs tests/ui/simd/issue-17170.rs tests/ui/simd/issue-39720.rs tests/ui/drop/panic-during-drop-14875.rs @@ -31,11 +28,9 @@ tests/ui/coroutine/resume-after-return.rs tests/ui/simd/masked-load-store.rs tests/ui/simd/repr_packed.rs tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs -tests/ui/consts/try-operator.rs tests/ui/coroutine/unwind-abort-mix.rs tests/ui/consts/issue-miri-1910.rs tests/ui/consts/const_cmp_type_id.rs -tests/ui/consts/issue-73976-monomorphic.rs tests/ui/consts/issue-94675.rs tests/ui/traits/const-traits/const-drop-fail.rs tests/ui/runtime/on-broken-pipe/child-processes.rs @@ -53,7 +48,6 @@ tests/ui/sanitizer/cfi/virtual-auto.rs tests/ui/sanitizer/cfi/sized-associated-ty.rs tests/ui/sanitizer/cfi/can-reveal-opaques.rs tests/ui/sanitizer/kcfi-mangling.rs -tests/ui/statics/const_generics.rs tests/ui/backtrace/dylib-dep.rs tests/ui/delegation/fn-header.rs tests/ui/consts/const-eval/parse_ints.rs @@ -74,13 +68,7 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs tests/ui/simd/simd-bitmask-notpow2.rs tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs tests/ui/numbers-arithmetic/u128-as-f32.rs -tests/ui/lto/all-crates.rs -tests/ui/uninhabited/uninhabited-transparent-return-abi.rs -tests/ui/coroutine/panic-drops-resume.rs -tests/ui/coroutine/panic-drops.rs -tests/ui/coroutine/panic-safe.rs tests/ui/process/nofile-limit.rs -tests/ui/simd/intrinsic/generic-arithmetic-pass.rs tests/ui/linking/no-gc-encapsulation-symbols.rs tests/ui/panics/unwind-force-no-unwind-tables.rs tests/ui/attributes/fn-align-dyn.rs @@ -88,3 +76,4 @@ tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs tests/ui/explicit-tail-calls/recursion-etc.rs tests/ui/explicit-tail-calls/indexer.rs tests/ui/explicit-tail-calls/drop-order.rs +tests/ui/c-variadic/valid.rs From 75f402847f1bea214232575d9a998e1eb28ec459 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 13 Oct 2025 12:41:24 -0400 Subject: [PATCH 02/27] rustc_target: introduce Arch Improve type safety by using an enum rather than strings. --- src/abi.rs | 20 +++++++------- src/attributes.rs | 8 +++--- src/base.rs | 4 +-- src/context.rs | 2 +- src/gcc_util.rs | 68 +++++++++++++++++++++++++---------------------- src/lib.rs | 4 +-- 6 files changed, 55 insertions(+), 51 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index 0b359f1c5c81b..b7d0e19ee2725 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -12,6 +12,8 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; +#[cfg(feature = "master")] +use rustc_target::spec::Arch; use crate::builder::Builder; use crate::context::CodegenCx; @@ -233,12 +235,12 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { #[cfg(feature = "master")] fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { - conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) + conv_to_fn_attribute(self.conv, cx.tcx.sess.target.arch) } } #[cfg(feature = "master")] -pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &str) -> Option> { +pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, CanonAbi::RustCold => FnAttribute::Cold, @@ -251,15 +253,11 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &str) -> Option FnAttribute::ArmCmseNonsecureEntry, ArmCall::Aapcs => FnAttribute::ArmPcs("aapcs"), }, - CanonAbi::GpuKernel => { - if arch == "amdgpu" { - FnAttribute::GcnAmdGpuHsaKernel - } else if arch == "nvptx64" { - FnAttribute::NvptxKernel - } else { - panic!("Architecture {} does not support GpuKernel calling convention", arch); - } - } + CanonAbi::GpuKernel => match arch { + Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, + Arch::Nvptx64 => FnAttribute::NvptxKernel, + arch => panic!("Arch {arch} does not support GpuKernel calling convention"), + }, // TODO(antoyo): check if those AVR attributes are mapped correctly. CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { InterruptKind::Avr => FnAttribute::AvrSignal, diff --git a/src/attributes.rs b/src/attributes.rs index 04b43bb8bb7c4..5df1dc41b01dd 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -9,6 +9,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; #[cfg(feature = "master")] use rustc_middle::mir::TerminatorKind; use rustc_middle::ty; +#[cfg(feature = "master")] +use rustc_target::spec::Arch; use crate::context::CodegenCx; use crate::gcc_util::to_gcc_features; @@ -70,7 +72,7 @@ fn inline_attr<'gcc, 'tcx>( InlineAttr::Hint => Some(FnAttribute::Inline), InlineAttr::Force { .. } => Some(FnAttribute::AlwaysInline), InlineAttr::Never => { - if cx.sess().target.arch != "amdgpu" { + if cx.sess().target.arch != Arch::AmdGpu { Some(FnAttribute::NoInline) } else { None @@ -153,8 +155,8 @@ pub fn from_fn_attrs<'gcc, 'tcx>( .join(","); if !target_features.is_empty() { #[cfg(feature = "master")] - match cx.sess().target.arch.as_ref() { - "x86" | "x86_64" | "powerpc" => { + match cx.sess().target.arch { + Arch::X86 | Arch::X86_64 | Arch::PowerPC => { func.add_attribute(FnAttribute::Target(&target_features)) } // The target attribute is not supported on other targets in GCC. diff --git a/src/base.rs b/src/base.rs index e8672f49580b6..0a0f0ed37f0b5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; use rustc_span::Symbol; -use rustc_target::spec::RelocModel; #[cfg(feature = "master")] use rustc_target::spec::SymbolVisibility; +use rustc_target::spec::{Arch, RelocModel}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -116,7 +116,7 @@ pub fn compile_codegen_unit( .map(|string| &string[1..]) .collect(); - if !disabled_features.contains("avx") && tcx.sess.target.arch == "x86_64" { + if !disabled_features.contains("avx") && tcx.sess.target.arch == Arch::X86_64 { // NOTE: we always enable AVX because the equivalent of llvm.x86.sse2.cmp.pd in GCC for // SSE2 is multiple builtins, so we use the AVX __builtin_ia32_cmppd instead. // FIXME(antoyo): use the proper builtins for llvm.x86.sse2.cmp.pd and similar. diff --git a/src/context.rs b/src/context.rs index c9ae96777de44..6084b4fc07fac 100644 --- a/src/context.rs +++ b/src/context.rs @@ -487,7 +487,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { #[cfg(feature = "master")] - let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch); + let conv = conv_to_fn_attribute(self.sess().target.entry_abi, self.sess().target.arch); #[cfg(not(feature = "master"))] let conv = None; Some(self.declare_entry_fn(entry_name, fn_type, conv)) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 702704ddf1369..83d54472e5ded 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -3,6 +3,7 @@ use gccjit::Context; use rustc_codegen_ssa::target_features; use rustc_data_structures::smallvec::{SmallVec, smallvec}; use rustc_session::Session; +use rustc_target::spec::Arch; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { target_features::retpoline_features_by_flags(sess, features); @@ -65,44 +66,47 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> { - let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch }; // cSpell:disable - match (arch, s) { + match (sess.target.arch, s) { // FIXME: seems like x87 does not exist? - ("x86", "x87") => smallvec![], - ("x86", "sse4.2") => smallvec!["sse4.2", "crc32"], - ("x86", "pclmulqdq") => smallvec!["pclmul"], - ("x86", "rdrand") => smallvec!["rdrnd"], - ("x86", "bmi1") => smallvec!["bmi"], - ("x86", "cmpxchg16b") => smallvec!["cx16"], - ("x86", "avx512vaes") => smallvec!["vaes"], - ("x86", "avx512gfni") => smallvec!["gfni"], - ("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], + (Arch::X86 | Arch::X86_64, "x87") => smallvec![], + (Arch::X86 | Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], + (Arch::X86 | Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], + (Arch::X86 | Arch::X86_64, "rdrand") => smallvec!["rdrnd"], + (Arch::X86 | Arch::X86_64, "bmi1") => smallvec!["bmi"], + (Arch::X86 | Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], + (Arch::X86 | Arch::X86_64, "avx512vaes") => smallvec!["vaes"], + (Arch::X86 | Arch::X86_64, "avx512gfni") => smallvec!["gfni"], + (Arch::X86 | Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], // NOTE: seems like GCC requires 'avx512bw' for 'avx512vbmi2'. - ("x86", "avx512vbmi2") => smallvec!["avx512vbmi2", "avx512bw"], + (Arch::X86 | Arch::X86_64, "avx512vbmi2") => { + smallvec!["avx512vbmi2", "avx512bw"] + } // NOTE: seems like GCC requires 'avx512bw' for 'avx512bitalg'. - ("x86", "avx512bitalg") => smallvec!["avx512bitalg", "avx512bw"], - ("aarch64", "rcpc2") => smallvec!["rcpc-immo"], - ("aarch64", "dpb") => smallvec!["ccpp"], - ("aarch64", "dpb2") => smallvec!["ccdp"], - ("aarch64", "frintts") => smallvec!["fptoint"], - ("aarch64", "fcma") => smallvec!["complxnum"], - ("aarch64", "pmuv3") => smallvec!["perfmon"], - ("aarch64", "paca") => smallvec!["pauth"], - ("aarch64", "pacg") => smallvec!["pauth"], + (Arch::X86 | Arch::X86_64, "avx512bitalg") => { + smallvec!["avx512bitalg", "avx512bw"] + } + (Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], + (Arch::AArch64, "dpb") => smallvec!["ccpp"], + (Arch::AArch64, "dpb2") => smallvec!["ccdp"], + (Arch::AArch64, "frintts") => smallvec!["fptoint"], + (Arch::AArch64, "fcma") => smallvec!["complxnum"], + (Arch::AArch64, "pmuv3") => smallvec!["perfmon"], + (Arch::AArch64, "paca") => smallvec!["pauth"], + (Arch::AArch64, "pacg") => smallvec!["pauth"], // Rust ties fp and neon together. In GCC neon implicitly enables fp, // but we manually enable neon when a feature only implicitly enables fp - ("aarch64", "f32mm") => smallvec!["f32mm", "neon"], - ("aarch64", "f64mm") => smallvec!["f64mm", "neon"], - ("aarch64", "fhm") => smallvec!["fp16fml", "neon"], - ("aarch64", "fp16") => smallvec!["fullfp16", "neon"], - ("aarch64", "jsconv") => smallvec!["jsconv", "neon"], - ("aarch64", "sve") => smallvec!["sve", "neon"], - ("aarch64", "sve2") => smallvec!["sve2", "neon"], - ("aarch64", "sve2-aes") => smallvec!["sve2-aes", "neon"], - ("aarch64", "sve2-sm4") => smallvec!["sve2-sm4", "neon"], - ("aarch64", "sve2-sha3") => smallvec!["sve2-sha3", "neon"], - ("aarch64", "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], + (Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], + (Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], + (Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], + (Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], + (Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], + (Arch::AArch64, "sve") => smallvec!["sve", "neon"], + (Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], + (Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], + (Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], + (Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], + (Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], (_, s) => smallvec![s], } // cSpell:enable diff --git a/src/lib.rs b/src/lib.rs index 71500ded02038..9f5b03c02a092 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,7 +103,7 @@ use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; use rustc_span::Symbol; -use rustc_target::spec::RelocModel; +use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; use crate::back::lto::ModuleBuffer; @@ -249,7 +249,7 @@ impl CodegenBackend for GccCodegenBackend { fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { let context = Context::default(); - if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { + if matches!(tcx.sess.target.arch, Arch::X86 | Arch::X86_64) { context.add_command_line_option("-masm=intel"); } #[cfg(feature = "master")] From 44b269db1449a8e907fa56f45ccd83d1ab100efa Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Tue, 28 Oct 2025 19:48:56 -0400 Subject: [PATCH 03/27] rustc_target: allow unenumerated architectures --- src/abi.rs | 8 +++---- src/context.rs | 2 +- src/gcc_util.rs | 62 ++++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index b7d0e19ee2725..bcc28e476dba9 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -235,12 +235,12 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { #[cfg(feature = "master")] fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { - conv_to_fn_attribute(self.conv, cx.tcx.sess.target.arch) + conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) } } #[cfg(feature = "master")] -pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option> { +pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, CanonAbi::RustCold => FnAttribute::Cold, @@ -254,8 +254,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option FnAttribute::ArmPcs("aapcs"), }, CanonAbi::GpuKernel => match arch { - Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, - Arch::Nvptx64 => FnAttribute::NvptxKernel, + &Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, + &Arch::Nvptx64 => FnAttribute::NvptxKernel, arch => panic!("Arch {arch} does not support GpuKernel calling convention"), }, // TODO(antoyo): check if those AVR attributes are mapped correctly. diff --git a/src/context.rs b/src/context.rs index 6084b4fc07fac..c9ae96777de44 100644 --- a/src/context.rs +++ b/src/context.rs @@ -487,7 +487,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { #[cfg(feature = "master")] - let conv = conv_to_fn_attribute(self.sess().target.entry_abi, self.sess().target.arch); + let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch); #[cfg(not(feature = "master"))] let conv = None; Some(self.declare_entry_fn(entry_name, fn_type, conv)) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 83d54472e5ded..e33b6c92d6371 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -67,46 +67,46 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> { // cSpell:disable - match (sess.target.arch, s) { + match (&sess.target.arch, s) { // FIXME: seems like x87 does not exist? - (Arch::X86 | Arch::X86_64, "x87") => smallvec![], - (Arch::X86 | Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], - (Arch::X86 | Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], - (Arch::X86 | Arch::X86_64, "rdrand") => smallvec!["rdrnd"], - (Arch::X86 | Arch::X86_64, "bmi1") => smallvec!["bmi"], - (Arch::X86 | Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], - (Arch::X86 | Arch::X86_64, "avx512vaes") => smallvec!["vaes"], - (Arch::X86 | Arch::X86_64, "avx512gfni") => smallvec!["gfni"], - (Arch::X86 | Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], + (&Arch::X86 | &Arch::X86_64, "x87") => smallvec![], + (&Arch::X86 | &Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], + (&Arch::X86 | &Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], + (&Arch::X86 | &Arch::X86_64, "rdrand") => smallvec!["rdrnd"], + (&Arch::X86 | &Arch::X86_64, "bmi1") => smallvec!["bmi"], + (&Arch::X86 | &Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], + (&Arch::X86 | &Arch::X86_64, "avx512vaes") => smallvec!["vaes"], + (&Arch::X86 | &Arch::X86_64, "avx512gfni") => smallvec!["gfni"], + (&Arch::X86 | &Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], // NOTE: seems like GCC requires 'avx512bw' for 'avx512vbmi2'. - (Arch::X86 | Arch::X86_64, "avx512vbmi2") => { + (&Arch::X86 | &Arch::X86_64, "avx512vbmi2") => { smallvec!["avx512vbmi2", "avx512bw"] } // NOTE: seems like GCC requires 'avx512bw' for 'avx512bitalg'. - (Arch::X86 | Arch::X86_64, "avx512bitalg") => { + (&Arch::X86 | &Arch::X86_64, "avx512bitalg") => { smallvec!["avx512bitalg", "avx512bw"] } - (Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], - (Arch::AArch64, "dpb") => smallvec!["ccpp"], - (Arch::AArch64, "dpb2") => smallvec!["ccdp"], - (Arch::AArch64, "frintts") => smallvec!["fptoint"], - (Arch::AArch64, "fcma") => smallvec!["complxnum"], - (Arch::AArch64, "pmuv3") => smallvec!["perfmon"], - (Arch::AArch64, "paca") => smallvec!["pauth"], - (Arch::AArch64, "pacg") => smallvec!["pauth"], + (&Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], + (&Arch::AArch64, "dpb") => smallvec!["ccpp"], + (&Arch::AArch64, "dpb2") => smallvec!["ccdp"], + (&Arch::AArch64, "frintts") => smallvec!["fptoint"], + (&Arch::AArch64, "fcma") => smallvec!["complxnum"], + (&Arch::AArch64, "pmuv3") => smallvec!["perfmon"], + (&Arch::AArch64, "paca") => smallvec!["pauth"], + (&Arch::AArch64, "pacg") => smallvec!["pauth"], // Rust ties fp and neon together. In GCC neon implicitly enables fp, // but we manually enable neon when a feature only implicitly enables fp - (Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], - (Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], - (Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], - (Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], - (Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], - (Arch::AArch64, "sve") => smallvec!["sve", "neon"], - (Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], - (Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], - (Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], - (Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], - (Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], + (&Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], + (&Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], + (&Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], + (&Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], + (&Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], + (&Arch::AArch64, "sve") => smallvec!["sve", "neon"], + (&Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], + (&Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], + (&Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], + (&Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], + (&Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], (_, s) => smallvec![s], } // cSpell:enable From a6ca4f529008c8d5aaf81efdace51e5544a4e26b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 09:19:25 +0000 Subject: [PATCH 04/27] Move warning reporting from flag_to_backend_features to cfg_target_feature This way warnings are emitted even in a check build. --- src/gcc_util.rs | 35 +++++++++++++---------------------- src/lib.rs | 38 +++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 702704ddf1369..1c9679ead0db0 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -11,7 +11,7 @@ fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { /// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). -pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec { +pub(crate) fn global_gcc_features(sess: &Session) -> Vec { // Features that come earlier are overridden by conflicting features later in the string. // Typically we'll want more explicit settings to override the implicit ones, so: // @@ -36,27 +36,18 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec) -> Box { @@ -446,21 +446,25 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig { - let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| { - // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. - if feature == "neon" { - return false; - } - target_info.cpu_supports(feature) - // cSpell:disable - /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ - // cSpell:enable - }); + let (unstable_target_features, target_features) = cfg_target_feature( + sess, + |feature| to_gcc_features(sess, feature), + |feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if feature == "neon" { + return false; + } + target_info.cpu_supports(feature) + // cSpell:disable + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ + // cSpell:enable + }, + ); let has_reliable_f16 = target_info.supports_target_dependent_type(CType::Float16); let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128); From 3a7f4c4c87f7ff11afde1b0b3e715f2f534883a6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:16:39 +0000 Subject: [PATCH 05/27] Unify the configuration of the compiler docs Previously it was rather inconsistent which crates got the rust logo and which didn't and setting html_root_url was forgotten in many cases. --- src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9f5b03c02a092..c3fa570fb5ccc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,9 +13,6 @@ * TODO(antoyo): remove the patches. */ -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(rustc_private)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] From 1548ba6a46c4a5ac6fa723daff48f0527ab84131 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 Nov 2025 12:22:15 +0100 Subject: [PATCH 06/27] Replace `allow` attributes with `expect` and remove unused attributes --- src/attributes.rs | 2 +- src/back/lto.rs | 2 +- src/builder.rs | 3 +-- src/consts.rs | 3 +-- src/context.rs | 4 ++-- src/declare.rs | 2 +- src/intrinsic/archs.rs | 20 +------------------- src/intrinsic/llvm.rs | 2 +- src/lib.rs | 6 +++--- src/mono_item.rs | 3 +-- src/type_.rs | 2 +- 11 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src/attributes.rs b/src/attributes.rs index 04b43bb8bb7c4..ee4a676e3d65c 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -84,7 +84,7 @@ fn inline_attr<'gcc, 'tcx>( /// attributes. pub fn from_fn_attrs<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, - #[cfg_attr(not(feature = "master"), allow(unused_variables))] func: Function<'gcc>, + #[cfg_attr(not(feature = "master"), expect(unused_variables))] func: Function<'gcc>, instance: ty::Instance<'tcx>, ) { let codegen_fn_attrs = cx.tcx.codegen_instance_attrs(instance.def); diff --git a/src/back/lto.rs b/src/back/lto.rs index 404064fb7a060..e80cec55f5d47 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -633,7 +633,7 @@ pub fn optimize_thin_module( save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); } }*/ - #[allow(clippy::let_and_return)] + #[expect(clippy::let_and_return)] module } diff --git a/src/builder.rs b/src/builder.rs index 481b12d842f44..62bc55a8ebbe1 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1481,7 +1481,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { variable.to_rvalue() } - #[allow(dead_code)] fn va_arg(&mut self, _list: RValue<'gcc>, _ty: Type<'gcc>) -> RValue<'gcc> { unimplemented!(); } @@ -2517,7 +2516,7 @@ impl ToGccComp for RealPredicate { } #[repr(C)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] enum MemOrdering { __ATOMIC_RELAXED, __ATOMIC_CONSUME, diff --git a/src/consts.rs b/src/consts.rs index ec7d4b285a3fd..6fb96f8832b93 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -58,7 +58,6 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { global_value } - #[cfg_attr(not(feature = "master"), allow(unused_mut))] fn codegen_static(&mut self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); @@ -162,7 +161,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { // TODO(antoyo) } - #[cfg_attr(not(feature = "master"), allow(unused_variables))] + #[cfg_attr(not(feature = "master"), expect(unused_variables))] pub fn add_used_function(&self, function: Function<'gcc>) { #[cfg(feature = "master")] function.add_attribute(FnAttribute::Used); diff --git a/src/context.rs b/src/context.rs index c9ae96777de44..dbb89a4ff7dba 100644 --- a/src/context.rs +++ b/src/context.rs @@ -28,7 +28,7 @@ use crate::abi::conv_to_fn_attribute; use crate::callee::get_fn; use crate::common::SignType; -#[cfg_attr(not(feature = "master"), allow(dead_code))] +#[cfg_attr(not(feature = "master"), expect(dead_code))] pub struct CodegenCx<'gcc, 'tcx> { /// A cache of converted ConstAllocs pub const_cache: RefCell>>, @@ -132,7 +132,7 @@ pub struct CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub fn new( context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, diff --git a/src/declare.rs b/src/declare.rs index 691fd8729e39a..42d6fb17a88bc 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -156,7 +156,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -#[allow(clippy::let_and_return)] +#[expect(clippy::let_and_return)] fn declare_raw_fn<'gcc>( cx: &CodegenCx<'gcc, '_>, name: &str, diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index c51bcbcedd677..bb8bcbf66f380 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -10,7 +10,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { }; match arch { "AMDGPU" => { - #[allow(non_snake_case)] + #[expect(non_snake_case)] fn AMDGPU(name: &str, full_name: &str) -> &'static str { match name { // AMDGPU @@ -48,7 +48,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { AMDGPU(name, full_name) } "aarch64" => { - #[allow(non_snake_case)] fn aarch64(name: &str, full_name: &str) -> &'static str { match name { // aarch64 @@ -81,7 +80,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { aarch64(name, full_name) } "amdgcn" => { - #[allow(non_snake_case)] fn amdgcn(name: &str, full_name: &str) -> &'static str { match name { // amdgcn @@ -524,7 +522,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { amdgcn(name, full_name) } "arm" => { - #[allow(non_snake_case)] fn arm(name: &str, full_name: &str) -> &'static str { match name { // arm @@ -633,7 +630,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { arm(name, full_name) } "bpf" => { - #[allow(non_snake_case)] fn bpf(name: &str, full_name: &str) -> &'static str { match name { // bpf @@ -655,7 +651,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { bpf(name, full_name) } "cuda" => { - #[allow(non_snake_case)] fn cuda(name: &str, full_name: &str) -> &'static str { match name { // cuda @@ -666,7 +661,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { cuda(name, full_name) } "hexagon" => { - #[allow(non_snake_case)] fn hexagon(name: &str, full_name: &str) -> &'static str { match name { // hexagon @@ -2653,7 +2647,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { hexagon(name, full_name) } "loongarch" => { - #[allow(non_snake_case)] fn loongarch(name: &str, full_name: &str) -> &'static str { match name { // loongarch @@ -4162,7 +4155,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { loongarch(name, full_name) } "mips" => { - #[allow(non_snake_case)] fn mips(name: &str, full_name: &str) -> &'static str { match name { // mips @@ -4843,7 +4835,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { mips(name, full_name) } "nvvm" => { - #[allow(non_snake_case)] fn nvvm(name: &str, full_name: &str) -> &'static str { match name { // nvvm @@ -5652,7 +5643,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { nvvm(name, full_name) } "ppc" => { - #[allow(non_snake_case)] fn ppc(name: &str, full_name: &str) -> &'static str { match name { // ppc @@ -6245,7 +6235,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ppc(name, full_name) } "ptx" => { - #[allow(non_snake_case)] fn ptx(name: &str, full_name: &str) -> &'static str { match name { // ptx @@ -6273,7 +6262,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ptx(name, full_name) } "r600" => { - #[allow(non_snake_case)] fn r600(name: &str, full_name: &str) -> &'static str { match name { // r600 @@ -6298,7 +6286,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { r600(name, full_name) } "riscv" => { - #[allow(non_snake_case)] fn riscv(name: &str, full_name: &str) -> &'static str { match name { // riscv @@ -6332,7 +6319,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { riscv(name, full_name) } "s390" => { - #[allow(non_snake_case)] fn s390(name: &str, full_name: &str) -> &'static str { match name { // s390 @@ -6526,7 +6512,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { s390(name, full_name) } "spv" => { - #[allow(non_snake_case)] fn spv(name: &str, full_name: &str) -> &'static str { match name { // spv @@ -6543,7 +6528,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { spv(name, full_name) } "ve" => { - #[allow(non_snake_case)] fn ve(name: &str, full_name: &str) -> &'static str { match name { // ve @@ -7816,7 +7800,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ve(name, full_name) } "x86" => { - #[allow(non_snake_case)] fn x86(name: &str, full_name: &str) -> &'static str { match name { // x86 @@ -10384,7 +10367,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { x86(name, full_name) } "xcore" => { - #[allow(non_snake_case)] fn xcore(name: &str, full_name: &str) -> &'static str { match name { // xcore diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 39dba28b24c9e..51f44011dc6ae 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -85,7 +85,7 @@ fn wide_aes_output_type<'a, 'gcc, 'tcx>( (aes_output_type.as_type(), field1, field2) } -#[cfg_attr(not(feature = "master"), allow(unused_variables))] +#[cfg_attr(not(feature = "master"), expect(unused_variables))] pub fn adjust_function<'gcc>( context: &'gcc Context<'gcc>, func_name: &str, diff --git a/src/lib.rs b/src/lib.rs index 5d84ba854bb3d..7337c9281eb39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ * TODO(antoyo): remove the patches. */ -#![allow(internal_features)] +#![expect(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] #![feature(rustc_private)] @@ -21,7 +21,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![deny(clippy::pattern_type_mismatch)] -#![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] +#![expect(clippy::uninlined_format_args)] // The rustc crates we need extern crate rustc_abi; @@ -46,7 +46,7 @@ extern crate rustc_target; extern crate rustc_type_ir; // This prevents duplicating functions and statics that are already part of the host rustc process. -#[allow(unused_extern_crates)] +#[expect(unused_extern_crates)] extern crate rustc_driver; mod abi; diff --git a/src/mono_item.rs b/src/mono_item.rs index 35d44d21bcbf6..31c03eddaca56 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -15,7 +15,7 @@ use crate::type_of::LayoutGccExt; use crate::{attributes, base}; impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - #[cfg_attr(not(feature = "master"), allow(unused_variables))] + #[cfg_attr(not(feature = "master"), expect(unused_variables))] fn predefine_static( &mut self, def_id: DefId, @@ -41,7 +41,6 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.instances.borrow_mut().insert(instance, global); } - #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_fn( &mut self, instance: Instance<'tcx>, diff --git a/src/type_.rs b/src/type_.rs index 15a0206607e12..d356b6af260ae 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -299,7 +299,7 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> { value.get_type() } - #[cfg_attr(feature = "master", allow(unused_mut))] + #[cfg_attr(feature = "master", expect(unused_mut))] fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { #[cfg(not(feature = "master"))] if let Some(struct_type) = ty.is_struct() From 884cea152d956e489ef896a7c25b64b553c34991 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 Nov 2025 12:36:16 +0100 Subject: [PATCH 07/27] Only generate `expect` attribute if needed --- tools/generate_intrinsics.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/generate_intrinsics.py b/tools/generate_intrinsics.py index 88927f39b93e4..767082c23cce8 100644 --- a/tools/generate_intrinsics.py +++ b/tools/generate_intrinsics.py @@ -183,7 +183,8 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): for arch in archs: if len(intrinsics[arch]) == 0: continue - out.write("\"{}\" => {{ #[allow(non_snake_case)] fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch,arch)) + attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else "" + out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch)) intrinsics[arch].sort(key=lambda x: (x[0], x[2])) out.write(' // {}\n'.format(arch)) for entry in intrinsics[arch]: From f7b66052098aa4584fb34bbe8eeba3e3988fc358 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 12 Oct 2025 22:41:03 -0700 Subject: [PATCH 08/27] Add -Zannotate-moves for profiler visibility of move/copy operations This implements a new unstable compiler flag `-Zannotate-moves` that makes move and copy operations visible in profilers by creating synthetic debug information. This is achieved with zero runtime cost by manipulating debug info scopes to make moves/copies appear as calls to `compiler_move` and `compiler_copy` marker functions in profiling tools. This allows developers to identify expensive move/copy operations in their code using standard profiling tools, without requiring specialized tooling or runtime instrumentation. The implementation works at codegen time. When processing MIR operands (`Operand::Move` and `Operand::Copy`), the codegen creates an `OperandRef` with an optional `move_annotation` field containing an `Instance` of the appropriate profiling marker function. When storing the operand, `store_with_annotation()` wraps the store operation in a synthetic debug scope that makes it appear inlined from the marker. Two marker functions (`compiler_move` and `compiler_copy`) are defined in `library/core/src/profiling.rs`. These are never actually called - they exist solely as debug info anchors. Operations are only annotated if the type: - Meets the size threshold (default: 65 bytes, configurable via `-Zannotate-moves=SIZE`) - Has a non-scalar backend representation (scalars use registers, not memcpy) This has a very small size impact on object file size. With the default limit it's well under 0.1%, and even with a very small limit of 8 bytes it's still ~1.5%. This could be enabled by default. --- src/builder.rs | 2 +- src/debuginfo.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 5657620879ca1..86031a8a46342 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1069,7 +1069,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.val) }; - OperandRef { val, layout: place.layout } + OperandRef { val, layout: place.layout, move_annotation: None } } fn write_operand_repeatedly( diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 0f015cc23f52f..3979f62987f2c 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -19,7 +19,7 @@ use crate::context::CodegenCx; pub(super) const UNKNOWN_LINE_NUMBER: u32 = 0; pub(super) const UNKNOWN_COLUMN_NUMBER: u32 = 0; -impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { +impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( From 0a7459be8350b35b91c11efa5177ef724a0384a3 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 13 Nov 2025 17:16:38 -0500 Subject: [PATCH 09/27] Update to nightly-2025-11-13 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9813bbea00c41..2ff7eb736dc8a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-04" +channel = "nightly-2025-11-13" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 95125dd3f99bebbdec395db92b14a9d50f13fe3d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 13 Nov 2025 17:16:46 -0500 Subject: [PATCH 10/27] Add --bypass-ignore-backends flag --- build_system/src/test.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index dbdaf2a63ef29..c717196134e72 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1065,6 +1065,7 @@ where &test_dir, &"--compiletest-rustc-args", &rustc_args, + &"--bypass-ignore-backends", ]; if run_ignored_tests { From 58684b30a956060da9ba87ee74601a4fc1b9b9f0 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 13 Nov 2025 17:33:41 -0500 Subject: [PATCH 11/27] Add new failing UI tests --- tests/failing-ui-tests.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index cc00432ceb54e..234344624457d 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -77,3 +77,12 @@ tests/ui/explicit-tail-calls/recursion-etc.rs tests/ui/explicit-tail-calls/indexer.rs tests/ui/explicit-tail-calls/drop-order.rs tests/ui/c-variadic/valid.rs +tests/ui/c-variadic/inherent-method.rs +tests/ui/c-variadic/trait-method.rs +tests/ui/explicit-tail-calls/become-cast-return.rs +tests/ui/explicit-tail-calls/become-indirect-return.rs +tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs +tests/ui/sanitizer/kcfi-c-variadic.rs +tests/ui/sanitizer/kcfi/fn-trait-objects.rs +tests/ui/statics/const_generics.rs +tests/ui/test-attrs/test-panic-while-printing.rs From 9dd009eb663cade26934db46e5d52d4929639e0b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 14 Nov 2025 12:44:22 -0500 Subject: [PATCH 12/27] Add back failing LTO tests --- .github/workflows/release.yml | 3 +++ tests/failing-lto-tests.txt | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 tests/failing-lto-tests.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52f94dc2970a4..895d66f9a4acd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,9 @@ jobs: git config --global user.name "User" ./y.sh prepare + - name: Add more failing tests (some panic and debuginfo tests fail) + run: cat tests/failing-lto-tests.txt >> tests/failing-ui-tests.txt + - name: Run tests run: | # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. diff --git a/tests/failing-lto-tests.txt b/tests/failing-lto-tests.txt new file mode 100644 index 0000000000000..c45fc0776588e --- /dev/null +++ b/tests/failing-lto-tests.txt @@ -0,0 +1,7 @@ +tests/ui/lto/all-crates.rs +tests/ui/lto/debuginfo-lto-alloc.rs +tests/ui/panic-runtime/lto-unwind.rs +tests/ui/uninhabited/uninhabited-transparent-return-abi.rs +tests/ui/coroutine/panic-drops-resume.rs +tests/ui/coroutine/panic-drops.rs +tests/ui/coroutine/panic-safe.rs From 4767bbfc69b99fa784f1236d9d53af46bdd02935 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 14 Nov 2025 12:44:27 -0500 Subject: [PATCH 13/27] Remove passing UI test --- tests/failing-ui-tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 234344624457d..e6c832da449b0 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -8,7 +8,6 @@ tests/ui/iterators/iter-sum-overflow-overflow-checks.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/mir/mir_match_guard_let_chains_drop_order.rs -tests/ui/panics/oom-panic-unwind.rs tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs tests/ui/panic-runtime/abort.rs tests/ui/panic-runtime/link-to-abort.rs From 2da6c169a818b18d5b9dee2e08f625e067b5bdc6 Mon Sep 17 00:00:00 2001 From: Harin Date: Sun, 23 Nov 2025 22:04:48 +0530 Subject: [PATCH 14/27] Clarify -Cllvm-args forwarding to GCC in Readme --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index cd6aeae4b42ea..49b0245bffbc7 100644 --- a/Readme.md +++ b/Readme.md @@ -159,7 +159,7 @@ $ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(ca * _**CG_GCCJIT_DUMP_ALL_MODULES**_: Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`. * _**CG_GCCJIT_DUMP_MODULE**_: Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`. - * _**CG_RUSTFLAGS**_: Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`. + * _**CG_RUSTFLAGS**_: Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`. Note that `-Cllvm-args` flags are forwarded to GCC. * _**CG_GCCJIT_DUMP_TO_FILE**_: Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation. * _**CG_GCCJIT_DUMP_RTL**_: Dumps RTL (Register Transfer Language) for virtual registers. * _**CG_GCCJIT_DUMP_RTL_ALL**_: Dumps all RTL passes. From e95bba142bf4fb859511bb6019293b405368d196 Mon Sep 17 00:00:00 2001 From: Harin Date: Sun, 23 Nov 2025 22:29:16 +0530 Subject: [PATCH 15/27] docs: Move -Cllvm-args forwarding explanation to tips.md --- Readme.md | 2 +- doc/tips.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 49b0245bffbc7..cd6aeae4b42ea 100644 --- a/Readme.md +++ b/Readme.md @@ -159,7 +159,7 @@ $ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(ca * _**CG_GCCJIT_DUMP_ALL_MODULES**_: Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`. * _**CG_GCCJIT_DUMP_MODULE**_: Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`. - * _**CG_RUSTFLAGS**_: Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`. Note that `-Cllvm-args` flags are forwarded to GCC. + * _**CG_RUSTFLAGS**_: Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`. * _**CG_GCCJIT_DUMP_TO_FILE**_: Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation. * _**CG_GCCJIT_DUMP_RTL**_: Dumps RTL (Register Transfer Language) for virtual registers. * _**CG_GCCJIT_DUMP_RTL_ALL**_: Dumps all RTL passes. diff --git a/doc/tips.md b/doc/tips.md index e62c3402a292d..38bc98c02d926 100644 --- a/doc/tips.md +++ b/doc/tips.md @@ -9,6 +9,14 @@ be useful. CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../y.sh cargo build ``` +### How to send arguments to GCC + +The `-Cllvm-args` `rustc` flag is repurposed by `rustc_codegen_gcc` to pass arguments directly to the GCC backend. You can use it via the `CG_RUSTFLAGS` environment variable. For example, to pass a `-f` flag to GCC: + +``` +CG_RUSTFLAGS="-Cllvm-args=-fflag-name" ../y.sh cargo build +``` + ### How to see the personality functions in the asm dump ``` From 99a3e75f59a46378f91f710f94825dbb8d7c6da4 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 24 Nov 2025 10:35:32 -0500 Subject: [PATCH 16/27] Update to nightly-2025-11-24 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 2ff7eb736dc8a..f9645451e964d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-13" +channel = "nightly-2025-11-24" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 35e02dd6ce72d578aacdd8830de57cc5d14d18e5 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 24 Nov 2025 11:24:54 -0500 Subject: [PATCH 17/27] Switch from #[expect] to #[allow] because of a clippy bug --- src/back/lto.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index e80cec55f5d47..840f51c0685d7 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -633,7 +633,8 @@ pub fn optimize_thin_module( save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); } }*/ - #[expect(clippy::let_and_return)] + // FIXME: switch to #[expect] when the clippy bug is fixed. + #[allow(clippy::let_and_return)] module } From bd64989880aba2340f2630017747e1dacbe5b6d1 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Nov 2025 09:57:07 -0500 Subject: [PATCH 18/27] Add failing UI tests --- tests/failing-ui-tests.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index e6c832da449b0..2380bd0fc137f 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -85,3 +85,6 @@ tests/ui/sanitizer/kcfi-c-variadic.rs tests/ui/sanitizer/kcfi/fn-trait-objects.rs tests/ui/statics/const_generics.rs tests/ui/test-attrs/test-panic-while-printing.rs +tests/ui/thir-print/offset_of.rs +tests/ui/iterators/rangefrom-overflow-debug.rs +tests/ui/iterators/rangefrom-overflow-overflow-checks.rs From 096b622e0845502ce21c59763f55859d5301ca2c Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Nov 2025 15:13:14 -0500 Subject: [PATCH 19/27] Implement simd_masked_load and simd_masked_store --- src/intrinsic/simd.rs | 190 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 2 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 41363d6313d69..c7ed887b30d02 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -53,6 +53,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }; } + // TODO(antoyo): refactor with the above require_simd macro that was changed in cg_llvm. + #[cfg(feature = "master")] + macro_rules! require_simd2 { + ($ty: expr, $variant:ident) => {{ + require!($ty.is_simd(), InvalidMonomorphization::$variant { span, name, ty: $ty }); + $ty.simd_size_and_type(bx.tcx()) + }}; + } + if name == sym::simd_select_bitmask { require_simd!( args[1].layout.ty, @@ -464,9 +473,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); - // TODO: also support unsigned integers. match *m_elem_ty.kind() { - ty::Int(_) => {} + ty::Int(_) | ty::Uint(_) => {} _ => return_error!(InvalidMonomorphization::MaskWrongElementType { span, name, @@ -1454,6 +1462,184 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( bitwise_red!(simd_reduce_all: BinaryOp::BitwiseAnd, true); bitwise_red!(simd_reduce_any: BinaryOp::BitwiseOr, true); + #[cfg(feature = "master")] + if name == sym::simd_masked_load { + // simd_masked_load<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *_ T, values: ) -> + // * N: number of elements in the input vectors + // * T: type of the element to load + // * M: any integer width is supported, will be truncated to i1 + // Loads contiguous elements from memory behind `pointer`, but only for + // those lanes whose `mask` bit is enabled. + // The memory addresses corresponding to the “off” lanes are not accessed. + + // TODO: handle the alignment. + + // The element type of the "mask" argument must be a signed integer type of any width + let mask_ty = in_ty; + let mask_len = in_len; + + // The second argument must be a pointer matching the element type + let pointer_ty = args[1].layout.ty; + + // The last argument is a passthrough vector providing values for disabled lanes + let values_ty = args[2].layout.ty; + let (values_len, values_elem) = require_simd2!(values_ty, SimdThird); + + require_simd2!(ret_ty, SimdReturn); + + // Of the same length: + require!( + values_len == mask_len, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len: mask_len, + in_ty: mask_ty, + arg_ty: values_ty, + out_len: values_len + } + ); + + // The return type must match the last argument type + require!( + ret_ty == values_ty, + InvalidMonomorphization::ExpectedReturnType { span, name, in_ty: values_ty, ret_ty } + ); + + require!( + matches!( + *pointer_ty.kind(), + ty::RawPtr(p_ty, _) if p_ty == values_elem && p_ty.kind() == values_elem.kind() + ), + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: values_elem, + second_arg: pointer_ty, + in_elem: values_elem, + in_ty: values_ty, + mutability: ExpectedPointerMutability::Not, + } + ); + + let mask = args[0].immediate(); + + let pointer = args[1].immediate(); + let default = args[2].immediate(); + let default_type = default.get_type(); + let vector_type = default_type.unqualified().dyncast_vector().expect("vector type"); + let value_type = vector_type.get_element_type(); + let new_pointer_type = value_type.make_pointer(); + + let pointer = bx.context.new_cast(None, pointer, new_pointer_type); + + let mask_vector_type = mask.get_type().unqualified().dyncast_vector().expect("vector type"); + let elem_type = mask_vector_type.get_element_type(); + let zero = bx.context.new_rvalue_zero(elem_type); + let mut elements = vec![]; + for i in 0..mask_len { + let i = bx.context.new_rvalue_from_int(bx.int_type, i as i32); + let mask = bx.context.new_vector_access(None, mask, i).to_rvalue(); + let mask = bx.context.new_comparison(None, ComparisonOp::NotEquals, mask, zero); + let then_val = bx.context.new_array_access(None, pointer, i).to_rvalue(); + let else_val = bx.context.new_vector_access(None, default, i).to_rvalue(); + let element = bx.select(mask, then_val, else_val); + elements.push(element); + } + let result = bx.context.new_rvalue_from_vector(None, default_type, &elements); + return Ok(result); + } + + #[cfg(feature = "master")] + if name == sym::simd_masked_store { + // simd_masked_store<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *mut T, values: ) -> () + // * N: number of elements in the input vectors + // * T: type of the element to load + // * M: any integer width is supported, will be truncated to i1 + // Stores contiguous elements to memory behind `pointer`, but only for + // those lanes whose `mask` bit is enabled. + // The memory addresses corresponding to the “off” lanes are not accessed. + + // TODO: handle the alignment. + + // The element type of the "mask" argument must be a signed integer type of any width + let mask_ty = in_ty; + let mask_len = in_len; + + // The second argument must be a pointer matching the element type + let pointer_ty = args[1].layout.ty; + + // The last argument specifies the values to store to memory + let values_ty = args[2].layout.ty; + let (values_len, values_elem) = require_simd2!(values_ty, SimdThird); + + // Of the same length: + require!( + values_len == mask_len, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len: mask_len, + in_ty: mask_ty, + arg_ty: values_ty, + out_len: values_len + } + ); + + // The second argument must be a mutable pointer type matching the element type + require!( + matches!( + *pointer_ty.kind(), + ty::RawPtr(p_ty, p_mutbl) + if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut() + ), + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: values_elem, + second_arg: pointer_ty, + in_elem: values_elem, + in_ty: values_ty, + mutability: ExpectedPointerMutability::Mut, + } + ); + + let mask = args[0].immediate(); + let pointer = args[1].immediate(); + let values = args[2].immediate(); + let values_type = values.get_type(); + let vector_type = values_type.unqualified().dyncast_vector().expect("vector type"); + let value_type = vector_type.get_element_type(); + let new_pointer_type = value_type.make_pointer(); + + let pointer = bx.context.new_cast(None, pointer, new_pointer_type); + + let vector_type = mask.get_type().unqualified().dyncast_vector().expect("vector type"); + let elem_type = vector_type.get_element_type(); + let zero = bx.context.new_rvalue_zero(elem_type); + for i in 0..mask_len { + let i = bx.context.new_rvalue_from_int(bx.int_type, i as i32); + let mask = bx.context.new_vector_access(None, mask, i).to_rvalue(); + let mask = bx.context.new_comparison(None, ComparisonOp::NotEquals, mask, zero); + + let after_block = bx.current_func().new_block("after"); + let then_block = bx.current_func().new_block("then"); + bx.llbb().end_with_conditional(None, mask, then_block, after_block); + + bx.switch_to_block(then_block); + let lvalue = bx.context.new_array_access(None, pointer, i); + let value = bx.context.new_vector_access(None, values, i).to_rvalue(); + bx.llbb().add_assignment(None, lvalue, value); + bx.llbb().end_with_jump(None, after_block); + + bx.switch_to_block(after_block); + } + + let dummy_value = bx.context.new_rvalue_zero(bx.int_type); + + return Ok(dummy_value); + } + unimplemented!("simd {}", name); } From 92f999471f86236acc8548c53bc70e23c02db669 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Nov 2025 15:13:38 -0500 Subject: [PATCH 20/27] Add dummy mapping for new tile builtins --- src/intrinsic/llvm.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 51f44011dc6ae..e3d189c95ced5 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1573,14 +1573,25 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.tileloadd64" => "__builtin_trap", "llvm.x86.tilerelease" => "__builtin_trap", "llvm.x86.tilestored64" => "__builtin_trap", + "llvm.x86.tileloaddrs64" => "__builtin_trap", "llvm.x86.tileloaddt164" => "__builtin_trap", + "llvm.x86.tileloaddrst164" => "__builtin_trap", "llvm.x86.tilezero" => "__builtin_trap", + "llvm.x86.tilemovrow" => "__builtin_trap", + "llvm.x86.tdpbhf8ps" => "__builtin_trap", + "llvm.x86.tdphbf8ps" => "__builtin_trap", + "llvm.x86.tdpbf8ps" => "__builtin_trap", + "llvm.x86.tdphf8ps" => "__builtin_trap", "llvm.x86.tdpbf16ps" => "__builtin_trap", "llvm.x86.tdpbssd" => "__builtin_trap", "llvm.x86.tdpbsud" => "__builtin_trap", "llvm.x86.tdpbusd" => "__builtin_trap", "llvm.x86.tdpbuud" => "__builtin_trap", "llvm.x86.tdpfp16ps" => "__builtin_trap", + "llvm.x86.tmmultf32ps" => "__builtin_trap", + "llvm.x86.tcvtrowps2phh" => "__builtin_trap", + "llvm.x86.tcvtrowps2phl" => "__builtin_trap", + "llvm.x86.tcvtrowd2ps" => "__builtin_trap", "llvm.x86.tcmmimfp16ps" => "__builtin_trap", "llvm.x86.tcmmrlfp16ps" => "__builtin_trap", From cfcd7ebf2d3f69c4963b30b90c18860ba39a9870 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Nov 2025 17:59:46 -0500 Subject: [PATCH 21/27] Dlopen libgccjit.so in order to support multiple targets more easily --- Cargo.lock | 8 ++++---- Cargo.toml | 6 +++--- libgccjit.version | 2 +- src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 181d3aa89bc89..aea40297f287f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.10.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60362e038e71e4bdc1a5b23fb45e1aba587b5947fe0db58f4871d95608f89eca" +checksum = "9a1d137657dee9b660e884dc11d41efbff8201aa49f9f75f7bc7d400ad1e9062" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.9.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd542c8414e122217551c6af6b7d33acf51a227aee85276f218c087525e01bb" +checksum = "dde7e9f1ec00279a8e901f30567f97ab7536b544b70cc1f79833f35caeed877a" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index d3ff2757857b1..adb272c32a36f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,11 +24,11 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" -gccjit = "2.10" -#gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } +gccjit = { version = "3.1", features = ["dlopen"] } +#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] } # Local copy. -#gccjit = { path = "../gccjit.rs" } +#gccjit = { path = "../gccjit.rs", features = ["dlopen"] } [dev-dependencies] boml = "0.3.1" diff --git a/libgccjit.version b/libgccjit.version index b8d4166542bcd..bab62f6423655 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -28b84db392ac0a572f1a2a2a1317aa5f2bc742cb +0081ca6631abdfa02bf42bc85aaf507b8a0e6beb diff --git a/src/lib.rs b/src/lib.rs index ae70360f2d5f7..3291fd882069d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,7 @@ mod type_; mod type_of; use std::any::Any; +use std::ffi::CString; use std::fmt::Debug; use std::ops::Deref; use std::path::PathBuf; @@ -142,7 +143,7 @@ impl TargetInfo { #[derive(Clone)] pub struct LockedTargetInfo { - info: Arc>>, + info: Arc>>>, } impl Debug for LockedTargetInfo { @@ -153,11 +154,21 @@ impl Debug for LockedTargetInfo { impl LockedTargetInfo { fn cpu_supports(&self, feature: &str) -> bool { - self.info.lock().expect("lock").cpu_supports(feature) + self.info + .lock() + .expect("lock") + .as_ref() + .expect("target info not initialized") + .cpu_supports(feature) } fn supports_target_dependent_type(&self, typ: CType) -> bool { - self.info.lock().expect("lock").supports_target_dependent_type(typ) + self.info + .lock() + .expect("lock") + .as_ref() + .expect("target info not initialized") + .supports_target_dependent_type(typ) } } @@ -169,6 +180,19 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); +fn load_libgccjit_if_needed() { + if gccjit::is_loaded() { + // Do not load a libgccjit second time. + return; + } + + let string = CString::new("libgccjit.so").expect("string to libgccjit path"); + + if let Err(error) = gccjit::load(&string) { + panic!("Cannot load libgccjit.so: {}", error); + } +} + impl CodegenBackend for GccCodegenBackend { fn locale_resource(&self) -> &'static str { crate::DEFAULT_LOCALE_RESOURCE @@ -179,6 +203,8 @@ impl CodegenBackend for GccCodegenBackend { } fn init(&self, _sess: &Session) { + load_libgccjit_if_needed(); + #[cfg(feature = "master")] { let target_cpu = target_cpu(_sess); @@ -189,7 +215,8 @@ impl CodegenBackend for GccCodegenBackend { context.add_command_line_option(format!("-march={}", target_cpu)); } - **self.target_info.info.lock().expect("lock") = context.get_target_info(); + *self.target_info.info.lock().expect("lock") = + IntoDynSyncSend(Some(context.get_target_info())); } #[cfg(feature = "master")] @@ -217,6 +244,9 @@ impl CodegenBackend for GccCodegenBackend { .info .lock() .expect("lock") + .0 + .as_ref() + .expect("target info not initialized") .supports_128bit_integers .store(check_context.get_last_error() == Ok(None), Ordering::SeqCst); } @@ -438,13 +468,12 @@ pub fn __rustc_codegen_backend() -> Box { let info = { // Check whether the target supports 128-bit integers, and sized floating point types (like // Float16). - let context = Context::default(); - Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info()))) + Arc::new(Mutex::new(IntoDynSyncSend(None))) }; #[cfg(not(feature = "master"))] - let info = Arc::new(Mutex::new(IntoDynSyncSend(TargetInfo { + let info = Arc::new(Mutex::new(IntoDynSyncSend(Some(TargetInfo { supports_128bit_integers: AtomicBool::new(false), - }))); + })))); Box::new(GccCodegenBackend { lto_supported: Arc::new(AtomicBool::new(false)), From 53dcfce670322f15acfa9bc685a79214e180dec5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 14:33:14 +0100 Subject: [PATCH 22/27] Update gccjit dependency --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aea40297f287f..00bdacaca6762 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d137657dee9b660e884dc11d41efbff8201aa49f9f75f7bc7d400ad1e9062" +checksum = "ff80f4d6d0749eab3a69122210b3a1fdd52edb6162781aadd7c4842e26983683" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde7e9f1ec00279a8e901f30567f97ab7536b544b70cc1f79833f35caeed877a" +checksum = "263da4f60b7bb5d6a5b21efda961741051ebdbf0e380a09118b03cce66a8c77e" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index adb272c32a36f..18847f50d46a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" -gccjit = { version = "3.1", features = ["dlopen"] } +gccjit = { version = "3.1.1", features = ["dlopen"] } #gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] } # Local copy. From 2567d8171a00061d7b7aa4796a72502f8a623a67 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 26 Nov 2025 12:13:29 -0500 Subject: [PATCH 23/27] Move libgccjit.so in the sysroot This will be useful for the unification work of the handling of the library between all Rust setups. --- .github/workflows/failures.yml | 2 -- .github/workflows/gcc12.yml | 6 ------ .github/workflows/stdarch.yml | 9 +-------- build_system/src/build.rs | 24 +++++++++++++++--------- build_system/src/config.rs | 13 ------------- build_system/src/test.rs | 13 ------------- src/lib.rs | 16 ++++++++++------ tests/lang_tests_common.rs | 26 +------------------------- 8 files changed, 27 insertions(+), 82 deletions(-) diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 67b7fbe4478bd..aa4b4dc22c3e4 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -54,8 +54,6 @@ jobs: if: matrix.libgccjit_version.gcc == 'libgccjit12.so' run: | echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml - echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index da9a1506855c3..55b090894b4af 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -51,12 +51,6 @@ jobs: - name: Setup path to libgccjit run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml - - name: Set env - run: | - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - #- name: Cache rust repository ## We only clone the rust repository for rustc tests #if: ${{ contains(matrix.commands, 'rustc') }} diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 184f122cc1c17..c0a0e3344cc2b 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -59,9 +59,8 @@ jobs: sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64 - - name: Set env + - name: Set config run: | - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV echo 'download-gccjit = true' > config.toml - name: Build @@ -69,12 +68,6 @@ jobs: ./y.sh prepare --only-libcore ./y.sh build --sysroot --release --release-sysroot - - name: Set env (part 2) - run: | - # Set the `LD_LIBRARY_PATH` and `LIBRARY_PATH` env variables... - echo "LD_LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV - echo "LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV - - name: Clean if: ${{ !matrix.cargo_runner }} run: | diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 6aa5faec4c81e..56503b239a3b5 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use std::ffi::OsStr; use std::fs; -use std::path::Path; +use std::os::unix::fs::symlink; +use std::path::{Path, PathBuf}; use crate::config::{Channel, ConfigInfo}; use crate::utils::{ @@ -100,6 +101,18 @@ fn cleanup_sysroot_previous_build(library_dir: &Path) { pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { let start_dir = get_sysroot_dir(); + // Symlink libgccjit.so to sysroot. + let lib_path = start_dir.join("sysroot").join("lib"); + let libgccjit_path = + PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point")) + .join("libgccjit.so"); + let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so"); + // First remove the file to be able to create the symlink even when the file already exists. + let _ = fs::remove_file(&libgccjit_in_sysroot_path); + create_dir(&lib_path)?; + symlink(libgccjit_path, libgccjit_in_sysroot_path) + .map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?; + let library_dir = start_dir.join("sysroot_src").join("library"); cleanup_sysroot_previous_build(&library_dir); @@ -148,7 +161,7 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu run_command_with_output_and_env(&args, Some(&sysroot_dir), Some(&env))?; // Copy files to sysroot - let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); + let sysroot_path = lib_path.join(format!("rustlib/{}/lib/", config.target_triple)); // To avoid errors like "multiple candidates for `rmeta` dependency `core` found", we clean the // sysroot directory before copying the sysroot build artifacts. let _ = fs::remove_dir_all(&sysroot_path); @@ -175,13 +188,6 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let mut env = HashMap::new(); - let gcc_path = - args.config_info.gcc_path.clone().expect( - "The config module should have emitted an error if the GCC path wasn't provided", - ); - env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone()); - env.insert("LIBRARY_PATH".to_string(), gcc_path); - if args.config_info.no_default_features { env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); } diff --git a/build_system/src/config.rs b/build_system/src/config.rs index a5f802e293a94..19255e1ba2b2c 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -429,19 +429,6 @@ impl ConfigInfo { // display metadata load errors env.insert("RUSTC_LOG".to_string(), "warn".to_string()); - let sysroot = current_dir - .join(get_sysroot_dir()) - .join(format!("sysroot/lib/rustlib/{}/lib", self.target_triple)); - let ld_library_path = format!( - "{target}:{sysroot}:{gcc_path}", - target = self.cargo_target_dir, - sysroot = sysroot.display(), - gcc_path = gcc_path, - ); - env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); - env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path); - // NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. // To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. // Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc diff --git a/build_system/src/test.rs b/build_system/src/test.rs index c717196134e72..8aabfa894ce08 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -214,14 +214,6 @@ fn cargo_tests(test_env: &Env, test_args: &TestArg) -> Result<(), String> { // We don't want to pass things like `RUSTFLAGS`, since they contain the -Zcodegen-backend flag. // That would force `cg_gcc` to *rebuild itself* and only then run tests, which is undesirable. let mut env = HashMap::new(); - env.insert( - "LD_LIBRARY_PATH".into(), - test_env.get("LD_LIBRARY_PATH").expect("LD_LIBRARY_PATH missing!").to_string(), - ); - env.insert( - "LIBRARY_PATH".into(), - test_env.get("LIBRARY_PATH").expect("LIBRARY_PATH missing!").to_string(), - ); env.insert( "CG_RUSTFLAGS".into(), test_env.get("CG_RUSTFLAGS").map(|s| s.as_str()).unwrap_or("").to_string(), @@ -1276,11 +1268,6 @@ pub fn run() -> Result<(), String> { if !args.use_system_gcc { args.config_info.setup_gcc_path()?; - let gcc_path = args.config_info.gcc_path.clone().expect( - "The config module should have emitted an error if the GCC path wasn't provided", - ); - env.insert("LIBRARY_PATH".to_string(), gcc_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), gcc_path); } build_if_no_backend(&env, &args)?; diff --git a/src/lib.rs b/src/lib.rs index 3291fd882069d..662e303f94f2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,7 +72,7 @@ use std::any::Any; use std::ffi::CString; use std::fmt::Debug; use std::ops::Deref; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; @@ -180,13 +180,17 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); -fn load_libgccjit_if_needed() { +fn load_libgccjit_if_needed(sysroot_path: &Path) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let string = CString::new("libgccjit.so").expect("string to libgccjit path"); + let sysroot_lib_dir = sysroot_path.join("lib"); + let libgccjit_target_lib_file = sysroot_lib_dir.join("libgccjit.so"); + let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); + + let string = CString::new(path).expect("string to libgccjit path"); if let Err(error) = gccjit::load(&string) { panic!("Cannot load libgccjit.so: {}", error); @@ -202,12 +206,12 @@ impl CodegenBackend for GccCodegenBackend { "gcc" } - fn init(&self, _sess: &Session) { - load_libgccjit_if_needed(); + fn init(&self, sess: &Session) { + load_libgccjit_if_needed(sess.opts.sysroot.path()); #[cfg(feature = "master")] { - let target_cpu = target_cpu(_sess); + let target_cpu = target_cpu(sess); // Get the second TargetInfo with the correct CPU features by setting the arch. let context = Context::default(); diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index 9abe97b108765..311f256b76008 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -2,11 +2,10 @@ #![allow(clippy::uninlined_format_args)] -use std::env::{self, current_dir}; +use std::env::current_dir; use std::path::{Path, PathBuf}; use std::process::Command; -use boml::Toml; use lang_tester::LangTester; use tempfile::TempDir; @@ -23,29 +22,6 @@ pub fn main_inner(profile: Profile) { let current_dir = current_dir().expect("current dir"); let current_dir = current_dir.to_str().expect("current dir").to_string(); - let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - - let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml")) - .ok() - .and_then(|v| { - let toml = Toml::parse(&v).expect("Failed to parse `config.toml`"); - toml.get_string("gcc-path").map(PathBuf::from).ok() - }) - .unwrap_or_else(|| { - // then we try to retrieve it from the `target` folder. - let commit = include_str!("../libgccjit.version").trim(); - Path::new("build/libgccjit").join(commit) - }); - - let gcc_path = Path::new(&gcc_path) - .canonicalize() - .expect("failed to get absolute path of `gcc-path`") - .display() - .to_string(); - unsafe { - env::set_var("LD_LIBRARY_PATH", gcc_path); - } - fn rust_filter(path: &Path) -> bool { path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs" } From 9776f45265d4043c844812a89ddd665267a52f65 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 11:42:42 +0100 Subject: [PATCH 24/27] Update GCC commit --- compiler/rustc_codegen_gcc/libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/libgccjit.version b/compiler/rustc_codegen_gcc/libgccjit.version index bab62f6423655..b8d4166542bcd 100644 --- a/compiler/rustc_codegen_gcc/libgccjit.version +++ b/compiler/rustc_codegen_gcc/libgccjit.version @@ -1 +1 @@ -0081ca6631abdfa02bf42bc85aaf507b8a0e6beb +28b84db392ac0a572f1a2a2a1317aa5f2bc742cb From 15b6fde930900fcfe479d8eb8e9cfc711047d913 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 20:11:18 +0100 Subject: [PATCH 25/27] Update GCC submodule --- compiler/rustc_codegen_gcc/libgccjit.version | 2 +- src/gcc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_gcc/libgccjit.version b/compiler/rustc_codegen_gcc/libgccjit.version index b8d4166542bcd..bab62f6423655 100644 --- a/compiler/rustc_codegen_gcc/libgccjit.version +++ b/compiler/rustc_codegen_gcc/libgccjit.version @@ -1 +1 @@ -28b84db392ac0a572f1a2a2a1317aa5f2bc742cb +0081ca6631abdfa02bf42bc85aaf507b8a0e6beb diff --git a/src/gcc b/src/gcc index 28b84db392ac0..0081ca6631abd 160000 --- a/src/gcc +++ b/src/gcc @@ -1 +1 @@ -Subproject commit 28b84db392ac0a572f1a2a2a1317aa5f2bc742cb +Subproject commit 0081ca6631abdfa02bf42bc85aaf507b8a0e6beb From c939e90a6d3b3a1a9baa24b9acf46091837ec4ff Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Nov 2025 17:59:48 +0100 Subject: [PATCH 26/27] Remove the extra `.0` at the end of the `libgccjit.so` file --- src/bootstrap/src/core/build_steps/gcc.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 17ab8c4e2f479..fa8cfa27a0441 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -40,8 +40,7 @@ impl GccOutput { // However, at runtime, it will by default look for libgccjit.so.0. // So when we install the built libgccjit.so file to the target `directory`, we add it there // with the `.0` suffix. - let mut target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string(); - target_filename.push_str(".0"); + let target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string(); // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink. // In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink, From f94e90f01cd0a68da7dafd22de605866873ac840 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Nov 2025 20:11:19 +0100 Subject: [PATCH 27/27] Remove outdated comment for `libgccjit.so.0` --- src/bootstrap/src/core/build_steps/gcc.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index fa8cfa27a0441..def794c98a41d 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -36,10 +36,6 @@ impl GccOutput { return; } - // At build time, cg_gcc has to link to libgccjit.so (the unversioned symbol). - // However, at runtime, it will by default look for libgccjit.so.0. - // So when we install the built libgccjit.so file to the target `directory`, we add it there - // with the `.0` suffix. let target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string(); // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.