about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc')
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/ci.yml10
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/failures.yml6
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml2
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/m68k.yml8
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/release.yml13
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/build.rs10
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/config.rs57
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/info.rs4
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/main.rs4
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/test.rs33
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_example.rs7
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_gcc/example/mod_bench.rs36
-rw-r--r--compiler/rustc_codegen_gcc/libgccjit.version2
-rw-r--r--compiler/rustc_codegen_gcc/messages.ftl3
-rw-r--r--compiler/rustc_codegen_gcc/src/abi.rs7
-rw-r--r--compiler/rustc_codegen_gcc/src/base.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs23
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs12
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs9
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs12
-rw-r--r--compiler/rustc_codegen_gcc/src/declare.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/gcc_util.rs50
-rw-r--r--compiler/rustc_codegen_gcc/src/int.rs7
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs22
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs14
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs468
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/mono_item.rs5
-rw-r--r--compiler/rustc_codegen_gcc/src/type_.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort1.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort2.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/array.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/assign.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/closure.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/condition.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/empty_main.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit_code.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/int.rs2
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/mut_ref.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/operations.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/return-tuple.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/slice.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/static.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/structs.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/tuple.rs7
51 files changed, 470 insertions, 507 deletions
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
index 73ec6b84a15..f96912e6b7a 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
@@ -13,14 +13,14 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
 
     strategy:
       fail-fast: false
       matrix:
         libgccjit_version:
-          - { gcc: "gcc-13.deb" }
-          - { gcc: "gcc-13-without-int128.deb" }
+          - { gcc: "gcc-15.deb" }
+          - { gcc: "gcc-15-without-int128.deb" }
         commands: [
           "--std-tests",
           # FIXME: re-enable asm tests when GCC can emit in the right syntax.
@@ -108,13 +108,13 @@ jobs:
         cargo clippy --all-targets --features master -- -D warnings
 
   duplicates:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - uses: actions/checkout@v4
       - run: python tools/check_intrinsics_duplicates.py
 
   build_system:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - uses: actions/checkout@v4
       - name: Test build system
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
index f33d9fcc582..d080bbfe91f 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
@@ -13,7 +13,7 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
 
     strategy:
       fail-fast: false
@@ -56,12 +56,12 @@ jobs:
 
     - name: Download artifact
       if: matrix.libgccjit_version.gcc != 'libgccjit12.so'
-      run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb
+      run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb
 
     - name: Setup path to libgccjit
       if: matrix.libgccjit_version.gcc != 'libgccjit12.so'
       run: |
-          sudo dpkg --force-overwrite -i gcc-13.deb
+          sudo dpkg --force-overwrite -i gcc-15.deb
           echo 'gcc-path = "/usr/lib"' > config.toml
           echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV
           echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml b/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
index 4c2ce91e86e..bb9e020dc6a 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
@@ -17,7 +17,7 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
 
     strategy:
       fail-fast: false
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
index 07bb372b360..ed1fc02bd91 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
@@ -17,7 +17,7 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
 
     strategy:
       fail-fast: false
@@ -47,17 +47,17 @@ jobs:
     - name: Install packages
       run: |
         sudo apt-get update
-        sudo apt-get install qemu qemu-user-static
+        sudo apt-get install qemu-system qemu-user-static
 
     - name: Download artifact
-      run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb
+      run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-15.deb
 
     - name: Download VM artifact
       run: curl -LO https://github.com/cross-cg-gcc-tools/vms/releases/latest/download/debian-m68k.img
 
     - name: Setup path to libgccjit
       run: |
-          sudo dpkg -i gcc-m68k-13.deb
+          sudo dpkg -i gcc-m68k-15.deb
           echo 'gcc-path = "/usr/lib/"' > config.toml
 
     - name: Set env
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/release.yml b/compiler/rustc_codegen_gcc/.github/workflows/release.yml
index 60e0943c87d..886ce90b471 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/release.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/release.yml
@@ -13,7 +13,7 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
 
     strategy:
       fail-fast: false
@@ -37,11 +37,11 @@ jobs:
       run: sudo apt-get install ninja-build ripgrep
 
     - name: Download artifact
-      run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb
+      run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb
 
     - name: Setup path to libgccjit
       run: |
-          sudo dpkg --force-overwrite -i gcc-13.deb
+          sudo dpkg --force-overwrite -i gcc-15.deb
           echo 'gcc-path = "/usr/lib/"' > config.toml
 
     - name: Set env
@@ -76,4 +76,9 @@ jobs:
     - name: Run y.sh cargo build
       run: |
         EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml
-        # TODO: grep the asm output for "call my_func" and fail if it is found.
+        call_found=$(objdump -dj .text tests/hello-world/target/release/hello_world | grep -c "call .*mylib.*my_func" ) ||:
+        if [ $call_found -gt 0 ]; then
+          echo "ERROR: call my_func found in asm"
+          echo "Test is done with LTO enabled, hence inlining should occur across crates"
+          exit 1
+        fi
diff --git a/compiler/rustc_codegen_gcc/build_system/src/build.rs b/compiler/rustc_codegen_gcc/build_system/src/build.rs
index d0ced211a61..e98377f15a9 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/build.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/build.rs
@@ -150,6 +150,8 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
         "debug"
     };
 
