diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4463a6bd53c..9dca00e23e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,14 +17,17 @@ env: jobs: build: - runs-on: ubuntu-24.04 + runs-on: ${{ matrix.os.image }} strategy: fail-fast: false matrix: + os: + - { image: ubuntu-24.04, asset_name_suffix: "" } + - { image: ubuntu-24.04-arm, asset_name_suffix: "-aarch64" } libgccjit_version: - - { gcc: "gcc-15.deb" } - - { gcc: "gcc-15-without-int128.deb" } + - { gcc: "gcc-15" } + - { gcc: "gcc-15-without-int128" } commands: [ "--std-tests --alloc-tests", # FIXME: re-enable asm tests when GCC can emit in the right syntax. @@ -57,19 +60,38 @@ jobs: run: rustup component add rustfmt clippy - name: Download artifact - run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }}${{ matrix.os.asset_name_suffix }}.deb - name: Setup path to libgccjit run: | - sudo dpkg --force-overwrite -i ${{ matrix.libgccjit_version.gcc }} + sudo dpkg --force-overwrite -i ${{ matrix.libgccjit_version.gcc }}${{ matrix.os.asset_name_suffix }}.deb echo 'gcc-path = "/usr/lib/"' > config.toml # Some run-make tests fail if we use our forked GCC because it doesn't # bundle libstdc++, so we switch to gcc-14 to have a GCC that has # libstdc++. + # + # We cannot do this on Aarch64: on x86-64, rustc links with rust-lld, which + # ignores the LTO bytecode that our GCC puts in the object files, while on + # Aarch64, it links via `cc`. Since LTO requires the same GCC version for + # the whole compilation, gcc-14 would run its own lto1 on that bytecode and + # fail with: + # lto1: fatal error: bytecode stream in file '...rcgu.o' generated with LTO + # version 17.0 instead of the expected 14.0 - name: Set default GCC to gcc-14 + if: ${{ matrix.os.image == 'ubuntu-24.04' }} run: sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-14 30 + # Since we keep our GCC as the linker on Aarch64 (see above) and it is + # built without C++ support, it ships neither libubsan (needed by the tests + # compiled with `-Cllvm-args=sanitize-undefined`) nor libstdc++ (needed by + # some run-make tests). Take those from gcc-14 instead: LIBRARY_PATH is + # only used to resolve `-l` options, so the startup files still come from + # our GCC. + - name: Use the libraries from gcc-14 that our GCC doesn't bundle + if: ${{ matrix.os.image == 'ubuntu-24.04-arm' }} + run: echo "LIBRARY_PATH=$(dirname "$(gcc-14 -print-file-name=libubsan.so)")" >> $GITHUB_ENV + - name: Set env run: | echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV @@ -119,7 +141,7 @@ jobs: ./y.sh prepare - name: Add more failing tests for GCC without 128-bit integers support - if: ${{ matrix.libgccjit_version.gcc == 'gcc-15-without-int128.deb' }} + if: ${{ matrix.libgccjit_version.gcc == 'gcc-15-without-int128' }} run: cat tests/failing-ui-tests-without-128bit-integers.txt >> tests/failing-ui-tests.txt - name: Run tests diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 4d7f2cdbb92..1944f911316 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -111,6 +111,15 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> // cSpell:enable } +/// Translate a Rust feature name to the name libgccjit reports in its target +/// info (see gcc/config/aarch64/aarch64-jit.cc and aarch64-option-extensions.def). +pub fn to_gcc_target_info_feature<'a>(sess: &Session, feature: &'a str) -> &'a str { + match (&sess.target.arch, feature) { + (&Arch::AArch64, "neon") => "asimd", + (_, feature) => feature, + } +} + fn arch_to_gcc(name: &str) -> &str { match name { "M68000" => "68000", @@ -141,6 +150,23 @@ pub fn target_cpu(sess: &Session) -> &str { } } +/*pub fn add_baseline_flags<'gcc>(context: &Context<'gcc>, sess: &Session) { + if sess.target.features.is_empty() { + return; + } + + for feature in sess.target.features.split(',') { + let flag = match feature { + "+v8a" => "-march=armv8-a", + "+outline-atomics" => "-moutline-atomics", + // FIXME: do not panic here. + _ => panic!("Feature: {feature}"), + }; + context.add_command_line_option(flag); + context.add_driver_option(flag); + } +}*/ + pub fn new_context<'gcc>(sess: &Session) -> Context<'gcc> { let context = Context::default(); if matches!(sess.target.arch, Arch::X86 | Arch::X86_64) { @@ -228,6 +254,8 @@ pub fn new_context<'gcc>(sess: &Session) -> Context<'gcc> { context.add_command_line_option(format!("-march={}", target_cpu)); } + // add_baseline_flags(&context, sess); + if sess.opts.unstable_opts.function_sections.unwrap_or(sess.target.function_sections) { context.add_command_line_option("-ffunction-sections"); context.add_command_line_option("-fdata-sections"); diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index bdd5a71533a..8d74acd8dce 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1719,6 +1719,13 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.tcmmrlfp16ps" => "__builtin_trap", "llvm.x86.tcmmrlfp16ps.internal" => "__builtin_trap", + "llvm.aarch64.neon.umaxp.v16i8" => "__builtin_aarch64_umaxpv16qi", + "llvm.aarch64.neon.smax.v4i32" => "__builtin_aarch64_smaxv4si", + "llvm.aarch64.neon.sqdmulh.v2i32" => "__builtin_aarch64_sqdmulhv2si", + "llvm.aarch64.neon.sqdmulh.v8i16" => "__builtin_aarch64_sqdmulhv8hi", + "llvm.aarch64.neon.sqdmulh.v4i32" => "__builtin_aarch64_sqdmulhv4si", + "llvm.aarch64.neon.tbl1.v16i8" => "__builtin_aarch64_qtbl1v16qi_ssu", + // NOTE: this file is generated by https://github.com/GuillaumeGomez/llvmint/blob/master/generate_list.py _ => map_arch_intrinsic(name), }; diff --git a/src/lib.rs b/src/lib.rs index 9e86a8b8f21..c8648dbed59 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,7 +101,7 @@ use rustc_target::spec::RelocModel; use tempfile::TempDir; use crate::back::lto::ModuleBuffer; -use crate::gcc_util::{target_cpu, to_gcc_features}; +use crate::gcc_util::{target_cpu, to_gcc_features, to_gcc_target_info_feature}; pub struct PrintOnPanic String>(pub F); @@ -232,6 +232,8 @@ impl CodegenBackend for GccCodegenBackend { #[cfg(feature = "master")] { + // use crate::gcc_util::add_baseline_flags; + gccjit::set_lang_name(c"GNU Rust"); let target_cpu = target_cpu(sess); @@ -242,6 +244,8 @@ impl CodegenBackend for GccCodegenBackend { context.add_command_line_option(format!("-march={}", target_cpu)); } + // add_baseline_flags(&context, sess); + *self.target_info.info.lock().expect("lock") = IntoDynSyncSend(Some(context.get_target_info())); } @@ -516,11 +520,8 @@ fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig sess, |feature| to_gcc_features(sess, feature), |feature| { - // FIXME: we disable Neon for now since we don't support the LLVM intrinsics for it. - if feature == "neon" { - return false; - } - target_info.cpu_supports(feature) + let gccjit_feature_name = to_gcc_target_info_feature(sess, feature); + target_info.cpu_supports(gccjit_feature_name) // cSpell:disable /* adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, diff --git a/tests/compile/simd-ffi.rs b/tests/compile/simd-ffi.rs index 56172ddc7c6..bf79a67aecc 100644 --- a/tests/compile/simd-ffi.rs +++ b/tests/compile/simd-ffi.rs @@ -1,5 +1,9 @@ // Compiler: +fn main() { +} + +/* // FIXME: Remove this test once stops // ignoring GCC backend. @@ -41,7 +45,7 @@ extern "C" { fn integer(a: i32x4, b: i32x4) -> i32x4; // vmaxq_s32 #[cfg(target_arch = "aarch64")] - #[link_name = "llvm.aarch64.neon.maxs.v4i32"] + #[link_name = "llvm.aarch64.neon.smax.v4i32"] fn integer(a: i32x4, b: i32x4) -> i32x4; // Use a generic LLVM intrinsic to do type checking on other platforms @@ -92,3 +96,4 @@ macro_rules! Copy { macro_rules! derive { () => {}; } +*/ diff --git a/tests/compile/x86_interrupt_first_arg_byval.rs b/tests/compile/x86_interrupt_first_arg_byval.rs index 4b6bbd48f7a..81cf6b28d2a 100644 --- a/tests/compile/x86_interrupt_first_arg_byval.rs +++ b/tests/compile/x86_interrupt_first_arg_byval.rs @@ -11,6 +11,8 @@ pub struct Frame { ip: u64, } +#[cfg(target_arch = "x86_64")] pub extern "x86-interrupt" fn scalar(_a: i64) {} +#[cfg(target_arch = "x86_64")] pub extern "x86-interrupt" fn aggregate(_frame: Frame) {}