Skip to content

GCC backend subtree update #143161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Jun 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8ad6957
Cleanup CodegenFnAttrFlags
Noratrieb May 24, 2025
0348509
Pass PlaceRef rather than Bx::Value to codegen_intrinsic_call
bjorn3 May 22, 2025
f994713
Remove usage of FnAbi in codegen_intrinsic_call
bjorn3 May 22, 2025
f6489c3
Remove codegen_unit from MiscCodegenMethods
bjorn3 Dec 13, 2024
4d47f6d
Remove a couple of uses of interior mutability around statics
bjorn3 Dec 13, 2024
f297400
Make predefine methods take &mut self
bjorn3 Jan 9, 2025
96be6ef
Remove methods from StaticCodegenMethods that are not called in cg_ss…
bjorn3 Jan 9, 2025
244ea12
Mark all optimize methods and the codegen method as safe
bjorn3 Jan 9, 2025
0c6f946
Remove unused arg_memory_ty method
bjorn3 Nov 7, 2024
dbbfb6e
get rid of rustc_codegen_ssa::common::AtomicOrdering
RalfJung May 28, 2025
acb2fcd
Rollup merge of #141507 - RalfJung:atomic-intrinsics, r=bjorn3
matthiaskrgr May 30, 2025
5c4b797
Use layout field of OperandRef and PlaceRef in codegen_intrinsic_call
bjorn3 May 30, 2025
926c8c8
Use layout field of OperandRef in generic_simd_intrinsic
bjorn3 May 30, 2025
6c6c31d
Avoid computing function type for intrinsic instances
bjorn3 May 30, 2025
f383b17
Directly use from_immediate for handling bool
bjorn3 May 30, 2025
f69d8fc
Merge branch 'master' into sync_from_rust_2025_06_02
antoyo Jun 2, 2025
2d7d0ee
Update to nightly-2025-06-02
antoyo Jun 2, 2025
38f134c
Remove unneeded patch
antoyo Jun 2, 2025
2e89179
Make comment more specific
antoyo Jun 5, 2025
ed441b6
Added support for testing the backend with abi-cafe
FractalFir Jun 14, 2025
395bca1
Merge pull request #710 from FractalFir/abi-cafe
antoyo Jun 18, 2025
b2b117e
Fixed some clippy warnings.
FractalFir Jun 19, 2025
962a08f
Merge pull request #716 from FractalFir/abi-cafe
antoyo Jun 20, 2025
8571aee
Skip needless calls to get_align in some cases.
FractalFir Jun 19, 2025
54b1ff5
Merge pull request #718 from FractalFir/needless_align
antoyo Jun 24, 2025
b03f7f8
Refactored the codebase to use Function instead of RValue where possi…
FractalFir Jun 25, 2025
79564c8
Merge pull request #720 from FractalFir/func_refactor
antoyo Jun 25, 2025
413821f
Remove unnecesary uses of the 'current_func' field, replacing it with…
FractalFir Jun 26, 2025
98d65f2
Merge pull request #722 from FractalFir/func_refactor
antoyo Jun 26, 2025
7c71c83
Fix type_name intrinsic
antoyo Jun 28, 2025
5735bb3
Merge branch 'master' into sync_from_rust_2025_06_02
antoyo Jun 28, 2025
1449894
Fix to use Function instead of RValue
antoyo Jun 28, 2025
eb4d429
Fix for libgccjit 12
antoyo Jun 28, 2025
c7c1622
Ignore failing test
antoyo Jun 28, 2025
49e65a0
Remove commented code
antoyo Jun 28, 2025
f876b18
Add TODOs
antoyo Jun 28, 2025
8385f3c
Stop skipping libcore's f16::test_total_cmp
antoyo Jun 28, 2025
b7091ec
Merge pull request #694 from rust-lang/sync_from_rust_2025_06_02
antoyo Jun 28, 2025
f8491b1
Merge commit 'b7091eca6d8eb0fe88b58cc9a7aec405d8de5b85' into subtree-…
GuillaumeGomez Jun 28, 2025
13d0ef3
Remove unwanted semi-colon in `rustc_codegen_gcc`
GuillaumeGomez Jun 28, 2025
a420d39
Fix signature of `filter_landing_pad`
GuillaumeGomez Jun 28, 2025
3dcbc1e
Remove `()` returned value
GuillaumeGomez Jun 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions compiler/rustc_codegen_gcc/build_system/src/abi_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::ffi::OsStr;
use std::path::Path;

use crate::utils::run_command_with_output;

fn show_usage() {
println!(
r#"
`abi-test` command help:
--help : Show this help"#
);
}