+    // We have a different environment variable than RUSTFLAGS to make sure those flags are only
+    // sent to rustc_codegen_gcc and not the LLVM backend.
     if let Ok(cg_rustflags) = std::env::var("CG_RUSTFLAGS") {
         rustflags.push(' ');
         rustflags.push_str(&cg_rustflags);
@@ -184,8 +186,12 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
 fn build_codegen(args: &mut BuildArg) -> Result<(), String> {
     let mut env = HashMap::new();
 
-    env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
-    env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
+    let gcc_path =
+        args.config_info.gcc_path.clone().expect(
+            "The config module should have emitted an error if the GCC path wasn't provided",
+        );
+    env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone());
+    env.insert("LIBRARY_PATH".to_string(), gcc_path);
 
     if args.config_info.no_default_features {
         env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string());
diff --git a/compiler/rustc_codegen_gcc/build_system/src/config.rs b/compiler/rustc_codegen_gcc/build_system/src/config.rs
index 37b4b68950e..4f9fcc97151 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/config.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/config.rs
@@ -112,7 +112,7 @@ pub struct ConfigInfo {
     pub sysroot_panic_abort: bool,
     pub cg_backend_path: String,
     pub sysroot_path: String,
-    pub gcc_path: String,
+    pub gcc_path: Option<String>,
     config_file: Option<String>,
     // This is used in particular in rust compiler bootstrap because it doesn't run at the root
     // of the `cg_gcc` folder, making it complicated for us to get access to local files we need
@@ -173,6 +173,14 @@ impl ConfigInfo {
             "--release-sysroot" => self.sysroot_release_channel = true,
             "--release" => self.channel = Channel::Release,
             "--sysroot-panic-abort" => self.sysroot_panic_abort = true,
+            "--gcc-path" => match args.next() {
+                Some(arg) if !arg.is_empty() => {
+                    self.gcc_path = Some(arg.into());
+                }
+                _ => {
+                    return Err("Expected a value after `--gcc-path`, found nothing".to_string());
+                }
+            },
             "--cg_gcc-path" => match args.next() {
                 Some(arg) if !arg.is_empty() => {
                     self.cg_gcc_path = Some(arg.into());
@@ -260,8 +268,9 @@ impl ConfigInfo {
             create_symlink(&libgccjit_so, output_dir.join(&format!("{}.0", libgccjit_so_name)))?;
         }
 
-        self.gcc_path = output_dir.display().to_string();
-        println!("Using `{}` as path for libgccjit", self.gcc_path);
+        let gcc_path = output_dir.display().to_string();
+        println!("Using `{}` as path for libgccjit", gcc_path);
+        self.gcc_path = Some(gcc_path);
         Ok(())
     }
 
@@ -273,6 +282,15 @@ impl ConfigInfo {
     }
 
     pub fn setup_gcc_path(&mut self) -> Result<(), String> {
+        // If the user used the `--gcc-path` option, no need to look at `config.toml` content
+        // since we already have everything we need.
+        if let Some(gcc_path) = &self.gcc_path {
+            println!(
+                "`--gcc-path` was provided, ignoring config file. Using `{}` as path for libgccjit",
+                gcc_path
+            );
+            return Ok(());
+        }
         let config_file = match self.config_file.as_deref() {
             Some(config_file) => config_file.into(),
             None => self.compute_path("config.toml"),
@@ -283,12 +301,15 @@ impl ConfigInfo {
             self.download_gccjit_if_needed()?;
             return Ok(());
         }
-        self.gcc_path = match gcc_path {
-            Some(path) => path,
-            None => {
-                return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),));
-            }
+        let Some(gcc_path) = gcc_path else {
+            return Err(format!("missing `gcc-path` value from `{}`", config_file.display()));
         };
+        println!(
+            "GCC path retrieved from `{}`. Using `{}` as path for libgccjit",
+            config_file.display(),
+            gcc_path
+        );
+        self.gcc_path = Some(gcc_path);
         Ok(())
     }
 
@@ -299,10 +320,17 @@ impl ConfigInfo {
     ) -> Result<(), String> {
         env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string());
 
-        if self.gcc_path.is_empty() && !use_system_gcc {
-            self.setup_gcc_path()?;
-        }
-        env.insert("GCC_PATH".to_string(), self.gcc_path.clone());
+        let gcc_path = if !use_system_gcc {
+            if self.gcc_path.is_none() {
+                self.setup_gcc_path()?;
+            }
+            self.gcc_path.clone().expect(
+                "The config module should have emitted an error if the GCC path wasn't provided",
+            )
+        } else {
+            String::new()
+        };
+        env.insert("GCC_PATH".to_string(), gcc_path.clone());
 
         if self.cargo_target_dir.is_empty() {
             match env.get("CARGO_TARGET_DIR").filter(|dir| !dir.is_empty()) {
@@ -381,6 +409,8 @@ impl ConfigInfo {
         }
 
         // This environment variable is useful in case we want to change options of rustc commands.
+        // We have a different environment variable than RUSTFLAGS to make sure those flags are
+        // only sent to rustc_codegen_gcc and not the LLVM backend.
         if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") {
             rustflags.extend_from_slice(&split_args(&cg_rustflags)?);
         }
@@ -414,7 +444,7 @@ impl ConfigInfo {
             "{target}:{sysroot}:{gcc_path}",
             target = self.cargo_target_dir,
             sysroot = sysroot.display(),
-            gcc_path = self.gcc_path,
+            gcc_path = gcc_path,
         );
         env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone());
         env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
@@ -459,6 +489,7 @@ impl ConfigInfo {
     --release-sysroot      : Build sysroot in release mode
     --sysroot-panic-abort  : Build the sysroot without unwinding support
     --config-file          : Location of the config file to be used
+    --gcc-path             : Location of the GCC root folder
     --cg_gcc-path          : Location of the rustc_codegen_gcc root folder (used
                              when ran from another directory)
     --no-default-features  : Add `--no-default-features` flag to cargo commands
diff --git a/compiler/rustc_codegen_gcc/build_system/src/info.rs b/compiler/rustc_codegen_gcc/build_system/src/info.rs
index ea38791d38c..bd891de2eb4 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/info.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/info.rs
@@ -14,6 +14,8 @@ pub fn run() -> Result<(), String> {
     }
     config.no_download = true;
     config.setup_gcc_path()?;
-    println!("{}", config.gcc_path);
+    if let Some(gcc_path) = config.gcc_path {
+        println!("{}", gcc_path);
+    }
     Ok(())
 }
diff --git a/compiler/rustc_codegen_gcc/build_system/src/main.rs b/compiler/rustc_codegen_gcc/build_system/src/main.rs
index 3a860e2b136..39361718306 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/main.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/main.rs
@@ -34,11 +34,11 @@ Options:
         --help    : Displays this help message.
 
 Commands:
-        cargo     : Executes a cargo command. 
+        cargo     : Executes a cargo command.
         rustc     : Compiles the program using the GCC compiler.
         clean     : Cleans the build directory, removing all compiled files and artifacts.
         prepare   : Prepares the environment for building, including fetching dependencies and setting up configurations.
-        build     : Compiles the project. 
+        build     : Compiles the project.
         test      : Runs tests for the project.
         info      : Displays information about the build environment and project configuration.
         clone-gcc : Clones the GCC compiler from a specified source.
diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs
index 7cc7336612c..6c29c7d1825 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/test.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs
@@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     run_command_with_env(&command, None, Some(env))?;
     maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
 
-    // FIXME: create a function "display_if_not_quiet" or something along the line.
-    println!("[AOT] mod_bench");
-    let mut command = args.config_info.rustc_command_vec();
-    command.extend_from_slice(&[
-        &"example/mod_bench.rs",
-        &"--crate-type",
-        &"bin",
-        &"--target",
-        &args.config_info.target_triple,
-    ]);
-    run_command_with_env(&command, None, Some(env))?;
-    // FIXME: the compiled binary is not run.
-
     Ok(())
 }
 
@@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
     Ok(())
 }
 
-// echo "[BENCH COMPILE] mod_bench"
-//
-// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline"
-// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort"
-//
-// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow
-// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3"
-// echo "[BENCH RUN] mod_bench"
-// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_*
-
 fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     if !args.is_using_gcc_master_branch() {
         println!("Not using GCC master branch. Skipping `extended_rand_tests`.");
@@ -1255,8 +1229,11 @@ pub fn run() -> Result<(), String> {
 
     if !args.use_system_gcc {
         args.config_info.setup_gcc_path()?;
-        env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
-        env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
+        let gcc_path = args.config_info.gcc_path.clone().expect(
+            "The config module should have emitted an error if the GCC path wasn't provided",
+        );
+        env.insert("LIBRARY_PATH".to_string(), gcc_path.clone());
+        env.insert("LD_LIBRARY_PATH".to_string(), gcc_path);
     }
 
     build_if_no_backend(&env, &args)?;
diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs
index 6ed8b9157f2..9a0b46d5b22 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_example.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs
@@ -1,5 +1,6 @@
-#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
+#![feature(core_intrinsics, alloc_error_handler, lang_items)]
 #![no_std]
+#![no_main]
 #![allow(internal_features)]
 
 extern crate alloc;
@@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() {
     core::intrinsics::unreachable();
 }
 
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
     let world: Box<&str> = Box::new("Hello World!\0");
     unsafe {
         puts(*world as *const str as *const u8);
diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
index 1d51e0a1856..4cbe66c5e4c 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
@@ -1,7 +1,7 @@
 // Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
 
 #![feature(
-    no_core, unboxed_closures, start, lang_items, never_type, linkage,
+    no_core, unboxed_closures, lang_items, never_type, linkage,
     extern_types, thread_local
 )]
 #![no_core]
diff --git a/compiler/rustc_codegen_gcc/example/mod_bench.rs b/compiler/rustc_codegen_gcc/example/mod_bench.rs
deleted file mode 100644
index e8a9cade747..00000000000
--- a/compiler/rustc_codegen_gcc/example/mod_bench.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-#![feature(start, core_intrinsics, lang_items)]
-#![no_std]
-#![allow(internal_features)]
-
-#[link(name = "c")]
-extern "C" {}
-
-#[panic_handler]
-fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
-    core::intrinsics::abort();
-}
-
-#[lang="eh_personality"]
-fn eh_personality(){}
-
-// Required for rustc_codegen_llvm
-#[no_mangle]
-unsafe extern "C" fn _Unwind_Resume() {
-    core::intrinsics::unreachable();
-}
-
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
-    for i in 2..100_000_000 {
-        black_box((i + 1) % i);
-    }
-
-    0
-}
-
-#[inline(never)]
-fn black_box(i: u32) {
-    if i != 1 {
-        core::intrinsics::abort();
-    }
-}
diff --git a/compiler/rustc_codegen_gcc/libgccjit.version b/compiler/rustc_codegen_gcc/libgccjit.version
index ff58accec1d..417fd5b0393 100644
--- a/compiler/rustc_codegen_gcc/libgccjit.version
+++ b/compiler/rustc_codegen_gcc/libgccjit.version
@@ -1 +1 @@
-45648c2edd4ecd862d9f08196d3d6c6ccba79f07
+e607be166673a8de9fc07f6f02c60426e556c5f2
diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl
index 85fa17a6ba5..882fff8673a 100644
--- a/compiler/rustc_codegen_gcc/messages.ftl
+++ b/compiler/rustc_codegen_gcc/messages.ftl
@@ -5,9 +5,6 @@ codegen_gcc_unknown_ctarget_feature_prefix =
 codegen_gcc_invalid_minimum_alignment =
     invalid minimum global alignment: {$err}
 
