From 8f9a32aaf844174b26d7a39839c19c8f1c8d8cd0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 21:19:50 +0200 Subject: [PATCH 1/9] Merge commit 'db1a31c243a649e1fe20f5466ba181da5be35c14' into subtree-update_cg_gcc_2025-04-18 --- .github/workflows/ci.yml | 25 +- .github/workflows/failures.yml | 24 +- .github/workflows/gcc12.yml | 25 +- .github/workflows/m68k.yml | 25 +- .github/workflows/release.yml | 25 +- .github/workflows/stdarch.yml | 25 +- Cargo.lock | 8 +- Cargo.toml | 2 +- Readme.md | 4 +- build_system/src/clone_gcc.rs | 2 +- build_system/src/test.rs | 21 +- doc/add-attribute.md | 2 +- example/mini_core.rs | 48 +++ libgccjit.version | 2 +- ...022-core-Disable-not-compiling-tests.patch | 44 --- ...0028-core-Disable-long-running-tests.patch | 26 +- ...001-Disable-libstd-and-libtest-dylib.patch | 18 +- ...0001-core-Disable-portable-simd-test.patch | 32 +- rust-toolchain | 2 +- src/abi.rs | 48 ++- src/asm.rs | 289 ++++++++++-------- src/builder.rs | 55 +++- src/context.rs | 41 +-- src/declare.rs | 25 +- src/gcc_util.rs | 1 + src/int.rs | 15 +- src/intrinsic/llvm.rs | 287 ++++++++++++++--- src/intrinsic/mod.rs | 1 + src/intrinsic/simd.rs | 10 +- src/lib.rs | 4 +- tests/failing-ui-tests.txt | 8 +- tests/run/abort1.rs | 38 +-- tests/run/abort2.rs | 38 +-- tests/run/array.rs | 10 +- tests/run/asm.rs | 53 ++++ tests/run/assign.rs | 126 +------- tests/run/closure.rs | 41 +-- tests/run/condition.rs | 26 +- tests/run/empty_main.rs | 30 +- tests/run/exit.rs | 37 +-- tests/run/exit_code.rs | 30 +- tests/run/float.rs | 28 ++ tests/run/fun_ptr.rs | 9 +- tests/run/int.rs | 4 +- tests/run/mut_ref.rs | 130 +------- tests/run/operations.rs | 222 +------------- tests/run/ptr_cast.rs | 29 +- tests/run/return-tuple.rs | 47 +-- tests/run/slice.rs | 13 +- tests/run/static.rs | 77 +---- tests/run/structs.rs | 37 +-- tests/run/tuple.rs | 37 +-- 52 files changed, 962 insertions(+), 1244 deletions(-) delete mode 100644 patches/0022-core-Disable-not-compiling-tests.patch create mode 100644 tests/run/float.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f96912e6b7a83..ef024258ffc86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,10 @@ name: CI on: - - push - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -121,3 +123,22 @@ jobs: run: | cd build_system cargo test + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success: + needs: [build, duplicates, build_system] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index d080bbfe91fe6..bc42eb1468ea2 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -2,7 +2,10 @@ name: Failures on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -108,3 +111,22 @@ jobs: echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!" 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_failures: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index bb9e020dc6a4c..da9a1506855c3 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -1,8 +1,10 @@ name: CI libgccjit 12 on: - - push - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -85,3 +87,22 @@ jobs: #- name: Run tests #run: | #./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_gcc12: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index ed1fc02bd9131..21731f7087e2c 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -3,8 +3,10 @@ name: m68k CI on: - - push - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -105,3 +107,22 @@ jobs: - name: Run tests run: | ./y.sh test --release --clean --build-sysroot --sysroot-features compiler_builtins/no-f16-f128 ${{ matrix.commands }} + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_m68k: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 886ce90b4713e..47a40286554e4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,10 @@ name: CI with sysroot compiled in release mode on: - - push - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -82,3 +84,22 @@ jobs: echo "Test is done with LTO enabled, hence inlining should occur across crates" 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: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index d5ae6144496f1..4b9f48e7b1835 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -1,8 +1,10 @@ name: stdarch tests with sysroot compiled in release mode on: - - push - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read @@ -102,3 +104,22 @@ jobs: # TODO: remove --skip test_mm512_stream_ps when stdarch is updated in rustc. # TODO: remove --skip test_tile_ when it's implemented. STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features --cfg stdarch_intel_sde" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_mm512_stream_ps --skip test_tile_ + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_stdarch: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/Cargo.lock b/Cargo.lock index 636e75b94a3f2..832603aa79252 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8" +checksum = "2895ddec764de7ac76fe6c056050c4801a80109c066f177a00a9cc8dee02b29b" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d" +checksum = "ac133db68db8a6a8b2c51ef4b18d8ea16682d5814c4641272fe37bbbc223d5f3" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 63d37358561e6..b50f2a626d57c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -gccjit = "2.4" +gccjit = "2.5" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } # Local copy. diff --git a/Readme.md b/Readme.md index e92c16ece2f10..d0e4dbba6d355 100644 --- a/Readme.md +++ b/Readme.md @@ -23,7 +23,7 @@ A secondary goal is to check if using the gcc backend will provide any run-time ## Building **This requires a patched libgccjit in order to work. -You need to use my [fork of gcc](https://github.com/antoyo/gcc) which already includes these patches.** +You need to use my [fork of gcc](https://github.com/rust-lang/gcc) which already includes these patches.** ```bash $ cp config.example.toml config.toml @@ -40,7 +40,7 @@ to do a few more things. To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue): ```bash -$ git clone https://github.com/antoyo/gcc +$ git clone https://github.com/rust-lang/gcc $ sudo apt install flex libmpfr-dev libgmp-dev libmpc3 libmpc-dev $ mkdir gcc-build gcc-install $ cd gcc-build diff --git a/build_system/src/clone_gcc.rs b/build_system/src/clone_gcc.rs index e28ee873eb6be..b49dd47f35219 100644 --- a/build_system/src/clone_gcc.rs +++ b/build_system/src/clone_gcc.rs @@ -61,7 +61,7 @@ pub fn run() -> Result<(), String> { return Ok(()); }; - let result = git_clone("https://github.com/antoyo/gcc", Some(&args.out_path), false)?; + let result = git_clone("https://github.com/rust-lang/gcc", Some(&args.out_path), false)?; if result.ran_clone { let gcc_commit = args.config_info.get_gcc_commit()?; println!("Checking out GCC commit `{}`...", gcc_commit); diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 6c29c7d1825b9..df4ac85233b02 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -529,20 +529,21 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); - let extra = - if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; - - let rustc_args = &format!( - r#"-Zpanic-abort-tests \ - -Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \ - --sysroot "{sysroot_dir}" -Cpanic=abort{extra}"#, + let codegen_backend_path = format!( + "{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}", pwd = std::env::current_dir() .map_err(|error| format!("`current_dir` failed: {:?}", error))? .display(), channel = args.config_info.channel.as_str(), dylib_ext = args.config_info.dylib_ext, - sysroot_dir = args.config_info.sysroot_path, - extra = extra, + ); + + let extra = + if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; + + let rustc_args = format!( + "-Zpanic-abort-tests -Zcodegen-backend={codegen_backend_path} --sysroot {} -Cpanic=abort{extra}", + args.config_info.sysroot_path ); run_command_with_env( @@ -677,7 +678,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[TEST] libcore"); - let path = get_sysroot_dir().join("sysroot_src/library/core/tests"); + let path = get_sysroot_dir().join("sysroot_src/library/coretests"); let _ = remove_dir_all(path.join("target")); run_cargo_command(&[&"test"], Some(&path), env, args)?; Ok(()) diff --git a/doc/add-attribute.md b/doc/add-attribute.md index ae3bcc5e2ebe2..267c181952556 100644 --- a/doc/add-attribute.md +++ b/doc/add-attribute.md @@ -14,4 +14,4 @@ Finally, you need to update this repository by calling the relevant API you adde To test it, build `gcc`, run `cargo update -p gccjit` and then you can test the generated output for a given Rust crate. -[gccjit.rs]: https://github.com/antoyo/gccjit.rs +[gccjit.rs]: https://github.com/rust-lang/gccjit.rs diff --git a/example/mini_core.rs b/example/mini_core.rs index 5544aee9eaf16..c554a87b8256c 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -51,6 +51,10 @@ impl LegacyReceiver for &T {} impl LegacyReceiver for &mut T {} impl LegacyReceiver for Box {} +#[lang = "receiver"] +trait Receiver { +} + #[lang = "copy"] pub trait Copy {} @@ -134,6 +138,14 @@ impl Mul for u8 { } } +impl Mul for i32 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + impl Mul for usize { type Output = Self; @@ -142,6 +154,14 @@ impl Mul for usize { } } +impl Mul for isize { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + #[lang = "add"] pub trait Add { type Output; @@ -165,6 +185,14 @@ impl Add for i8 { } } +impl Add for i32 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + impl Add for usize { type Output = Self; @@ -196,6 +224,14 @@ impl Sub for usize { } } +impl Sub for isize { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + impl Sub for u8 { type Output = Self; @@ -220,6 +256,14 @@ impl Sub for i16 { } } +impl Sub for i32 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + #[lang = "rem"] pub trait Rem { type Output; @@ -628,6 +672,10 @@ pub mod libc { pub fn memcpy(dst: *mut u8, src: *const u8, size: usize); pub fn memmove(dst: *mut u8, src: *const u8, size: usize); pub fn strncpy(dst: *mut u8, src: *const u8, size: usize); + pub fn fflush(stream: *mut i32) -> i32; + pub fn exit(status: i32); + + pub static stdout: *mut i32; } } diff --git a/libgccjit.version b/libgccjit.version index 417fd5b03935d..125b04004b07f 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -e607be166673a8de9fc07f6f02c60426e556c5f2 +0ea98a1365b81f7488073512c850e8ee951a4afd diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch deleted file mode 100644 index 70e3e2ba7fee1..0000000000000 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ /dev/null @@ -1,44 +0,0 @@ -From af0e237f056fa838c77463381a19b0dc993c0a35 Mon Sep 17 00:00:00 2001 -From: None -Date: Sun, 1 Sep 2024 11:42:17 -0400 -Subject: [PATCH] Disable not compiling tests - ---- - library/core/tests/Cargo.toml | 14 ++++++++++++++ - library/core/tests/lib.rs | 1 + - 2 files changed, 15 insertions(+) - create mode 100644 library/core/tests/Cargo.toml - -diff --git a/library/core/tests/Cargo.toml b/library/core/tests/Cargo.toml -new file mode 100644 -index 0000000..ca326ac ---- /dev/null -+++ b/library/core/tests/Cargo.toml -@@ -0,0 +1,14 @@ -+[workspace] -+ -+[package] -+name = "coretests" -+version = "0.0.0" -+edition = "2021" -+ -+[lib] -+name = "coretests" -+path = "lib.rs" -+ -+[dependencies] -+rand = { version = "0.8.5", default-features = false } -+rand_xorshift = { version = "0.3.0", default-features = false } -diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index a4a7946..ecfe43f 100644 ---- a/library/core/tests/lib.rs -+++ b/library/core/tests/lib.rs -@@ -1,4 +1,5 @@ - // tidy-alphabetical-start -+#![cfg(test)] - #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] - #![cfg_attr(test, feature(cfg_match))] - #![feature(alloc_layout_extra)] --- -2.47.1 - diff --git a/patches/0028-core-Disable-long-running-tests.patch b/patches/0028-core-Disable-long-running-tests.patch index dc1beae6d2e71..20df4245cfdf2 100644 --- a/patches/0028-core-Disable-long-running-tests.patch +++ b/patches/0028-core-Disable-long-running-tests.patch @@ -1,17 +1,17 @@ -From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001 -From: bjorn3 -Date: Fri, 3 Dec 2021 12:16:30 +0100 +From ec2d0dc77fb484d926b45bb626b0db6a4bb0ab5c Mon Sep 17 00:00:00 2001 +From: None +Date: Thu, 27 Mar 2025 09:20:41 -0400 Subject: [PATCH] Disable long running tests --- - library/core/tests/slice.rs | 2 ++ + library/coretests/tests/slice.rs | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs -index 8402833..84592e0 100644 ---- a/library/core/tests/slice.rs -+++ b/library/core/tests/slice.rs -@@ -2462,6 +2462,7 @@ take_tests! { +diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs +index d17e681..fba5cd6 100644 +--- a/library/coretests/tests/slice.rs ++++ b/library/coretests/tests/slice.rs +@@ -2486,6 +2486,7 @@ split_off_tests! { #[cfg(not(miri))] // unused in Miri const EMPTY_MAX: &'static [()] = &[(); usize::MAX]; @@ -19,14 +19,14 @@ index 8402833..84592e0 100644 // can't be a constant due to const mutability rules #[cfg(not(miri))] // unused in Miri macro_rules! empty_max_mut { -@@ -2485,6 +2486,7 @@ take_tests! { - (take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), - (take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), +@@ -2509,6 +2510,7 @@ split_off_tests! { + (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), + (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), } +*/ #[test] fn test_slice_from_ptr_range() { -- -2.26.2.7.g19db9cfb68 +2.49.0 diff --git a/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch index c220f53040f05..fa360fe9e74e7 100644 --- a/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch +++ b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch @@ -1,19 +1,18 @@ -From 966beefe08be6045bfcca26079b76a7a80413080 Mon Sep 17 00:00:00 2001 +From b2911e732d1bf0e28872495c4c47af1dad3c7911 Mon Sep 17 00:00:00 2001 From: None -Date: Thu, 28 Sep 2023 17:37:38 -0400 +Date: Thu, 27 Mar 2025 14:30:10 -0400 Subject: [PATCH] Disable libstd and libtest dylib --- - library/std/Cargo.toml | 2 +- - library/test/Cargo.toml | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + library/std/Cargo.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml -index 5b21355..cb0c49b 100644 +index 176da60..c183cdb 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml -@@ -9,7 +9,7 @@ description = "The Rust Standard Library" - edition = "2021" +@@ -10,7 +10,7 @@ edition = "2024" + autobenches = false [lib] -crate-type = ["dylib", "rlib"] @@ -21,3 +20,6 @@ index 5b21355..cb0c49b 100644 [dependencies] alloc = { path = "../alloc", public = true } +-- +2.49.0 + diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 9ef5e0e4f4672..9d5b2dc537d2c 100644 --- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -1,25 +1,17 @@ -From 124a11ce086952a5794d5cfbaa45175809497b81 Mon Sep 17 00:00:00 2001 +From 1a8f6b8e39f343959d4d2e6b6957a6d780ac3fc0 Mon Sep 17 00:00:00 2001 From: None -Date: Sat, 18 Nov 2023 10:50:36 -0500 -Subject: [PATCH] [core] Disable portable-simd test +Date: Thu, 27 Mar 2025 14:32:14 -0400 +Subject: [PATCH] Disable portable-simd test --- - library/core/tests/lib.rs | 2 -- - 1 file changed, 2 deletions(-) + library/coretests/tests/lib.rs | 1 - + 1 file changed, 1 deletion(-) -diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index b71786c..cf484d5 100644 ---- a/library/core/tests/lib.rs -+++ b/library/core/tests/lib.rs -@@ -87,7 +87,6 @@ - #![feature(numfmt)] - #![feature(pattern)] - #![feature(pointer_is_aligned_to)] --#![feature(portable_simd)] - #![feature(ptr_metadata)] - #![feature(slice_from_ptr_range)] - #![feature(slice_internals)] -@@ -155,7 +154,6 @@ mod pin; +diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs +index 79022fe..9223b2f 100644 +--- a/library/coretests/tests/lib.rs ++++ b/library/coretests/tests/lib.rs +@@ -165,7 +165,6 @@ mod pin; mod pin_macro; mod ptr; mod result; @@ -27,4 +19,6 @@ index b71786c..cf484d5 100644 mod slice; mod str; mod str_lossy; --- 2.45.2 +-- +2.49.0 + diff --git a/rust-toolchain b/rust-toolchain index 940b3de9f7453..fd898c59707b0 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-01-12" +channel = "nightly-2025-04-17" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/abi.rs b/src/abi.rs index 9fe6baa3d2573..890a25e6a7ca0 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -9,7 +9,8 @@ use rustc_middle::ty::Ty; 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::callconv::{ArgAttributes, CastTarget, Conv, FnAbi, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -105,6 +106,8 @@ pub trait FnAbiGccExt<'gcc, 'tcx> { // TODO(antoyo): return a function pointer type instead? fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>; fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; + #[cfg(feature = "master")] + fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option>; } impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { @@ -227,4 +230,47 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { ); pointer_type } + + #[cfg(feature = "master")] + fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { + conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) + } +} + +#[cfg(feature = "master")] +pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option> { + // TODO: handle the calling conventions returning None. + let attribute = match conv { + Conv::C + | Conv::Rust + | Conv::CCmseNonSecureCall + | Conv::CCmseNonSecureEntry + | Conv::RiscvInterrupt { .. } => return None, + Conv::Cold => return None, + Conv::PreserveMost => return None, + Conv::PreserveAll => return None, + Conv::GpuKernel => { + // TODO(antoyo): remove clippy allow attribute when this is implemented. + #[allow(clippy::if_same_then_else)] + if arch == "amdgpu" { + return None; + } else if arch == "nvptx64" { + return None; + } else { + panic!("Architecture {} does not support GpuKernel calling convention", arch); + } + } + Conv::AvrInterrupt => return None, + Conv::AvrNonBlockingInterrupt => return None, + Conv::ArmAapcs => return None, + Conv::Msp430Intr => return None, + Conv::X86Fastcall => return None, + Conv::X86Intr => return None, + Conv::X86Stdcall => return None, + Conv::X86ThisCall => return None, + Conv::X86VectorCall => return None, + Conv::X86_64SysV => FnAttribute::SysvAbi, + Conv::X86_64Win64 => FnAttribute::MsAbi, + }; + Some(attribute) } diff --git a/src/asm.rs b/src/asm.rs index 415f8affab901..dbdf37ee6c9ef 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -36,7 +36,8 @@ use crate::type_of::LayoutGccExt; // // 3. Clobbers. GCC has a separate list of clobbers, and clobbers don't have indexes. // Contrary, Rust expresses clobbers through "out" operands that aren't tied to -// a variable (`_`), and such "clobbers" do have index. +// a variable (`_`), and such "clobbers" do have index. Input operands cannot also +// be clobbered. // // 4. Furthermore, GCC Extended Asm does not support explicit register constraints // (like `out("eax")`) directly, offering so-called "local register variables" @@ -161,6 +162,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // Also, we don't emit any asm operands immediately; we save them to // the one of the buffers to be emitted later. + let mut input_registers = vec![]; + + for op in rust_operands { + if let InlineAsmOperandRef::In { reg, .. } = *op { + if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) { + input_registers.push(reg_name); + } + } + } + // 1. Normal variables (and saving operands to buffers). for (rust_idx, op) in rust_operands.iter().enumerate() { match *op { @@ -183,25 +194,39 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { continue; } (Register(reg_name), None) => { - // `clobber_abi` can add lots of clobbers that are not supported by the target, - // such as AVX-512 registers, so we just ignore unsupported registers - let is_target_supported = - reg.reg_class().supported_types(asm_arch, true).iter().any( - |&(_, feature)| { - if let Some(feature) = feature { - self.tcx - .asm_target_features(instance.def_id()) - .contains(&feature) - } else { - true // Register class is unconditionally supported - } - }, - ); - - if is_target_supported && !clobbers.contains(®_name) { - clobbers.push(reg_name); + if input_registers.contains(®_name) { + // the `clobber_abi` operand is converted into a series of + // `lateout("reg") _` operands. Of course, a user could also + // explicitly define such an output operand. + // + // GCC does not allow input registers to be clobbered, so if this out register + // is also used as an in register, do not add it to the clobbers list. + // it will be treated as a lateout register with `out_place: None` + if !late { + bug!("input registers can only be used as lateout regisers"); + } + ("r", dummy_output_type(self.cx, reg.reg_class())) + } else { + // `clobber_abi` can add lots of clobbers that are not supported by the target, + // such as AVX-512 registers, so we just ignore unsupported registers + let is_target_supported = + reg.reg_class().supported_types(asm_arch, true).iter().any( + |&(_, feature)| { + if let Some(feature) = feature { + self.tcx + .asm_target_features(instance.def_id()) + .contains(&feature) + } else { + true // Register class is unconditionally supported + } + }, + ); + + if is_target_supported && !clobbers.contains(®_name) { + clobbers.push(reg_name); + } + continue; } - continue; } }; @@ -230,13 +255,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => { - let constraint = - if let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) { - constraint - } else { - // left for the next pass - continue; - }; + let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) else { + // left for the next pass + continue; + }; // Rustc frontend guarantees that input and output types are "compatible", // so we can just use input var's type for the output variable. @@ -589,114 +611,127 @@ fn estimate_template_length( } /// Converts a register class to a GCC constraint code. -fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { - let constraint = match reg { - // For vector registers LLVM wants the register name to match the type size. +fn reg_to_gcc(reg_or_reg_class: InlineAsmRegOrRegClass) -> ConstraintOrRegister { + match reg_or_reg_class { InlineAsmRegOrRegClass::Reg(reg) => { - match reg { - InlineAsmReg::X86(_) => { - // TODO(antoyo): add support for vector register. - // - // // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 - return ConstraintOrRegister::Register(match reg.name() { - // Some of registers' names does not map 1-1 from rust to gcc - "st(0)" => "st", + ConstraintOrRegister::Register(explicit_reg_to_gcc(reg)) + } + InlineAsmRegOrRegClass::RegClass(reg_class) => { + ConstraintOrRegister::Constraint(reg_class_to_gcc(reg_class)) + } + } +} - name => name, - }); +fn explicit_reg_to_gcc(reg: InlineAsmReg) -> &'static str { + // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 + match reg { + InlineAsmReg::X86(reg) => { + // TODO(antoyo): add support for vector register. + match reg.reg_class() { + X86InlineAsmRegClass::reg_byte => { + // GCC does not support the `b` suffix, so we just strip it + // see https://github.com/rust-lang/rustc_codegen_gcc/issues/485 + reg.name().trim_end_matches('b') } + _ => match reg.name() { + // Some of registers' names does not map 1-1 from rust to gcc + "st(0)" => "st", - _ => unimplemented!(), + name => name, + }, } } - // They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html - InlineAsmRegOrRegClass::RegClass(reg) => match reg { - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", - InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", - // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for - // "define_constraint". - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h", - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r", - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l", - - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r", - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q", - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q", - InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) - | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", - InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", - InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk", - InlineAsmRegClass::X86( - X86InlineAsmRegClass::kreg0 - | X86InlineAsmRegClass::x87_reg - | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::tmm_reg, - ) => unreachable!("clobber-only"), - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("GCC backend does not support SPIR-V") - } - InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), - InlineAsmRegClass::Err => unreachable!(), - }, - }; - ConstraintOrRegister::Constraint(constraint) + _ => unimplemented!(), + } +} + +/// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html +fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { + match reg_class { + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", + // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for + // "define_constraint". + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h", + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r", + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l", + + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) + | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r", + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q", + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q", + InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) + | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", + InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", + InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk", + InlineAsmRegClass::X86( + X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::x87_reg + | X86InlineAsmRegClass::mmx_reg + | X86InlineAsmRegClass::tmm_reg, + ) => unreachable!("clobber-only"), + InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { + bug!("GCC backend does not support SPIR-V") + } + InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), + InlineAsmRegClass::Err => unreachable!(), + } } /// Type to use for outputs that are discarded. It doesn't really matter what diff --git a/src/builder.rs b/src/builder.rs index 6573b5b165e61..5c70f4a7df93c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -368,16 +368,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let previous_arg_count = args.len(); let orig_args = args; let args = { - let function_address_names = self.function_address_names.borrow(); - let original_function_name = function_address_names.get(&func_ptr); func_ptr = llvm::adjust_function(self.context, &func_name, func_ptr, args); - llvm::adjust_intrinsic_arguments( - self, - gcc_func, - args.into(), - &func_name, - original_function_name, - ) + llvm::adjust_intrinsic_arguments(self, gcc_func, args.into(), &func_name) }; let args_adjusted = args.len() != previous_arg_count; let args = self.check_ptr_call("call", func_ptr, &args); @@ -1271,7 +1263,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { - self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) + // LLVM has a concept of "unordered compares", where eg ULT returns true if either the two + // arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does + // not natively have this concept, so in some cases we must manually handle NaNs + let must_handle_nan = match op { + RealPredicate::RealPredicateFalse => unreachable!(), + RealPredicate::RealOEQ => false, + RealPredicate::RealOGT => false, + RealPredicate::RealOGE => false, + RealPredicate::RealOLT => false, + RealPredicate::RealOLE => false, + RealPredicate::RealONE => false, + RealPredicate::RealORD => unreachable!(), + RealPredicate::RealUNO => unreachable!(), + RealPredicate::RealUEQ => false, + RealPredicate::RealUGT => true, + RealPredicate::RealUGE => true, + RealPredicate::RealULT => true, + RealPredicate::RealULE => true, + RealPredicate::RealUNE => false, + RealPredicate::RealPredicateTrue => unreachable!(), + }; + + let cmp = self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs); + + if must_handle_nan { + let is_nan = self.context.new_binary_op( + self.location, + BinaryOp::LogicalOr, + self.cx.bool_type, + // compare a value to itself to check whether it is NaN + self.context.new_comparison(self.location, ComparisonOp::NotEquals, lhs, lhs), + self.context.new_comparison(self.location, ComparisonOp::NotEquals, rhs, rhs), + ); + + self.context.new_binary_op( + self.location, + BinaryOp::LogicalOr, + self.cx.bool_type, + is_nan, + cmp, + ) + } else { + cmp + } } /* Miscellaneous instructions */ diff --git a/src/context.rs b/src/context.rs index 1e1f577bb3a15..73718994e6417 100644 --- a/src/context.rs +++ b/src/context.rs @@ -23,6 +23,8 @@ use rustc_target::spec::{ HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi, }; +#[cfg(feature = "master")] +use crate::abi::conv_to_fn_attribute; use crate::callee::get_fn; use crate::common::SignType; @@ -213,33 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let bool_type = context.new_type::(); let mut functions = FxHashMap::default(); - let builtins = [ - "__builtin_unreachable", - "abort", - "__builtin_expect", /*"__builtin_expect_with_probability",*/ - "__builtin_constant_p", - "__builtin_add_overflow", - "__builtin_mul_overflow", - "__builtin_saddll_overflow", - /*"__builtin_sadd_overflow",*/ - "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ - "__builtin_ssubll_overflow", - /*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow", - "__builtin_uaddll_overflow", - "__builtin_uadd_overflow", - "__builtin_umulll_overflow", - "__builtin_umul_overflow", - "__builtin_usubll_overflow", - "__builtin_usub_overflow", - "__builtin_powif", - "__builtin_powi", - "fabsf", - "fabs", - "copysignf", - "copysign", - "nearbyintf", - "nearbyint", - ]; + let builtins = ["abort"]; for builtin in builtins.iter() { functions.insert(builtin.to_string(), context.get_builtin_function(builtin)); @@ -509,7 +485,11 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn declare_c_main(&self, fn_type: Self::Type) -> Option { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { - Some(self.declare_entry_fn(entry_name, fn_type, ())) + #[cfg(feature = "master")] + 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)) } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} @@ -605,7 +585,10 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { let mut name = String::with_capacity(prefix.len() + 6); name.push_str(prefix); name.push('.'); - name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY)); + // Offset the index by the base so that always at least two characters + // are generated. This avoids cases where the suffix is interpreted as + // size by the assembler (for m68k: .b, .w, .l). + name.push_str(&(idx as u64 + ALPHANUMERIC_ONLY as u64).to_base(ALPHANUMERIC_ONLY)); name } } diff --git a/src/declare.rs b/src/declare.rs index 7cdbe3c0c6290..c1ca3eb849e88 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -58,7 +58,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { variadic: bool, ) -> Function<'gcc> { self.linkage.set(FunctionType::Extern); - declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, params, variadic) + declare_raw_fn(self, name, None, return_type, params, variadic) } pub fn declare_global( @@ -92,7 +92,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { &self, name: &str, _fn_type: Type<'gcc>, - callconv: (), /*llvm::CCallConv*/ + #[cfg(feature = "master")] callconv: Option>, + #[cfg(not(feature = "master"))] callconv: Option<()>, ) -> RValue<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::().make_pointer().make_pointer(); @@ -123,14 +124,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn_attributes, } = fn_abi.gcc_type(self); - let func = declare_raw_fn( - self, - name, - (), /*fn_abi.llvm_cconv()*/ - return_type, - &arguments_type, - is_c_variadic, - ); + #[cfg(feature = "master")] + let conv = fn_abi.gcc_cconv(self); + #[cfg(not(feature = "master"))] + let conv = None; + let func = declare_raw_fn(self, name, conv, return_type, &arguments_type, is_c_variadic); self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices); #[cfg(feature = "master")] for fn_attr in fn_attributes { @@ -162,7 +160,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { fn declare_raw_fn<'gcc>( cx: &CodegenCx<'gcc, '_>, name: &str, - _callconv: (), /*llvm::CallConv*/ + #[cfg(feature = "master")] callconv: Option>, + #[cfg(not(feature = "master"))] _callconv: Option<()>, return_type: Type<'gcc>, param_types: &[Type<'gcc>], variadic: bool, @@ -192,6 +191,10 @@ fn declare_raw_fn<'gcc>( let name = &mangle_name(name); let func = cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic); + #[cfg(feature = "master")] + if let Some(attribute) = callconv { + func.add_attribute(attribute); + } cx.functions.borrow_mut().insert(name.to_string(), func); #[cfg(feature = "master")] diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 6eae0c24f48ad..202764d564916 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -194,6 +194,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> fn arch_to_gcc(name: &str) -> &str { match name { + "M68000" => "68000", "M68020" => "68020", _ => name, } diff --git a/src/int.rs b/src/int.rs index f3552d9b12fcb..906d7eaceb6be 100644 --- a/src/int.rs +++ b/src/int.rs @@ -432,8 +432,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { ); self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr]) }; - - (result, self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue()) + // NOTE: we must assign the result of the operation to a variable at this point to make + // sure it will be evaluated by libgccjit now. + // Otherwise, it will only be evaluated when the rvalue for the call is used somewhere else + // and overflow_value will not be initialized at the correct point in the program. + let result = self.current_func().new_local(self.location, res_type, "result"); + self.block.add_assignment(self.location, result, call); + + ( + result.to_rvalue(), + self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue(), + ) } pub fn gcc_icmp( @@ -865,6 +874,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let value_type = value.get_type(); if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type) { + // TODO: use self.location. self.context.new_cast(None, value, dest_typ) } else if self.is_native_int_type_or_bool(dest_typ) { self.context.new_cast(None, self.low(value), dest_typ) @@ -905,6 +915,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let name_suffix = match self.type_kind(dest_typ) { TypeKind::Float => "tisf", TypeKind::Double => "tidf", + TypeKind::FP128 => "tixf", kind => panic!("cannot cast a non-native integer to type {:?}", kind), }; let sign = if signed { "" } else { "un" }; diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 2d731f88d7d36..0eebd21001a90 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1,11 +1,90 @@ use std::borrow::Cow; -use gccjit::{CType, Context, Function, FunctionPtrType, RValue, ToRValue, UnaryOp}; +use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue, Type}; use rustc_codegen_ssa::traits::BuilderMethods; use crate::builder::Builder; use crate::context::CodegenCx; +fn encode_key_128_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u32_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let encode_type = builder.context.new_struct_type( + None, + "EncodeKey128Output", + &[field1, field2, field3, field4, field5, field6, field7], + ); + #[cfg(feature = "master")] + encode_type.as_type().set_packed(); + (encode_type.as_type(), field1, field2) +} + +fn encode_key_256_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u32_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let field8 = builder.context.new_field(None, m128i, "field8"); + let encode_type = builder.context.new_struct_type( + None, + "EncodeKey256Output", + &[field1, field2, field3, field4, field5, field6, field7, field8], + ); + #[cfg(feature = "master")] + encode_type.as_type().set_packed(); + (encode_type.as_type(), field1, field2) +} + +fn aes_output_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u8_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let aes_output_type = builder.context.new_struct_type(None, "AesOutput", &[field1, field2]); + let typ = aes_output_type.as_type(); + #[cfg(feature = "master")] + typ.set_packed(); + (typ, field1, field2) +} + +fn wide_aes_output_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u8_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let field8 = builder.context.new_field(None, m128i, "field8"); + let field9 = builder.context.new_field(None, m128i, "field9"); + let aes_output_type = builder.context.new_struct_type( + None, + "WideAesOutput", + &[field1, field2, field3, field4, field5, field6, field7, field8, field9], + ); + #[cfg(feature = "master")] + aes_output_type.as_type().set_packed(); + (aes_output_type.as_type(), field1, field2) +} + #[cfg_attr(not(feature = "master"), allow(unused_variables))] pub fn adjust_function<'gcc>( context: &'gcc Context<'gcc>, @@ -43,7 +122,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, - original_function_name: Option<&String>, ) -> Cow<'b, [RValue<'gcc>]> { // TODO: this might not be a good way to workaround the missing tile builtins. if func_name == "__builtin_trap" { @@ -504,6 +582,72 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( let arg4 = builder.context.new_rvalue_from_int(arg4_type, -1); args = vec![a, b, c, arg4, new_args[3]].into(); } + "__builtin_ia32_encodekey128_u32" => { + let mut new_args = args.to_vec(); + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let array_type = builder.context.new_array_type(None, m128i, 6); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + args = new_args.into(); + } + "__builtin_ia32_encodekey256_u32" => { + let mut new_args = args.to_vec(); + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let array_type = builder.context.new_array_type(None, m128i, 7); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + args = new_args.into(); + } + "__builtin_ia32_aesenc128kl_u8" + | "__builtin_ia32_aesdec128kl_u8" + | "__builtin_ia32_aesenc256kl_u8" + | "__builtin_ia32_aesdec256kl_u8" => { + let mut new_args = vec![]; + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let result = builder.current_func().new_local(None, m128i, "result"); + new_args.push(result.get_address(None)); + new_args.extend(args.to_vec()); + args = new_args.into(); + } + "__builtin_ia32_aesencwide128kl_u8" + | "__builtin_ia32_aesdecwide128kl_u8" + | "__builtin_ia32_aesencwide256kl_u8" + | "__builtin_ia32_aesdecwide256kl_u8" => { + let mut new_args = vec![]; + + let mut old_args = args.to_vec(); + let handle = old_args.swap_remove(0); // Called __P in GCC. + let first_value = old_args.swap_remove(0); + + let element_type = first_value.get_type(); + let array_type = builder.context.new_array_type(None, element_type, 8); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + + let array = builder.current_func().new_local(None, array_type, "array"); + let input = builder.context.new_array_constructor( + None, + array_type, + &[ + first_value, + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + ], + ); + builder.llbb().add_assignment(None, array, input); + let input_ptr = array.get_address(None); + let arg2_type = gcc_func.get_param_type(1); + let input_ptr = builder.context.new_cast(None, input_ptr, arg2_type); + new_args.push(input_ptr); + + new_args.push(handle); + args = new_args.into(); + } _ => (), } } else { @@ -541,33 +685,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 2]); args = vec![a, b, c, new_args[3]].into(); } - "__builtin_ia32_vfmaddsubpd256" - | "__builtin_ia32_vfmaddsubps" - | "__builtin_ia32_vfmaddsubps256" - | "__builtin_ia32_vfmaddsubpd" => { - if let Some(original_function_name) = original_function_name { - match &**original_function_name { - "llvm.x86.fma.vfmsubadd.pd.256" - | "llvm.x86.fma.vfmsubadd.ps" - | "llvm.x86.fma.vfmsubadd.ps.256" - | "llvm.x86.fma.vfmsubadd.pd" => { - // NOTE: since both llvm.x86.fma.vfmsubadd.ps and llvm.x86.fma.vfmaddsub.ps maps to - // __builtin_ia32_vfmaddsubps, only add minus if this comes from a - // subadd LLVM intrinsic, e.g. _mm256_fmsubadd_pd. - let mut new_args = args.to_vec(); - let arg3 = &mut new_args[2]; - *arg3 = builder.context.new_unary_op( - None, - UnaryOp::Minus, - arg3.get_type(), - *arg3, - ); - args = new_args.into(); - } - _ => (), - } - } - } "__builtin_ia32_ldmxcsr" => { // The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer, // so dereference the pointer. @@ -728,6 +845,96 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( let f16_type = builder.context.new_c_type(CType::Float16); return_value = builder.context.new_cast(None, return_value, f16_type); } + "__builtin_ia32_encodekey128_u32" => { + // The builtin __builtin_ia32_encodekey128_u32 writes the result in its pointer argument while + // llvm.x86.encodekey128 returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (encode_type, field1, field2) = encode_key_128_type(builder); + let result = builder.current_func().new_local(None, encode_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 6); + let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } + "__builtin_ia32_encodekey256_u32" => { + // The builtin __builtin_ia32_encodekey256_u32 writes the result in its pointer argument while + // llvm.x86.encodekey256 returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (encode_type, field1, field2) = encode_key_256_type(builder); + let result = builder.current_func().new_local(None, encode_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 7); + let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } + "__builtin_ia32_aesdec128kl_u8" + | "__builtin_ia32_aesenc128kl_u8" + | "__builtin_ia32_aesdec256kl_u8" + | "__builtin_ia32_aesenc256kl_u8" => { + // The builtin for aesdec/aesenc writes the result in its pointer argument while + // llvm.x86.aesdec128kl returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (aes_output_type, field1, field2) = aes_output_type(builder); + let result = builder.current_func().new_local(None, aes_output_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let ptr = builder.context.new_cast( + None, + args[0], + field2.to_rvalue().get_type().make_pointer(), + ); + builder.llbb().add_assignment(None, field2, ptr.dereference(None)); + return_value = result.to_rvalue(); + } + "__builtin_ia32_aesencwide128kl_u8" + | "__builtin_ia32_aesdecwide128kl_u8" + | "__builtin_ia32_aesencwide256kl_u8" + | "__builtin_ia32_aesdecwide256kl_u8" => { + // The builtin for aesdecwide/aesencwide writes the result in its pointer argument while + // llvm.x86.aesencwide128kl returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (aes_output_type, field1, field2) = wide_aes_output_type(builder); + let result = builder.current_func().new_local(None, aes_output_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 8); + let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } _ => (), } @@ -915,16 +1122,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.ctlz.v4i64" => "__builtin_ia32_vplzcntq_256_mask", "llvm.ctlz.v2i64" => "__builtin_ia32_vplzcntq_128_mask", "llvm.ctpop.v32i16" => "__builtin_ia32_vpopcountw_v32hi", - "llvm.x86.fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd3", - "llvm.x86.fma.vfmsub.ss" => "__builtin_ia32_vfmsubss3", - "llvm.x86.fma.vfmsubadd.pd" => "__builtin_ia32_vfmaddsubpd", - "llvm.x86.fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmaddsubpd256", - "llvm.x86.fma.vfmsubadd.ps" => "__builtin_ia32_vfmaddsubps", - "llvm.x86.fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmaddsubps256", - "llvm.x86.fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd3", - "llvm.x86.fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss3", - "llvm.x86.fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd3", - "llvm.x86.fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss3", "llvm.x86.avx512.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", "llvm.x86.avx512.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", "llvm.x86.avx512.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", @@ -1002,8 +1199,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.fshr.v32i16" => "__builtin_ia32_vpshrdv_v32hi", "llvm.fshr.v16i16" => "__builtin_ia32_vpshrdv_v16hi", "llvm.fshr.v8i16" => "__builtin_ia32_vpshrdv_v8hi", - "llvm.x86.fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd3", - "llvm.x86.fma.vfmadd.ss" => "__builtin_ia32_vfmaddss3", "llvm.x86.rdrand.64" => "__builtin_ia32_rdrand64_step", // The above doc points to unknown builtins for the following, so override them: @@ -1324,6 +1519,16 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.avx512fp16.mask.vfmadd.cph.256" => "__builtin_ia32_vfmaddcph256_mask3", "llvm.x86.avx512fp16.mask.vfcmadd.cph.128" => "__builtin_ia32_vfcmaddcph128_mask3", "llvm.x86.avx512fp16.mask.vfmadd.cph.128" => "__builtin_ia32_vfmaddcph128_mask3", + "llvm.x86.encodekey128" => "__builtin_ia32_encodekey128_u32", + "llvm.x86.encodekey256" => "__builtin_ia32_encodekey256_u32", + "llvm.x86.aesenc128kl" => "__builtin_ia32_aesenc128kl_u8", + "llvm.x86.aesdec128kl" => "__builtin_ia32_aesdec128kl_u8", + "llvm.x86.aesenc256kl" => "__builtin_ia32_aesenc256kl_u8", + "llvm.x86.aesdec256kl" => "__builtin_ia32_aesdec256kl_u8", + "llvm.x86.aesencwide128kl" => "__builtin_ia32_aesencwide128kl_u8", + "llvm.x86.aesdecwide128kl" => "__builtin_ia32_aesdecwide128kl_u8", + "llvm.x86.aesencwide256kl" => "__builtin_ia32_aesencwide256kl_u8", + "llvm.x86.aesdecwide256kl" => "__builtin_ia32_aesdecwide256kl_u8", // TODO: support the tile builtins: "llvm.x86.ldtilecfg" => "__builtin_trap", diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index f38622074f18b..d22f4229e2374 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -78,6 +78,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::maxnumf64 => "fmax", sym::copysignf32 => "copysignf", sym::copysignf64 => "copysign", + sym::copysignf128 => "copysignl", sym::floorf32 => "floorf", sym::floorf64 => "floor", sym::ceilf32 => "ceilf", diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 8b454ab2a4241..6d40d5297f1a0 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -399,7 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - if name == sym::simd_insert { + if name == sym::simd_insert || name == sym::simd_insert_dyn { require!( in_elem == arg_tys[2], InvalidMonomorphization::InsertedType { @@ -410,6 +410,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( out_ty: arg_tys[2] } ); + + // TODO(antoyo): For simd_insert, check if the index is a constant of the correct size. let vector = args[0].immediate(); let index = args[1].immediate(); let value = args[2].immediate(); @@ -422,13 +424,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - if name == sym::simd_extract { + if name == sym::simd_extract || name == sym::simd_extract_dyn { require!( ret_ty == in_elem, InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); + // TODO(antoyo): For simd_extract, check if the index is a constant of the correct size. let vector = args[0].immediate(); - return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); + let index = args[1].immediate(); + return Ok(bx.context.new_vector_access(None, vector, index).to_rvalue()); } if name == sym::simd_select { diff --git a/src/lib.rs b/src/lib.rs index bfa23174a19d9..624fdb4043c7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,10 +188,10 @@ impl CodegenBackend for GccCodegenBackend { crate::DEFAULT_LOCALE_RESOURCE } - fn init(&self, sess: &Session) { + fn init(&self, _sess: &Session) { #[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/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 082958bfe1f85..499c1a962311c 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -1,11 +1,9 @@ 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/multiple-clobber-abi.rs tests/ui/functions-closures/parallel-codegen-closures.rs tests/ui/linkage-attr/linkage1.rs tests/ui/lto/dylib-works.rs -tests/ui/numbers-arithmetic/saturating-float-casts.rs tests/ui/sepcomp/sepcomp-cci.rs tests/ui/sepcomp/sepcomp-extern.rs tests/ui/sepcomp/sepcomp-fns-backwards.rs @@ -33,7 +31,6 @@ tests/ui/unwind-no-uwtable.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/issues/issue-40883.rs tests/ui/issues/issue-43853.rs tests/ui/issues/issue-47364.rs tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs @@ -102,14 +99,12 @@ tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs -tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs -tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs @@ -117,8 +112,9 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs -tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs 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/uninhabited/uninhabited-transparent-return-abi.rs diff --git a/tests/run/abort1.rs b/tests/run/abort1.rs index fe46d9ae41849..ff2bb75ece22a 100644 --- a/tests/run/abort1.rs +++ b/tests/run/abort1.rs @@ -3,45 +3,13 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn test_fail() -> ! { unsafe { intrinsics::abort() }; diff --git a/tests/run/abort2.rs b/tests/run/abort2.rs index 4123f4f4beebc..781f518e0b222 100644 --- a/tests/run/abort2.rs +++ b/tests/run/abort2.rs @@ -3,45 +3,13 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn fail() -> i32 { unsafe { intrinsics::abort() }; diff --git a/tests/run/array.rs b/tests/run/array.rs index e18a4ced6bc46..3ab0c309fdeae 100644 --- a/tests/run/array.rs +++ b/tests/run/array.rs @@ -8,20 +8,12 @@ // 10 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; - } -} +use mini_core::*; static mut ONE: usize = 1; diff --git a/tests/run/asm.rs b/tests/run/asm.rs index 4e05d026868e7..2dbf43be664dc 100644 --- a/tests/run/asm.rs +++ b/tests/run/asm.rs @@ -174,6 +174,59 @@ fn asm() { mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3); } assert_eq!(array1, array2); + + // in and clobber registers cannot overlap. This tests that the lateout register without an + // output place (indicated by the `_`) is not added to the list of clobbered registers + let x = 8; + let y: i32; + unsafe { + asm!( + "mov rax, rdi", + in("rdi") x, + lateout("rdi") _, + out("rax") y, + ); + } + assert_eq!((x, y), (8, 8)); + + // sysv64 is the default calling convention on unix systems. The rdi register is + // used to pass arguments in the sysv64 calling convention, so this register will be clobbered + #[cfg(unix)] + { + let x = 16; + let y: i32; + unsafe { + asm!( + "mov rax, rdi", + in("rdi") x, + out("rax") y, + clobber_abi("sysv64"), + ); + } + assert_eq!((x, y), (16, 16)); + } + + // the `b` suffix for registers in the `reg_byte` register class is not supported in GCC + // and needs to be stripped in order to use these registers. + unsafe { + core::arch::asm!( + "", + out("al") _, + out("bl") _, + out("cl") _, + out("dl") _, + out("sil") _, + out("dil") _, + out("r8b") _, + out("r9b") _, + out("r10b") _, + out("r11b") _, + out("r12b") _, + out("r13b") _, + out("r14b") _, + out("r15b") _, + ); + } } #[cfg(not(target_arch = "x86_64"))] diff --git a/tests/run/assign.rs b/tests/run/assign.rs index 286155852d50f..4535ab5778e93 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -5,130 +5,13 @@ // 7 8 // 10 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i32 {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - pub fn printf(format: *const i8, ...) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn inc_ref(num: &mut isize) -> isize { *num = *num + 5; @@ -139,9 +22,8 @@ fn inc(num: isize) -> isize { num + 1 } - #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 { argc = inc(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); diff --git a/tests/run/closure.rs b/tests/run/closure.rs index c7a236f74f9e6..a8a3fadfed47b 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -9,55 +9,38 @@ // Both args: 11 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 { let string = "Arg: %d\n\0"; - let mut closure = || { - unsafe { - libc::printf(string as *const str as *const i8, argc); - } + let mut closure = || unsafe { + libc::printf(string as *const str as *const i8, argc); }; closure(); - let mut closure = || { - unsafe { - libc::printf("Argument: %d\n\0" as *const str as *const i8, argc); - } + let mut closure = || unsafe { + libc::printf("Argument: %d\n\0" as *const str as *const i8, argc); }; closure(); - let mut closure = |string| { - unsafe { - libc::printf(string as *const str as *const i8, argc); - } + let mut closure = |string| unsafe { + libc::printf(string as *const str as *const i8, argc); }; closure("String arg: %d\n\0"); - let mut closure = |arg: isize| { - unsafe { - libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg); - } + let mut closure = |arg: isize| unsafe { + libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg); }; closure(argc + 1); - let mut closure = |string, arg: isize| { - unsafe { - libc::printf(string as *const str as *const i8, arg); - } + let mut closure = |string, arg: isize| unsafe { + libc::printf(string as *const str as *const i8, arg); }; closure("Both args: %d\n\0", argc + 10); diff --git a/tests/run/condition.rs b/tests/run/condition.rs index b02359702ed2e..bd3b6f7497fbd 100644 --- a/tests/run/condition.rs +++ b/tests/run/condition.rs @@ -6,19 +6,12 @@ // 1 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { @@ -27,15 +20,14 @@ extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { libc::printf(b"true\n\0" as *const u8 as *const i8); } - let string = - match argc { - 1 => b"1\n\0", - 2 => b"2\n\0", - 3 => b"3\n\0", - 4 => b"4\n\0", - 5 => b"5\n\0", - _ => b"_\n\0", - }; + let string = match argc { + 1 => b"1\n\0", + 2 => b"2\n\0", + 3 => b"3\n\0", + 4 => b"4\n\0", + 5 => b"5\n\0", + _ => b"_\n\0", + }; libc::printf(string as *const u8 as *const i8); } 0 diff --git a/tests/run/empty_main.rs b/tests/run/empty_main.rs index 042e44080c53a..fe3df5a2389ca 100644 --- a/tests/run/empty_main.rs +++ b/tests/run/empty_main.rs @@ -3,37 +3,13 @@ // Run-time: // status: 0 -#![feature(auto_traits, lang_items, no_core)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { diff --git a/tests/run/exit.rs b/tests/run/exit.rs index 9a7c91c0adb20..e0a59174bd383 100644 --- a/tests/run/exit.rs +++ b/tests/run/exit.rs @@ -3,44 +3,13 @@ // Run-time: // status: 2 -#![feature(auto_traits, lang_items, no_core, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -mod libc { - #[link(name = "c")] - extern "C" { - pub fn exit(status: i32); - } -} - -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { diff --git a/tests/run/exit_code.rs b/tests/run/exit_code.rs index c50d2b0d7107c..376824da845c3 100644 --- a/tests/run/exit_code.rs +++ b/tests/run/exit_code.rs @@ -3,37 +3,13 @@ // Run-time: // status: 1 -#![feature(auto_traits, lang_items, no_core)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { diff --git a/tests/run/float.rs b/tests/run/float.rs new file mode 100644 index 0000000000000..424fa1cf4ad53 --- /dev/null +++ b/tests/run/float.rs @@ -0,0 +1,28 @@ +// Compiler: +// +// Run-time: +// status: 0 + +#![feature(const_black_box)] + +fn main() { + use std::hint::black_box; + + macro_rules! check { + ($ty:ty, $expr:expr) => {{ + const EXPECTED: $ty = $expr; + assert_eq!($expr, EXPECTED); + }}; + } + + check!(i32, (black_box(0.0f32) as i32)); + + check!(u64, (black_box(f32::NAN) as u64)); + check!(u128, (black_box(f32::NAN) as u128)); + + check!(i64, (black_box(f64::NAN) as i64)); + check!(u64, (black_box(f64::NAN) as u64)); + + check!(i16, (black_box(f32::MIN) as i16)); + check!(i16, (black_box(f32::MAX) as i16)); +} diff --git a/tests/run/fun_ptr.rs b/tests/run/fun_ptr.rs index 98b351e504495..93b9baee1b24a 100644 --- a/tests/run/fun_ptr.rs +++ b/tests/run/fun_ptr.rs @@ -5,19 +5,12 @@ // stdout: 1 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; fn i16_as_i8(a: i16) -> i8 { a as i8 diff --git a/tests/run/int.rs b/tests/run/int.rs index 58a26801b678c..47b5dea46f8de 100644 --- a/tests/run/int.rs +++ b/tests/run/int.rs @@ -3,9 +3,7 @@ // Run-time: // status: 0 -/* - * Code - */ +#![feature(const_black_box)] fn main() { use std::hint::black_box; diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index b0215860406e5..fa50d5bc5d3d3 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -1,4 +1,3 @@ - // Compiler: // // Run-time: @@ -7,139 +6,20 @@ // 6 // 11 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i32 {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - pub fn printf(format: *const i8, ...) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, } fn test(num: isize) -> Test { - Test { - field: num + 1, - } + Test { field: num + 1 } } fn update_num(num: &mut isize) { @@ -147,7 +27,7 @@ fn update_num(num: &mut isize) { } #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 { let mut test = test(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); diff --git a/tests/run/operations.rs b/tests/run/operations.rs index 8ba7a4c5ed8ce..a1b0772f76b62 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -5,229 +5,13 @@ // 39 // 10 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for i32 {} - -#[lang = "deref"] -pub trait Deref { - type Target: ?Sized; - - fn deref(&self) -> &Self::Target; -} - -#[lang = "legacy_receiver"] -trait LegacyReceiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -#[lang = "mul"] -pub trait Mul { - type Output; - - #[must_use] - fn mul(self, rhs: RHS) -> Self::Output; -} - -impl Mul for u8 { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -impl Mul for usize { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -impl Mul for isize { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -#[track_caller] -#[lang = "panic_const_sub_overflow"] -pub fn panic_const_sub_overflow() -> ! { - panic("attempt to subtract with overflow"); -} - -#[track_caller] -#[lang = "panic_const_mul_overflow"] -pub fn panic_const_mul_overflow() -> ! { - panic("attempt to multiply with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { diff --git a/tests/run/ptr_cast.rs b/tests/run/ptr_cast.rs index 0ba49e7187fca..c1254c51ce91d 100644 --- a/tests/run/ptr_cast.rs +++ b/tests/run/ptr_cast.rs @@ -2,35 +2,32 @@ // // Run-time: // status: 0 -// stdout: 1 +// stdout: 10 +// 10 +// 42 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; +use mini_core::*; -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -static mut ONE: usize = 1; - -fn make_array() -> [u8; 3] { - [42, 10, 5] +fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) { + ( + a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8, + b as u32, + ) } #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { + let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42); unsafe { - let ptr = ONE as *mut usize; - let value = ptr as usize; - libc::printf(b"%ld\n\0" as *const u8 as *const i8, value); + libc::printf(b"%d\n\0" as *const u8 as *const i8, c); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, d); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, j); } 0 } diff --git a/tests/run/return-tuple.rs b/tests/run/return-tuple.rs index 3cc1e274001e7..c6e1ba7ce3949 100644 --- a/tests/run/return-tuple.rs +++ b/tests/run/return-tuple.rs @@ -6,54 +6,19 @@ // 10 // 42 +<<<<<<< HEAD #![feature(auto_traits, lang_items, no_core, intrinsics)] #![allow(internal_features)] +======= +#![feature(no_core)] +>>>>>>> db1a31c243a649e1fe20f5466ba181da5be35c14 #![no_std] #![no_core] #![no_main] -#[lang = "copy"] -pub unsafe trait Copy {} - -impl Copy for bool {} -impl Copy for u8 {} -impl Copy for u16 {} -impl Copy for u32 {} -impl Copy for u64 {} -impl Copy for usize {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for i32 {} -impl Copy for isize {} -impl Copy for f32 {} -impl Copy for char {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "legacy_receiver"] -trait LegacyReceiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) { ( diff --git a/tests/run/slice.rs b/tests/run/slice.rs index 825fcb8a081e7..449ccabef7fe3 100644 --- a/tests/run/slice.rs +++ b/tests/run/slice.rs @@ -5,26 +5,17 @@ // stdout: 5 #![feature(no_core)] - #![no_std] #![no_core] #![no_main] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; static mut TWO: usize = 2; fn index_slice(s: &[u32]) -> u32 { - unsafe { - s[TWO] - } + unsafe { s[TWO] } } #[no_mangle] diff --git a/tests/run/static.rs b/tests/run/static.rs index c3c8121b1e195..1e36cf4f3d316 100644 --- a/tests/run/static.rs +++ b/tests/run/static.rs @@ -9,70 +9,13 @@ // 12 // 1 -#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "destruct"] -pub trait Destruct {} - -#[lang = "drop"] -pub trait Drop {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - pub fn abort() -> !; -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -#[lang = "structural_peq"] -pub trait StructuralPartialEq {} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, @@ -84,20 +27,14 @@ struct WithRef { static mut CONSTANT: isize = 10; -static mut TEST: Test = Test { - field: 12, -}; +static mut TEST: Test = Test { field: 12 }; -static mut TEST2: Test = Test { - field: 14, -}; +static mut TEST2: Test = Test { field: 14 }; -static mut WITH_REF: WithRef = WithRef { - refe: unsafe { &TEST }, -}; +static mut WITH_REF: WithRef = WithRef { refe: unsafe { &TEST } }; #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 { unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT); libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field); diff --git a/tests/run/structs.rs b/tests/run/structs.rs index 59b8f358863f2..da73cbed9ae97 100644 --- a/tests/run/structs.rs +++ b/tests/run/structs.rs @@ -5,44 +5,13 @@ // stdout: 1 // 2 -#![feature(auto_traits, lang_items, no_core, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, diff --git a/tests/run/tuple.rs b/tests/run/tuple.rs index ed60a56a68c4c..e0f2e95f6289b 100644 --- a/tests/run/tuple.rs +++ b/tests/run/tuple.rs @@ -4,44 +4,13 @@ // status: 0 // stdout: 3 -#![feature(auto_traits, lang_items, no_core, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core)] #![no_std] #![no_core] #![no_main] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[no_mangle] extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { From 4900dd2e5ccd5cd9a67f0d7c908a15c5a24067ab Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 21:21:15 +0200 Subject: [PATCH 2/9] Fix `rustc_codegen_gcc/tests/run/return-tuple.rs` test --- tests/run/return-tuple.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/run/return-tuple.rs b/tests/run/return-tuple.rs index c6e1ba7ce3949..c1254c51ce91d 100644 --- a/tests/run/return-tuple.rs +++ b/tests/run/return-tuple.rs @@ -6,13 +6,7 @@ // 10 // 42 -<<<<<<< HEAD -#![feature(auto_traits, lang_items, no_core, intrinsics)] -#![allow(internal_features)] - -======= #![feature(no_core)] ->>>>>>> db1a31c243a649e1fe20f5466ba181da5be35c14 #![no_std] #![no_core] #![no_main] From acdd3b729ff82be3d5f540f08cdb4b479fdf9de9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 22:46:43 +0200 Subject: [PATCH 3/9] Fix compilation error in GCC backend --- src/int.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/int.rs b/src/int.rs index 906d7eaceb6be..9b5b0fde6e2f1 100644 --- a/src/int.rs +++ b/src/int.rs @@ -404,7 +404,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); - let result = if ret_indirect { + let call = if ret_indirect { let res_value = self.current_func().new_local(self.location, res_type, "result_value"); let res_addr = res_value.get_address(self.location); let res_param_type = res_type.make_pointer(); From e32e494097ebf595b048876140c3aedf77857924 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 23:02:07 +0200 Subject: [PATCH 4/9] Fix import --- src/abi.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/abi.rs b/src/abi.rs index 890a25e6a7ca0..a96b18e01c087 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -10,7 +10,8 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; #[cfg(feature = "master")] -use rustc_target::callconv::{ArgAttributes, CastTarget, Conv, FnAbi, PassMode}; +use rustc_target::callconv::Conv; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; From fc4afeafc1c7631b98e41cc1585e9e21ac754dac Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 3 Mar 2025 18:18:33 +0100 Subject: [PATCH 5/9] simd intrinsics with mask: accept unsigned integer masks --- src/intrinsic/simd.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 8b454ab2a4241..787f4cd7d41d8 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -443,9 +443,14 @@ 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(_) => {} - _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }), + _ => return_error!(InvalidMonomorphization::MaskWrongElementType { + span, + name, + ty: m_elem_ty + }), } return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); } @@ -987,19 +992,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( assert_eq!(pointer_count - 1, ptr_count(element_ty0)); assert_eq!(underlying_ty, non_ptr(element_ty0)); - // The element type of the third argument must be a signed integer type of any width: + // The element type of the third argument must be an integer type of any width: + // TODO: also support unsigned integers. let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); match *element_ty2.kind() { ty::Int(_) => (), _ => { require!( false, - InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - } + InvalidMonomorphization::MaskWrongElementType { span, name, ty: element_ty2 } ); } } @@ -1105,17 +1106,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( assert_eq!(underlying_ty, non_ptr(element_ty0)); // The element type of the third argument must be a signed integer type of any width: + // TODO: also support unsigned integers. match *element_ty2.kind() { ty::Int(_) => (), _ => { require!( false, - InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - } + InvalidMonomorphization::MaskWrongElementType { span, name, ty: element_ty2 } ); } } From 338e7388ea078c8bf70600f0755701b490ec267b Mon Sep 17 00:00:00 2001 From: bendn Date: Mon, 31 Mar 2025 15:50:56 +0700 Subject: [PATCH 6/9] Suggest {to,from}_ne_bytes for transmutations between arrays and integers, etc --- example/example.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/example/example.rs b/example/example.rs index 03470b74d0a13..888fa89201e13 100644 --- a/example/example.rs +++ b/example/example.rs @@ -1,6 +1,6 @@ #![feature(no_core, unboxed_closures)] #![no_core] -#![allow(dead_code)] +#![allow(dead_code, unnecessary_transmutes)] extern crate mini_core; @@ -11,11 +11,7 @@ fn abc(a: u8) -> u8 { } fn bcd(b: bool, a: u8) -> u8 { - if b { - a * 2 - } else { - a * 3 - } + if b { a * 2 } else { a * 3 } } fn call() { From 79339104b1cc2e0cce8eb4e74e0184e00e872782 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 25 Apr 2025 10:05:35 -0400 Subject: [PATCH 7/9] Update to nightly-2025-04-25 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index fd898c59707b0..452d3f22dc518 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-04-17" +channel = "nightly-2025-04-25" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 5e5ad10bc6eea1d7ff23e9f49e42e39a6c2873f1 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 25 Apr 2025 10:10:50 -0400 Subject: [PATCH 8/9] Fix clippy warnings --- src/asm.rs | 8 ++++---- src/common.rs | 11 +++++------ src/consts.rs | 8 ++++---- src/debuginfo.rs | 17 +++++++++-------- src/gcc_util.rs | 14 ++++++-------- src/lib.rs | 2 +- src/type_of.rs | 14 +++++++------- tests/lang_tests_common.rs | 2 ++ 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index dbdf37ee6c9ef..396c6d5795015 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -165,10 +165,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let mut input_registers = vec![]; for op in rust_operands { - if let InlineAsmOperandRef::In { reg, .. } = *op { - if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) { - input_registers.push(reg_name); - } + if let InlineAsmOperandRef::In { reg, .. } = *op + && let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) + { + input_registers.push(reg_name); } } diff --git a/src/common.rs b/src/common.rs index a63da6b6e27d8..918195364ffee 100644 --- a/src/common.rs +++ b/src/common.rs @@ -33,12 +33,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { - if value.get_type() == self.bool_type.make_pointer() { - if let Some(pointee) = typ.get_pointee() { - if pointee.dyncast_vector().is_some() { - panic!() - } - } + if value.get_type() == self.bool_type.make_pointer() + && let Some(pointee) = typ.get_pointee() + && pointee.dyncast_vector().is_some() + { + panic!() } // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some // SIMD builtins require a constant value. diff --git a/src/consts.rs b/src/consts.rs index acb3937462857..0a67bd7bc71af 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -242,10 +242,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let fn_attrs = self.tcx.codegen_fn_attrs(def_id); let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { - if let Some(global) = self.get_declared_value(sym) { - if self.val_ty(global) != self.type_ptr_to(gcc_type) { - span_bug!(self.tcx.def_span(def_id), "Conflicting types for static"); - } + if let Some(global) = self.get_declared_value(sym) + && self.val_ty(global) != self.type_ptr_to(gcc_type) + { + span_bug!(self.tcx.def_span(def_id), "Conflicting types for static"); } let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 55e01687400aa..f3ced86439527 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -126,14 +126,15 @@ fn make_mir_scope<'gcc, 'tcx>( return; }; - if let Some(ref vars) = *variables { - if !vars.contains(scope) && scope_data.inlined.is_none() { - // Do not create a DIScope if there are no variables defined in this - // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. - debug_context.scopes[scope] = parent_scope; - instantiated.insert(scope); - return; - } + if let Some(ref vars) = *variables + && !vars.contains(scope) + && scope_data.inlined.is_none() + { + // Do not create a DIScope if there are no variables defined in this + // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. + debug_context.scopes[scope] = parent_scope; + instantiated.insert(scope); + return; } let loc = cx.lookup_debug_loc(scope_data.span.lo()); diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 202764d564916..955f902023573 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -136,14 +136,12 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec( let mut name = with_no_trimmed_paths!(layout.ty.to_string()); if let (&ty::Adt(def, _), &Variants::Single { index }) = (layout.ty.kind(), &layout.variants) + && def.is_enum() + && !def.variants().is_empty() { - if def.is_enum() && !def.variants().is_empty() { - write!(&mut name, "::{}", def.variant(index).name).unwrap(); - } + write!(&mut name, "::{}", def.variant(index).name).unwrap(); } if let (&ty::Coroutine(_, _), &Variants::Single { index }) = (layout.ty.kind(), &layout.variants) @@ -264,10 +264,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { } fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - if let BackendRepr::Scalar(ref scalar) = self.backend_repr { - if scalar.is_bool() { - return cx.type_i1(); - } + if let BackendRepr::Scalar(ref scalar) = self.backend_repr + && scalar.is_bool() + { + return cx.type_i1(); } self.gcc_type(cx) } diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index 64c932a265819..d5a0d71c4b298 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -1,5 +1,7 @@ //! The common code for `tests/lang_tests_*.rs` +#![allow(clippy::uninlined_format_args)] + use std::env::{self, current_dir}; use std::path::{Path, PathBuf}; use std::process::Command; From 9059f8cd7c312d55a78cbf32ddf0729032993a9d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 25 Apr 2025 10:18:12 -0400 Subject: [PATCH 9/9] Fix test --- tests/run/ptr_cast.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run/ptr_cast.rs b/tests/run/ptr_cast.rs index 03d998c14cc93..e627886a9d575 100644 --- a/tests/run/ptr_cast.rs +++ b/tests/run/ptr_cast.rs @@ -5,6 +5,7 @@ // stdout: 10 // 10 // 42 +// 1 #![feature(no_core)] #![no_std]