pub fn run() -> Result<(), String> {
let mut args = std::env::args().skip(2);
// FractalFir: In the future, I'd like to add some more subcommands / options.
// So, this loop ought to stay for that purpose. It should also stay as a while loop(to parse args)
#[allow(clippy::never_loop, clippy::while_let_on_iterator)]
while let Some(arg) = args.next() {
match arg.as_str() {
"--help" => {
show_usage();
return Ok(());
}
_ => return Err(format!("Unknown option {arg:?}")),
}
}
// Ensure that we have a cloned version of abi-cafe on hand.
crate::utils::git_clone(
"https://github.com/Gankra/abi-cafe.git",
Some("clones/abi-cafe".as_ref()),
true,
)
.map_err(|err| (format!("Git clone failed with message: {err:?}!")))?;
// Configure abi-cafe to use the exact same rustc version we use - this is crucial.
// Otherwise, the concept of ABI compatibility becomes meanignless.
std::fs::copy("rust-toolchain", "clones/abi-cafe/rust-toolchain")
.expect("Could not copy toolchain configs!");
// Get the backend path.
// We will use the *debug* build of the backend - it has more checks enabled.
let backend_path = std::path::absolute("target/debug/librustc_codegen_gcc.so").unwrap();
let backend_arg = format!("--add-rustc-codegen-backend=cg_gcc:{}", backend_path.display());
// Run ABI cafe using cargo.
let cmd: &[&dyn AsRef<OsStr>] = &[
&"cargo",
&"run",
&"--release",
&"--",
&backend_arg,
// Test rust-LLVM to Rust-GCC calls
&"--pairs",
&"rustc_calls_cg_gcc",
&"--pairs",
&"cg_gcc_calls_rustc",
// Test Rust-GCC to C calls
&"--pairs",
&"cg_gcc_calls_c",
&"--pairs",
&"c_calls_cg_gcc",
];
// Run ABI cafe.
run_command_with_output(cmd, Some(Path::new("clones/abi-cafe")))?;

Ok(())
}
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_gcc/build_system/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{env, process};

mod abi_test;
mod build;
mod clean;
mod clone_gcc;
Expand All @@ -12,7 +13,6 @@ mod rust_tools;
mod rustc_info;
mod test;
mod utils;

const BUILD_DIR: &str = "build";

macro_rules! arg_error {
Expand Down Expand Up @@ -44,7 +44,8 @@ Commands:
info : Displays information about the build environment and project configuration.
clone-gcc : Clones the GCC compiler from a specified source.
fmt : Runs rustfmt
fuzz : Fuzzes `cg_gcc` using rustlantis"
fuzz : Fuzzes `cg_gcc` using rustlantis
abi-test : Runs the abi-cafe test suite on the codegen, checking for ABI compatibility with LLVM"
);
}

Expand All @@ -59,6 +60,7 @@ pub enum Command {
Info,
Fmt,
Fuzz,
AbiTest,
}