-codegen_gcc_lto_not_supported =
-    LTO is not supported. You may get a linker error.
-
 codegen_gcc_forbidden_ctarget_feature =
     target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
 
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs
index 14fc23593f0..717baebcd8c 100644
--- a/compiler/rustc_codegen_gcc/src/abi.rs
+++ b/compiler/rustc_codegen_gcc/src/abi.rs
@@ -1,6 +1,7 @@
 #[cfg(feature = "master")]
 use gccjit::FnAttribute;
 use gccjit::{ToLValue, ToRValue, Type};
+use rustc_abi::{Reg, RegKind};
 use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
@@ -8,7 +9,7 @@ use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature = "master")]
 use rustc_session::config;
-use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
+use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
@@ -132,10 +133,10 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             if cx.sess().opts.optimize == config::OptLevel::No {
                 return ty;
             }
-            if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NoAlias) {
+            if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) {
                 ty = ty.make_restrict()
             }
-            if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NonNull) {
+            if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) {
                 non_null_args.push(arg_index as i32 + 1);
             }
             ty
diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs
index c9701fb9885..962f4b161d7 100644
--- a/compiler/rustc_codegen_gcc/src/base.rs
+++ b/compiler/rustc_codegen_gcc/src/base.rs
@@ -49,9 +49,7 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
         Linkage::LinkOnceODR => unimplemented!(),
         Linkage::WeakAny => unimplemented!(),
         Linkage::WeakODR => unimplemented!(),
