diff --git a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml index 67b7fbe4478bd..aa4b4dc22c3e4 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml +++ b/compiler/rustc_codegen_gcc/.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/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml b/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml index da9a1506855c3..55b090894b4af 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml +++ b/compiler/rustc_codegen_gcc/.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/compiler/rustc_codegen_gcc/.github/workflows/release.yml b/compiler/rustc_codegen_gcc/.github/workflows/release.yml index 52f94dc2970a4..895d66f9a4acd 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/release.yml +++ b/compiler/rustc_codegen_gcc/.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/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml index 184f122cc1c17..c0a0e3344cc2b 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml +++ b/compiler/rustc_codegen_gcc/.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/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index 181d3aa89bc89..00bdacaca6762 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.10.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60362e038e71e4bdc1a5b23fb45e1aba587b5947fe0db58f4871d95608f89eca" +checksum = "ff80f4d6d0749eab3a69122210b3a1fdd52edb6162781aadd7c4842e26983683" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.9.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd542c8414e122217551c6af6b7d33acf51a227aee85276f218c087525e01bb" +checksum = "263da4f60b7bb5d6a5b21efda961741051ebdbf0e380a09118b03cce66a8c77e" dependencies = [ "libc", ] diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index d3ff2757857b1..18847f50d46a2 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/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.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/compiler/rustc_codegen_gcc/build_system/src/build.rs b/compiler/rustc_codegen_gcc/build_system/src/build.rs index 6aa5faec4c81e..56503b239a3b5 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/build.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/build_system/src/config.rs b/compiler/rustc_codegen_gcc/build_system/src/config.rs index a5f802e293a94..19255e1ba2b2c 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/config.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs index dbdaf2a63ef29..8aabfa894ce08 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/test.rs +++ b/compiler/rustc_codegen_gcc/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(), @@ -1065,6 +1057,7 @@ where &test_dir, &"--compiletest-rustc-args", &rustc_args, + &"--bypass-ignore-backends", ]; if run_ignored_tests { @@ -1275,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/compiler/rustc_codegen_gcc/doc/tips.md b/compiler/rustc_codegen_gcc/doc/tips.md index e62c3402a292d..38bc98c02d926 100644 --- a/compiler/rustc_codegen_gcc/doc/tips.md +++ b/compiler/rustc_codegen_gcc/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 ``` 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/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain index 9813bbea00c41..f9645451e964d 100644 --- a/compiler/rustc_codegen_gcc/rust-toolchain +++ b/compiler/rustc_codegen_gcc/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-04" +channel = "nightly-2025-11-24" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_gcc/src/attributes.rs b/compiler/rustc_codegen_gcc/src/attributes.rs index 5df1dc41b01dd..cd8c1206c821b 100644 --- a/compiler/rustc_codegen_gcc/src/attributes.rs +++ b/compiler/rustc_codegen_gcc/src/attributes.rs @@ -86,7 +86,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/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index 404064fb7a060..840f51c0685d7 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -633,6 +633,7 @@ pub fn optimize_thin_module( save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); } }*/ + // FIXME: switch to #[expect] when the clippy bug is fixed. #[allow(clippy::let_and_return)] module } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 132c43ef3cdad..c0519f7a68e28 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index ec7d4b285a3fd..6fb96f8832b93 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index c9ae96777de44..dbb89a4ff7dba 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index 691fd8729e39a..42d6fb17a88bc 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs index c51bcbcedd677..bb8bcbf66f380 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs index 39dba28b24c9e..e3d189c95ced5 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs +++ b/compiler/rustc_codegen_gcc/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, @@ -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", diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 41363d6313d69..c7ed887b30d02 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/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); } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 409b7886740a4..662e303f94f2d 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -18,7 +18,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; @@ -43,7 +43,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; @@ -69,9 +69,10 @@ 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; +use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; @@ -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,23 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); +fn load_libgccjit_if_needed(sysroot_path: &Path) { + if gccjit::is_loaded() { + // Do not load a libgccjit second time. + return; + } + + 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); + } +} + impl CodegenBackend for GccCodegenBackend { fn locale_resource(&self) -> &'static str { crate::DEFAULT_LOCALE_RESOURCE @@ -178,10 +206,12 @@ impl CodegenBackend for GccCodegenBackend { "gcc" } - fn init(&self, _sess: &Session) { + 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(); @@ -189,7 +219,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 +248,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 +472,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)), diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs index 35d44d21bcbf6..31c03eddaca56 100644 --- a/compiler/rustc_codegen_gcc/src/mono_item.rs +++ b/compiler/rustc_codegen_gcc/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/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index 15a0206607e12..d356b6af260ae 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/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() diff --git a/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt new file mode 100644 index 0000000000000..c45fc0776588e --- /dev/null +++ b/compiler/rustc_codegen_gcc/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 diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt index cc00432ceb54e..2380bd0fc137f 100644 --- a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt +++ b/compiler/rustc_codegen_gcc/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 @@ -77,3 +76,15 @@ 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 +tests/ui/thir-print/offset_of.rs +tests/ui/iterators/rangefrom-overflow-debug.rs +tests/ui/iterators/rangefrom-overflow-overflow-checks.rs diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs index 9abe97b108765..311f256b76008 100644 --- a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs +++ b/compiler/rustc_codegen_gcc/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" } diff --git a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py index 88927f39b93e4..767082c23cce8 100644 --- a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py +++ b/compiler/rustc_codegen_gcc/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]: diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 17ab8c4e2f479..def794c98a41d 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -36,12 +36,7 @@ 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 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, 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