fn main() {
Expand All @@ -77,6 +79,7 @@ fn main() {
Some("test") => Command::Test,
Some("info") => Command::Info,
Some("clone-gcc") => Command::CloneGcc,
Some("abi-test") => Command::AbiTest,
Some("fmt") => Command::Fmt,
Some("fuzz") => Command::Fuzz,
Some("--help") => {
Expand All @@ -102,6 +105,7 @@ fn main() {
Command::CloneGcc => clone_gcc::run(),
Command::Fmt => fmt::run(),
Command::Fuzz => fuzz::run(),
Command::AbiTest => abi_test::run(),
} {
eprintln!("Command failed to run: {e}");
process::exit(1);
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_codegen_gcc/build_system/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -738,14 +738,7 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
let path = get_sysroot_dir().join("sysroot_src/library/coretests");
let _ = remove_dir_all(path.join("target"));
// TODO(antoyo): run in release mode when we fix the failures.
// TODO(antoyo): remove the --skip f16::test_total_cmp when this issue is fixed:
// https://github.com/rust-lang/rust/issues/141503
run_cargo_command(
&[&"test", &"--", &"--skip", &"f16::test_total_cmp"],
Some(&path),
env,
args,
)?;
run_cargo_command(&[&"test"], Some(&path), env, args)?;
Ok(())
}

Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-05-21"
channel = "nightly-2025-06-02"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
65 changes: 41 additions & 24 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
self.block
}

fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> {
let func = cx.rvalue_as_function(func);
fn append_block(_: &'a CodegenCx<'gcc, 'tcx>, func: Function<'gcc>, name: &str) -> Block<'gcc> {
func.new_block(name)
}

Expand Down Expand Up @@ -782,6 +781,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
return self.context.new_call(self.location, fmod, &[a, b]);
}
TypeKind::FP128 => {
// TODO(antoyo): use get_simple_function_f128_2args.
let f128_type = self.type_f128();
let fmodf128 = self.context.new_function(
None,
Expand Down Expand Up @@ -938,22 +938,36 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
let block = self.llbb();
let function = block.get_function();
// NOTE(FractalFir): In some cases, we *should* skip the call to get_aligned.
// For example, calling `get_aligned` on a i8 is pointless(since it can only be 1 aligned)
// Calling get_aligned on a `u128`/`i128` causes the attribute to become "stacked"
//
// From GCCs perspective:
// __int128_t __attribute__((aligned(16))) __attribute__((aligned(16)))
// and:
// __int128_t __attribute__((aligned(16)))
// are 2 distinct, incompatible types.
//
// So, we skip the call to `get_aligned` in such a case. *Ideally*, we could do this for all the types,
// but the GCC APIs to facilitate this just aren't quite there yet.

// This checks that we only skip `get_aligned` on 128 bit ints if they have the correct alignment.
// Otherwise, this may be an under-aligned load, so we will still call get_aligned.
let mut can_skip_align = (pointee_ty == self.cx.u128_type
|| pointee_ty == self.cx.i128_type)
&& align == self.int128_align;
// We can skip the call to `get_aligned` for byte-sized types with alignment of 1.
can_skip_align = can_skip_align
|| (pointee_ty == self.cx.u8_type || pointee_ty == self.cx.i8_type)
&& align.bytes() == 1;
// Skip the call to `get_aligned` when possible.
let aligned_type =
if can_skip_align { pointee_ty } else { pointee_ty.get_aligned(align.bytes()) };

let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
// NOTE: instead of returning the dereference here, we have to assign it to a variable in
// the current basic block. Otherwise, it could be used in another basic block, causing a
// dereference after a drop, for instance.
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
// Ideally, we shouldn't need to do this check.
// FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
// the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
// under-aligned loads correctly.
let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type)
&& align == self.int128_align
{
pointee_ty
} else {
pointee_ty.get_aligned(align.bytes())
};
let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
let deref = ptr.dereference(self.location).to_rvalue();
let loaded_value = function.new_local(
self.location,
Expand Down Expand Up @@ -1105,7 +1119,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
// TODO(antoyo)
}

fn store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
fn store(&mut self, mut val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
if self.structs_as_pointer.borrow().contains(&val) {
// NOTE: hack to workaround a limitation of the rustc API: see comment on
// CodegenCx.structs_as_pointer
val = val.dereference(self.location).to_rvalue();
}

self.store_with_flags(val, ptr, align, MemFlags::empty())
}

Expand Down Expand Up @@ -1551,16 +1571,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
aggregate_value
}

fn set_personality_fn(&mut self, _personality: RValue<'gcc>) {
fn set_personality_fn(&mut self, _personality: Function<'gcc>) {
#[cfg(feature = "master")]
{
let personality = self.rvalue_as_function(_personality);
self.current_func().set_personality_function(personality);
}
self.current_func().set_personality_function(_personality);
}

#[cfg(feature = "master")]
fn cleanup_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
fn cleanup_landing_pad(&mut self, pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
self.set_personality_fn(pers_fn);

// NOTE: insert the current block in a variable so that a later call to invoke knows to
Expand All @@ -1581,7 +1598,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
}

#[cfg(not(feature = "master"))]
fn cleanup_landing_pad(&mut self, _pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
fn cleanup_landing_pad(&mut self, _pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
let value1 = self
.current_func()
.new_local(self.location, self.u8_type.make_pointer(), "landing_pad0")
Expand All @@ -1591,7 +1608,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
(value1, value2)
}

fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) {
fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) {
// TODO(antoyo): generate the correct landing pad
self.cleanup_landing_pad(pers_fn);
}
Expand Down
13 changes: 0 additions & 13 deletions compiler/rustc_codegen_gcc/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,19 +234,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
match cv {
Scalar::Int(int) => {
let data = int.to_bits(layout.size(self));

// FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code
// the paths for floating-point values.
// TODO: Remove this code?
/*if ty == self.float_type {
return self
.context
.new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64);
}
if ty == self.double_type {
return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64));
}*/

let value = self.const_uint_big(self.type_ix(bitsize), data);
let bytesize = layout.size(self).bytes();
if bitsize > 1 && ty.is_integral() && bytesize as u32 == ty.get_size() {
Expand Down
Loading
Loading