-        Linkage::Appending => unimplemented!(),
         Linkage::Internal => GlobalKind::Internal,
-        Linkage::Private => GlobalKind::Internal,
         Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage.
         Linkage::Common => unimplemented!(),
     }
@@ -66,9 +64,7 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType {
         Linkage::LinkOnceODR => unimplemented!(),
         Linkage::WeakAny => FunctionType::Exported, // FIXME(antoyo): should be similar to linkonce.
         Linkage::WeakODR => unimplemented!(),
-        Linkage::Appending => unimplemented!(),
         Linkage::Internal => FunctionType::Internal,
-        Linkage::Private => FunctionType::Internal,
         Linkage::ExternalWeak => unimplemented!(),
         Linkage::Common => unimplemented!(),
     }
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 89e5cf1b8c6..1c3d6cc899a 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -29,7 +29,7 @@ use rustc_middle::ty::layout::{
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_span::Span;
 use rustc_span::def_id::DefId;
-use rustc_target::abi::call::FnAbi;
+use rustc_target::callconv::FnAbi;
 use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, WasmCAbi, X86Abi};
 
 use crate::common::{SignType, TypeReflection, type_is_pointer};
@@ -155,14 +155,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         // NOTE: not sure why, but we have the wrong type here.
         let int_type = compare_exchange.get_param(2).to_rvalue().get_type();
         let src = self.context.new_bitcast(self.location, src, int_type);
-        self.context.new_call(self.location, compare_exchange, &[
-            dst,
-            expected,
-            src,
-            weak,
-            order,
-            failure_order,
-        ])
+        self.context.new_call(
+            self.location,
+            compare_exchange,
+            &[dst, expected, src, weak, order, failure_order],
+        )
     }
 
     pub fn assign(&self, lvalue: LValue<'gcc>, value: RValue<'gcc>) {
@@ -1076,9 +1073,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         let align = dest.val.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
         cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
 
-        let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[
-            self.const_usize(1),
-        ]);
+        let next = self.inbounds_gep(
+            self.backend_type(cg_elem.layout),
+            current.to_rvalue(),
+            &[self.const_usize(1)],
+        );
         self.llbb().add_assignment(self.location, current, next);
         self.br(header_bb);
 
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index f43743fc2a4..20a3482aaa2 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -64,6 +64,11 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
     }
 
+    fn is_undef(&self, _val: RValue<'gcc>) -> bool {
+        // FIXME: actually check for undef
+        false
+    }
+
     fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
         let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined");
         if typ.is_struct().is_some() {
@@ -229,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                     GlobalAlloc::VTable(ty, dyn_ty) => {
                         let alloc = self
                             .tcx
-                            .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
+                            .global_alloc(self.tcx.vtable_allocation((
+                                ty,
+                                dyn_ty.principal().map(|principal| {
+                                    self.tcx.instantiate_bound_regions_with_erased(principal)
+                                }),
+                            )))
                             .unwrap_memory();
                         let init = const_alloc_to_gcc(self, alloc);
                         self.static_addr_of(init, alloc.inner().align, None)
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 1631ecfeecf..fb0ca31c543 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -1,6 +1,7 @@
 #[cfg(feature = "master")]
 use gccjit::{FnAttribute, VarAttribute, Visibility};
 use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
+use rustc_abi::{self as abi, Align, HasDataLayout, Primitive, Size, WrappingRange};
 use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
 };
@@ -14,7 +15,6 @@ use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Instance};
 use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
-use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange};
 
 use crate::base;
 use crate::context::CodegenCx;
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index c81c53359fd..1e1f577bb3a 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell};
 use gccjit::{
     Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type,
 };
+use rustc_abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
 use rustc_codegen_ssa::base::wants_msvc_seh;
 use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
@@ -14,11 +15,10 @@ use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
     LayoutOfHelpers,
 };
-use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::source_map::respan;
 use rustc_span::{DUMMY_SP, Span};
-use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
 use rustc_target::spec::{
     HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi,
 };
@@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
     pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
     /// Cache generated vtables
     pub vtables:
-        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
+        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
 
     // TODO(antoyo): improve the SSA API to not require those.
     /// Mapping from function pointer type to indexes of on stack parameters.
@@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
 impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn vtables(
         &self,
-    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
+    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
         &self.vtables
     }
 
@@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         } else {
             // If the symbol already exists, it is an error: for example, the user wrote
             // #[no_mangle] extern "C" fn main(..) {..}
-            // instead of #[start]
             None
         }
     }
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index 4b84b1dbfd3..55e01687400 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -1,17 +1,17 @@
 use std::ops::Range;
+use std::sync::Arc;
 
 use gccjit::{Location, RValue};
+use rustc_abi::Size;
 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
 use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods};
-use rustc_data_structures::sync::Lrc;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::{self, Body, SourceScope};
-use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
+use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
 use rustc_session::config::DebugInfo;
 use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol};
-use rustc_target::abi::Size;
-use rustc_target::abi::call::FnAbi;
+use rustc_target::callconv::FnAbi;
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
@@ -172,7 +172,7 @@ fn make_mir_scope<'gcc, 'tcx>(
 // `lookup_char_pos` return the right information instead.
 pub struct DebugLoc {
     /// Information about the original source file.
-    pub file: Lrc<SourceFile>,
+    pub file: Arc<SourceFile>,
     /// The (1-based) line number.
     pub line: u32,
     /// The (1-based) column number.
@@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn create_vtable_debuginfo(
         &self,
         _ty: Ty<'tcx>,
-        _trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+        _trait_ref: Option<ExistentialTraitRef<'tcx>>,
         _vtable: Self::Value,
     ) {
         // TODO(antoyo)
diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs
index 442488b7fd6..7cdbe3c0c62 100644
--- a/compiler/rustc_codegen_gcc/src/declare.rs
+++ b/compiler/rustc_codegen_gcc/src/declare.rs
@@ -4,7 +4,7 @@ use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type};
 use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
 use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
-use rustc_target::abi::call::FnAbi;
+use rustc_target::callconv::FnAbi;
 
 use crate::abi::{FnAbiGcc, FnAbiGccExt};
 use crate::context::CodegenCx;
diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs
index 560aff43d65..4e8c8aaaf5c 100644
--- a/compiler/rustc_codegen_gcc/src/gcc_util.rs
+++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs
@@ -1,10 +1,8 @@
-use std::iter::FromIterator;
-
 #[cfg(feature = "master")]
 use gccjit::Context;
 use rustc_codegen_ssa::codegen_attrs::check_tied_features;
 use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::unord::UnordSet;
 use rustc_session::Session;
 use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
@@ -45,12 +43,6 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
     let known_features = sess.target.rust_target_features();
     let mut featsmap = FxHashMap::default();
 
-    // Ensure that all ABI-required features are enabled, and the ABI-forbidden ones
-    // are disabled.
-    let abi_feature_constraints = sess.target.abi_required_features();
-    let abi_incompatible_set =
-        FxHashSet::from_iter(abi_feature_constraints.incompatible.iter().copied());
-
     // Compute implied features
     let mut all_rust_features = vec![];
     for feature in sess.opts.cg.target_feature.split(',') {
@@ -117,51 +109,11 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
                 }
             }
 
-            // Ensure that the features we enable/disable are compatible with the ABI.
-            if enable {
-                if abi_incompatible_set.contains(feature) {
-                    sess.dcx().emit_warn(ForbiddenCTargetFeature {
-                        feature,
-                        enabled: "enabled",
-                        reason: "this feature is incompatible with the target ABI",
-                    });
-                }
-            } else {
-                // FIXME: we have to request implied features here since
-                // negative features do not handle implied features above.
-                for &required in abi_feature_constraints.required.iter() {
-                    let implied = sess.target.implied_target_features(std::iter::once(required));
-                    if implied.contains(feature) {
-                        sess.dcx().emit_warn(ForbiddenCTargetFeature {
-                            feature,
-                            enabled: "disabled",
-                            reason: "this feature is required by the target ABI",
-                        });
-                    }
-                }
-            }
-
             // FIXME(nagisa): figure out how to not allocate a full hashset here.
             featsmap.insert(feature, enable);
         }
     }
 
-    // To be sure the ABI-relevant features are all in the right state, we explicitly
-    // (un)set them here. This means if the target spec sets those features wrong,
-    // we will silently correct them rather than silently producing wrong code.
-    // (The target sanity check tries to catch this, but we can't know which features are
-    // enabled in GCC by default so we can't be fully sure about that check.)
-    // We add these at the beginning of the list so that `-Ctarget-features` can
-    // still override it... that's unsound, but more compatible with past behavior.
-    all_rust_features.splice(
-        0..0,
-        abi_feature_constraints
-            .required
-            .iter()
-            .map(|&f| (true, f))
-            .chain(abi_feature_constraints.incompatible.iter().map(|&f| (false, f))),
-    );
-
     // Translate this into GCC features.
     let feats =
         all_rust_features.iter().flat_map(|&(enable, feature)| {
diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs
index fe6a65bed03..4a1db8d662a 100644
--- a/compiler/rustc_codegen_gcc/src/int.rs
+++ b/compiler/rustc_codegen_gcc/src/int.rs
@@ -3,12 +3,11 @@
 //! 128-bit integers on 32-bit platforms and thus require to be handled manually.
 
 use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
+use rustc_abi::{Endian, ExternAbi};
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
 use rustc_middle::ty::{self, Ty};
-use rustc_target::abi::Endian;
-use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
-use rustc_target::spec;
+use rustc_target::callconv::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
 
 use crate::builder::{Builder, ToGccComp};
 use crate::common::{SignType, TypeReflection};
@@ -401,7 +400,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             conv: Conv::C,
             can_unwind: false,
         };
-        fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { unwind: false }).unwrap();
+        fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }).unwrap();
 
         let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
 
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
index 231307def29..2d731f88d7d 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
@@ -687,11 +687,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
                 let field2 = builder.context.new_field(None, args[1].get_type(), "carryResult");
                 let struct_type =
                     builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]);
-                return_value =
-                    builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
-                        return_value,
-                        last_arg.dereference(None).to_rvalue(),
-                    ]);
+                return_value = builder.context.new_struct_constructor(
+                    None,
+                    struct_type.as_type(),
+                    None,
+                    &[return_value, last_arg.dereference(None).to_rvalue()],
+                );
             }
         }
         "__builtin_ia32_stmxcsr" => {
@@ -716,11 +717,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
             let field2 = builder.context.new_field(None, return_value.get_type(), "success");
             let struct_type =
                 builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]);
-            return_value =
-                builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
-                    random_number,
-                    success_variable.to_rvalue(),
-                ]);
+            return_value = builder.context.new_struct_constructor(
+                None,
+                struct_type.as_type(),
+                None,
+                &[random_number, success_variable.to_rvalue()],
+            );
         }
         "fma" => {
             let f16_type = builder.context.new_c_type(CType::Float16);
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 48606f5f91c..a1123fafe2f 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -7,6 +7,9 @@ use std::iter;
 #[cfg(feature = "master")]
 use gccjit::FunctionType;
 use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp};
+#[cfg(feature = "master")]
+use rustc_abi::ExternAbi;
+use rustc_abi::HasDataLayout;
 use rustc_codegen_ssa::MemFlags;
 use rustc_codegen_ssa::base::wants_msvc_seh;
 use rustc_codegen_ssa::common::IntPredicate;
@@ -25,11 +28,8 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
 use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::abi::HasDataLayout;
-use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
+use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
 use rustc_target::spec::PanicStrategy;
-#[cfg(feature = "master")]
-use rustc_target::spec::abi::Abi;
 
 #[cfg(feature = "master")]
 use crate::abi::FnAbiGccExt;
@@ -1238,7 +1238,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
             tcx.types.unit,
             false,
             rustc_hir::Safety::Unsafe,
-            Abi::Rust,
+            ExternAbi::Rust,
         )),
     );
     // `unsafe fn(*mut i8, *mut i8) -> ()`
@@ -1249,7 +1249,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
             tcx.types.unit,
             false,
             rustc_hir::Safety::Unsafe,
-            Abi::Rust,
+            ExternAbi::Rust,
         )),
     );
     // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
@@ -1258,7 +1258,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
         tcx.types.i32,
         false,
         rustc_hir::Safety::Unsafe,
-        Abi::Rust,
+        ExternAbi::Rust,
     ));
     let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
     cx.rust_try_fn.set(Some(rust_try));
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 1be452e5d05..84cd5b002fb 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -3,6 +3,7 @@ use std::iter::FromIterator;
 use gccjit::{BinaryOp, RValue, ToRValue, Type};
 #[cfg(feature = "master")]
 use gccjit::{ComparisonOp, UnaryOp};
+use rustc_abi::{Align, Size};
 use rustc_codegen_ssa::base::compare_simd_types;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 #[cfg(feature = "master")]
@@ -17,7 +18,6 @@ use rustc_middle::mir::BinOp;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::abi::{Align, Size};
 
 use crate::builder::Builder;
 #[cfg(not(feature = "master"))]
@@ -62,11 +62,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     let arg_tys = sig.inputs();
 
     if name == sym::simd_select_bitmask {
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
+        );
         let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
 
         let expected_int_bits = (len.max(8) - 1).next_power_of_two();
@@ -140,14 +139,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         require!(
             bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
             InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
@@ -269,23 +271,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         let lo_nibble =
             bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &lo_nibble_elements);
 
-        let mask = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
-            bx.context
-                .new_rvalue_from_int(
-                    bx.u8_type, 0x0f
-                );
-            byte_vector_type_size
-                as _
-        ]);
-
-        let four_vec = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
-                bx.context
-                    .new_rvalue_from_int(
-                        bx.u8_type, 4
-                    );
-                byte_vector_type_size
-                    as _
-            ]);
+        let mask = bx.context.new_rvalue_from_vector(
+            None,
+            long_byte_vector_type,
+            &vec![bx.context.new_rvalue_from_int(bx.u8_type, 0x0f); byte_vector_type_size as _],
+        );
+
+        let four_vec = bx.context.new_rvalue_from_vector(
+            None,
+            long_byte_vector_type,
+            &vec![bx.context.new_rvalue_from_int(bx.u8_type, 4); byte_vector_type_size as _],
+        );
 
         // Step 2: Byte-swap the input.
         let swapped = simd_bswap(bx, args[0].immediate());
@@ -388,21 +384,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(out_len == n, InvalidMonomorphization::ReturnLength {
-            span,
-            name,
-            in_len: n,
-            ret_ty,
-            out_len
-        });
-        require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty,
-            out_ty
-        });
+        require!(
+            out_len == n,
+            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
+        );
+        require!(
+            in_elem == out_ty,
+            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
+        );
 
         let vector = args[2].immediate();
 
@@ -411,13 +400,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
     #[cfg(feature = "master")]
     if name == sym::simd_insert {
-        require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            out_ty: arg_tys[2]
-        });
+        require!(
+            in_elem == arg_tys[2],
+            InvalidMonomorphization::InsertedType {
+                span,
+                name,
+                in_elem,
+                in_ty,
+                out_ty: arg_tys[2]
+            }
+        );
         let vector = args[0].immediate();
         let index = args[1].immediate();
         let value = args[2].immediate();
@@ -431,13 +423,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
     #[cfg(feature = "master")]
     if name == sym::simd_extract {
-        require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_elem,
+            InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+        );
         let vector = args[0].immediate();
         return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
     }
@@ -445,18 +434,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     if name == sym::simd_select {
         let m_elem_ty = in_elem;
         let m_len = in_len;
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
+        );
         let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
-        require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths {
-            span,
-            name,
-            m_len,
-            v_len
-        });
+        require!(
+            m_len == v_len,
+            InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
+        );
         match *m_elem_ty.kind() {
             ty::Int(_) => {}
             _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }),
@@ -468,25 +454,27 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::RawPtr(p_ty, _) => {
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: in_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
@@ -497,11 +485,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: out_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
@@ -524,14 +511,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::RawPtr(_, _) => {}
@@ -560,14 +550,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::Uint(ty::UintTy::Usize) => {}
@@ -596,14 +589,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     if name == sym::simd_cast || name == sym::simd_as {
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         // casting cares about nominal type, not just structural type
         if in_elem == out_elem {
             return Ok(args[0].immediate());
@@ -629,14 +625,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         match (in_style, out_style) {
             (Style::Unsupported, Style::Unsupported) => {
-                require!(false, InvalidMonomorphization::UnsupportedCast {
-                    span,
-                    name,
-                    in_ty,
-                    in_elem,
-                    ret_ty,
-                    out_elem
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::UnsupportedCast {
+                        span,
+                        name,
+                        in_ty,
+                        in_elem,
+                        ret_ty,
+                        out_elem
+                    }
+                );
             }
             _ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)),
         }
@@ -914,45 +913,47 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         // All types must be simd vector types
         require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
-        require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
-            span,
-            name,
-            ty: arg_tys[2]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
+        );
+        require_simd!(
+            arg_tys[2],
+            InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
+        );
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         // Of the same length:
         let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
         let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len
-        });
-        require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: out_len2
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len
+            }
+        );
+        require!(
+            in_len == out_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: out_len2
+            }
+        );
 
         // The return type must match the first argument type
-        require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType {
-            span,
-            name,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_ty,
+            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
+        );
 
         // This counts how many pointers
         fn ptr_count(t: Ty<'_>) -> usize {
@@ -979,15 +980,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 (ptr_count(element_ty1), non_ptr(element_ty1))
             }
             _ => {
-                require!(false, InvalidMonomorphization::ExpectedElementType {
-                    span,
-                    name,
-                    expected_element: element_ty1,
-                    second_arg: arg_tys[1],
-                    in_elem,
-                    in_ty,
-                    mutability: ExpectedPointerMutability::Not,
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ExpectedElementType {
+                        span,
+                        name,
+                        expected_element: element_ty1,
+                        second_arg: arg_tys[1],
+                        in_elem,
+                        in_ty,
+                        mutability: ExpectedPointerMutability::Not,
+                    }
+                );
                 unreachable!();
             }
         };
@@ -1000,12 +1004,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         match *element_ty2.kind() {
             ty::Int(_) => (),
             _ => {
-                require!(false, InvalidMonomorphization::ThirdArgElementType {
-                    span,
-                    name,
-                    expected_element: element_ty2,
-                    third_arg: arg_tys[2]
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ThirdArgElementType {
+                        span,
+                        name,
+                        expected_element: element_ty2,
+                        third_arg: arg_tys[2]
+                    }
+                );
             }
         }
 
@@ -1029,36 +1036,40 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         // All types must be simd vector types
         require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
-        require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
-            span,
-            name,
-            ty: arg_tys[2]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
+        );
+        require_simd!(
+            arg_tys[2],
+            InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
+        );
 
         // Of the same length:
         let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
         let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
-        require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len: element_len1
-        });
-        require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: element_len2
-        });
+        require!(
+            in_len == element_len1,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len: element_len1
+            }
+        );
+        require!(
+            in_len == element_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: element_len2
+            }
+        );
 
         // This counts how many pointers
         fn ptr_count(t: Ty<'_>) -> usize {
@@ -1086,15 +1097,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 (ptr_count(element_ty1), non_ptr(element_ty1))
             }
             _ => {
-                require!(false, InvalidMonomorphization::ExpectedElementType {
-                    span,
-                    name,
-                    expected_element: element_ty1,
-                    second_arg: arg_tys[1],
-                    in_elem,
-                    in_ty,
-                    mutability: ExpectedPointerMutability::Mut,
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ExpectedElementType {
+                        span,
+                        name,
+                        expected_element: element_ty1,
+                        second_arg: arg_tys[1],
+                        in_elem,
+                        in_ty,
+                        mutability: ExpectedPointerMutability::Mut,
+                    }
+                );
                 unreachable!();
             }
         };
@@ -1106,12 +1120,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         match *element_ty2.kind() {
             ty::Int(_) => (),
             _ => {
-                require!(false, InvalidMonomorphization::ThirdArgElementType {
-                    span,
-                    name,
-                    expected_element: element_ty2,
-                    third_arg: arg_tys[2]
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ThirdArgElementType {
+                        span,
+                        name,
+                        expected_element: element_ty2,
+                        third_arg: arg_tys[2]
+                    }
+                );
             }
         }
 
@@ -1278,13 +1295,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         ($name:ident : $vec_op:expr, $float_reduce:ident, $ordered:expr, $op:ident,
          $identity:expr) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match *in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => {
                         let r = bx.vector_reduce_op(args[0].immediate(), $vec_op);
@@ -1350,13 +1364,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     macro_rules! minmax_red {
         ($name:ident: $int_red:ident, $float_red:ident) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match *in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
                     ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
@@ -1380,13 +1391,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         ($name:ident : $op:expr, $boolean:expr) => {
             if name == sym::$name {
                 let input = if !$boolean {
-                    require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                        span,
-                        name,
-                        in_elem,
-                        in_ty,
-                        ret_ty
-                    });
+                    require!(
+                        ret_ty == in_elem,
+                        InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                    );
                     args[0].immediate()
                 } else {
                     match *in_elem.kind() {
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f6ad0c79de5..ce88ac39021 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -444,7 +444,6 @@ impl WriteBackendMethods for GccCodegenBackend {
     }
     fn autodiff(
         _cgcx: &CodegenContext<Self>,
-        _tcx: TyCtxt<'_>,
         _module: &ModuleCodegen<Self::Module>,
         _diff_fncs: Vec<AutoDiffItem>,
         _config: &ModuleConfig,
@@ -494,9 +493,10 @@ fn target_features_cfg(
     sess.target
         .rust_target_features()
         .iter()
-        .filter(|&&(_, gate, _)| gate.in_cfg())
         .filter_map(|&(feature, gate, _)| {
-            if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() {
+            if allow_unstable
+                || (gate.in_cfg() && (sess.is_nightly_build() || gate.requires_nightly().is_none()))
+            {
                 Some(feature)
             } else {
                 None
diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs
index 239902df7f0..a2df7b2596f 100644
--- a/compiler/rustc_codegen_gcc/src/mono_item.rs
+++ b/compiler/rustc_codegen_gcc/src/mono_item.rs
@@ -61,10 +61,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         // compiler-rt, then we want to implicitly compile everything with hidden
         // visibility as we're going to link this object all over the place but
         // don't want the symbols to get exported.
-        if linkage != Linkage::Internal
-            && linkage != Linkage::Private
-            && self.tcx.is_compiler_builtins(LOCAL_CRATE)
-        {
+        if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) {
             #[cfg(feature = "master")]
             decl.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
         } else {
diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs
index 4ea5544721d..cb08723431a 100644
--- a/compiler/rustc_codegen_gcc/src/type_.rs
+++ b/compiler/rustc_codegen_gcc/src/type_.rs
@@ -4,13 +4,13 @@ use std::convert::TryInto;
 #[cfg(feature = "master")]
 use gccjit::CType;
 use gccjit::{RValue, Struct, Type};
+use rustc_abi::{AddressSpace, Align, Integer, Size};
 use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, DerivedTypeCodegenMethods, TypeMembershipCodegenMethods,
 };
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, ty};
-use rustc_target::abi::{AddressSpace, Align, Integer, Size};
 
 use crate::common::TypeReflection;
 use crate::context::CodegenCx;
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 0efdf36da48..8b8b54753e7 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -3,7 +3,9 @@ use std::fmt::Write;
 use gccjit::{Struct, Type};
 use rustc_abi as abi;
 use rustc_abi::Primitive::*;
-use rustc_abi::{BackendRepr, FieldsShape, Integer, PointeeInfo, Size, Variants};
+use rustc_abi::{
+    BackendRepr, FieldsShape, Integer, PointeeInfo, Reg, Size, TyAbiInterface, Variants,
+};
 use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, DerivedTypeCodegenMethods, LayoutTypeCodegenMethods,
 };
@@ -11,8 +13,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt};
-use rustc_target::abi::TyAbiInterface;
-use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
+use rustc_target::callconv::{CastTarget, FnAbi};
 
 use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
 use crate::context::CodegenCx;
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
index 696197d7377..385e41a6881 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort1.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: signal
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -49,7 +50,7 @@ fn test_fail() -> ! {
     unsafe { intrinsics::abort() };
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     test_fail();
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
index 714cd6c0f38..6c66a930e07 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort2.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: signal
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -50,8 +51,8 @@ fn fail() -> i32 {
     0
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     fail();
     0
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs
index c3c08c29c6d..e18a4ced6bc 100644
--- a/compiler/rustc_codegen_gcc/tests/run/array.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/array.rs
@@ -7,10 +7,11 @@
 //     5
 //     10
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] {
     [42, 10, 5]
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let array = [42, 7, 5];
     let array2 = make_array();
     unsafe {
diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs
index 2a47f0c2966..4d414c577a6 100644
--- a/compiler/rustc_codegen_gcc/tests/run/assign.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs
@@ -6,10 +6,11 @@
 //     10
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -142,8 +143,8 @@ fn inc(num: isize) -> isize {
 }
 
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _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/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs
index 46c47bc54ed..c7a236f74f9 100644
--- a/compiler/rustc_codegen_gcc/tests/run/closure.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs
@@ -8,10 +8,11 @@
 //     Int argument: 2
 //     Both args: 11
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -22,8 +23,8 @@ mod libc {
     }
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let string = "Arg: %d\n\0";
     let mut closure = || {
         unsafe {
diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs
index 039ef94eaa7..b02359702ed 100644
--- a/compiler/rustc_codegen_gcc/tests/run/condition.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs
@@ -5,10 +5,11 @@
 //   stdout: true
 //     1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -19,8 +20,8 @@ mod libc {
     }
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         if argc == 1 {
             libc::printf(b"true\n\0" as *const u8 as *const i8);
diff --git a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
index e66a859ad69..042e44080c5 100644
--- a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 0
 
-#![feature(auto_traits, lang_items, no_core, start)]
+#![feature(auto_traits, lang_items, no_core)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     0
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit.rs b/compiler/rustc_codegen_gcc/tests/run/exit.rs
index bf1cbeef302..9a7c91c0adb 100644
--- a/compiler/rustc_codegen_gcc/tests/run/exit.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/exit.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 2
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 mod libc {
     #[link(name = "c")]
@@ -41,8 +42,8 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         libc::exit(2);
     }
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
index be7a233efda..c50d2b0d710 100644
--- a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 1
 
-#![feature(auto_traits, lang_items, no_core, start)]
+#![feature(auto_traits, lang_items, no_core)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     1
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
index ed1bf72bb27..98b351e5044 100644
--- a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -26,8 +27,8 @@ fn call_func(func: fn(i16) -> i8, param: i16) -> i8 {
     func(param)
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         let result = call_func(i16_as_i8, argc as i16) as isize;
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);
diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs
index bfe73c38435..58a26801b67 100644
--- a/compiler/rustc_codegen_gcc/tests/run/int.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/int.rs
@@ -3,8 +3,6 @@
 // Run-time:
 //   status: 0
 
-#![feature(const_black_box)]
-
 /*
  * Code
  */
diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
index 3ae79338216..9be64f991ee 100644
--- a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
@@ -8,10 +8,11 @@
 //     11
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -148,8 +149,8 @@ fn update_num(num: &mut isize) {
     *num = *num + 5;
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _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/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs
index 0e44fc580b8..c92d3cc0b8f 100644
--- a/compiler/rustc_codegen_gcc/tests/run/operations.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs
@@ -6,10 +6,11 @@
 //     10
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -231,8 +232,8 @@ pub fn panic_const_mul_overflow() -> ! {
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);
diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
index 2b8812ad51c..0ba49e7187f 100644
--- a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -24,8 +25,8 @@ fn make_array() -> [u8; 3] {
     [42, 10, 5]
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         let ptr = ONE as *mut usize;
         let value = ptr as usize;
diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
index f2a5a2e4384..3cc1e274001 100644
--- a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
@@ -6,11 +6,12 @@
 //     10
 //     42
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 #[lang = "copy"]
 pub unsafe trait Copy {}
@@ -61,8 +62,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3
     )
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[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 {
         libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs
index fba93fc1554..825fcb8a081 100644
--- a/compiler/rustc_codegen_gcc/tests/run/slice.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 5
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -26,8 +27,8 @@ fn index_slice(s: &[u32]) -> u32 {
     }
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let array = [42, 7, 5];
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));
diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs
index a17ea2a4893..80c8782c4b1 100644
--- a/compiler/rustc_codegen_gcc/tests/run/static.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/static.rs
@@ -9,11 +9,12 @@
 //      12
 //      1
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -98,8 +99,8 @@ static mut WITH_REF: WithRef = WithRef {
     refe: unsafe { &TEST },
 };
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _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/compiler/rustc_codegen_gcc/tests/run/structs.rs b/compiler/rustc_codegen_gcc/tests/run/structs.rs
index d6455667400..59b8f358863 100644
--- a/compiler/rustc_codegen_gcc/tests/run/structs.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/structs.rs
@@ -5,11 +5,12 @@
 //   stdout: 1
 //     2
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -55,8 +56,8 @@ fn one() -> isize {
     1
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let test = Test {
         field: one(),
     };
diff --git a/compiler/rustc_codegen_gcc/tests/run/tuple.rs b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
index 8a7d85ae867..ed60a56a68c 100644
--- a/compiler/rustc_codegen_gcc/tests/run/tuple.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
@@ -4,11 +4,12 @@
 //   status: 0
 //   stdout: 3
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -42,8 +43,8 @@ mod libc {
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let test: (isize, isize, isize) = (3, 1, 4);
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);