Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit dddd7ab

Browse files
committed
Auto merge of #143161 - GuillaumeGomez:subtree-update_cg_gcc_2025年06月28日, r=GuillaumeGomez
GCC backend subtree update cc `@antoyo` r? ghost
2 parents 8141c22 + 3dcbc1e commit dddd7ab

File tree

12 files changed

+150
-117
lines changed

12 files changed

+150
-117
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use std::ffi::OsStr;
2+
use std::path::Path;
3+
4+
use crate::utils::run_command_with_output;
5+
6+
fn show_usage() {
7+
println!(
8+
r#"
9+
`abi-test` command help:
10+
--help : Show this help"#
11+
);
12+
}
13+
14+
pub fn run() -> Result<(), String> {
15+
let mut args = std::env::args().skip(2);
16+
// FractalFir: In the future, I'd like to add some more subcommands / options.
17+
// So, this loop ought to stay for that purpose. It should also stay as a while loop(to parse args)
18+
#[allow(clippy::never_loop, clippy::while_let_on_iterator)]
19+
while let Some(arg) = args.next() {
20+
match arg.as_str() {
21+
"--help" => {
22+
show_usage();
23+
return Ok(());
24+
}
25+
_ => return Err(format!("Unknown option {arg:?}")),
26+
}
27+
}
28+
// Ensure that we have a cloned version of abi-cafe on hand.
29+
crate::utils::git_clone(
30+
"https://github.com/Gankra/abi-cafe.git",
31+
Some("clones/abi-cafe".as_ref()),
32+
true,
33+
)
34+
.map_err(|err| (format!("Git clone failed with message: {err:?}!")))?;
35+
// Configure abi-cafe to use the exact same rustc version we use - this is crucial.
36+
// Otherwise, the concept of ABI compatibility becomes meanignless.
37+
std::fs::copy("rust-toolchain", "clones/abi-cafe/rust-toolchain")
38+
.expect("Could not copy toolchain configs!");
39+
// Get the backend path.
40+
// We will use the *debug* build of the backend - it has more checks enabled.
41+
let backend_path = std::path::absolute("target/debug/librustc_codegen_gcc.so").unwrap();
42+
let backend_arg = format!("--add-rustc-codegen-backend=cg_gcc:{}", backend_path.display());
43+
// Run ABI cafe using cargo.
44+
let cmd: &[&dyn AsRef<OsStr>] = &[
45+
&"cargo",
46+
&"run",
47+
&"--release",
48+
&"--",
49+
&backend_arg,
50+
// Test rust-LLVM to Rust-GCC calls
51+
&"--pairs",
52+
&"rustc_calls_cg_gcc",
53+
&"--pairs",
54+
&"cg_gcc_calls_rustc",
55+
// Test Rust-GCC to C calls
56+
&"--pairs",
57+
&"cg_gcc_calls_c",
58+
&"--pairs",
59+
&"c_calls_cg_gcc",
60+
];
61+
// Run ABI cafe.
62+
run_command_with_output(cmd, Some(Path::new("clones/abi-cafe")))?;
63+
64+
Ok(())
65+
}

‎compiler/rustc_codegen_gcc/build_system/src/main.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{env, process};
22

3+
mod abi_test;
34
mod build;
45
mod clean;
56
mod clone_gcc;
@@ -12,7 +13,6 @@ mod rust_tools;
1213
mod rustc_info;
1314
mod test;
1415
mod utils;
15-
1616
const BUILD_DIR: &str = "build";
1717

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

@@ -59,6 +60,7 @@ pub enum Command {
5960
Info,
6061
Fmt,
6162
Fuzz,
63+
AbiTest,
6264
}
6365

6466
fn main() {
@@ -77,6 +79,7 @@ fn main() {
7779
Some("test") => Command::Test,
7880
Some("info") => Command::Info,
7981
Some("clone-gcc") => Command::CloneGcc,
82+
Some("abi-test") => Command::AbiTest,
8083
Some("fmt") => Command::Fmt,
8184
Some("fuzz") => Command::Fuzz,
8285
Some("--help") => {
@@ -102,6 +105,7 @@ fn main() {
102105
Command::CloneGcc => clone_gcc::run(),
103106
Command::Fmt => fmt::run(),
104107
Command::Fuzz => fuzz::run(),
108+
Command::AbiTest => abi_test::run(),
105109
} {
106110
eprintln!("Command failed to run: {e}");
107111
process::exit(1);

‎compiler/rustc_codegen_gcc/build_system/src/test.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -738,14 +738,7 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
738738
let path = get_sysroot_dir().join("sysroot_src/library/coretests");
739739
let _ = remove_dir_all(path.join("target"));
740740
// TODO(antoyo): run in release mode when we fix the failures.
741-
// TODO(antoyo): remove the --skip f16::test_total_cmp when this issue is fixed:
742-
// https://github.com/rust-lang/rust/issues/141503
743-
run_cargo_command(
744-
&[&"test", &"--", &"--skip", &"f16::test_total_cmp"],
745-
Some(&path),
746-
env,
747-
args,
748-
)?;
741+
run_cargo_command(&[&"test"], Some(&path), env, args)?;
749742
Ok(())
750743
}
751744

‎compiler/rustc_codegen_gcc/patches/0001-Pin-compiler_builtins-to-0.1.160.patch

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2025-05-21"
2+
channel = "nightly-2025-06-02"
33
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

‎compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
520520
self.block
521521
}
522522

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

@@ -782,6 +781,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
782781
return self.context.new_call(self.location, fmod, &[a, b]);
783782
}
784783
TypeKind::FP128 => {
784+
// TODO(antoyo): use get_simple_function_f128_2args.
785785
let f128_type = self.type_f128();
786786
let fmodf128 = self.context.new_function(
787787
None,
@@ -938,22 +938,36 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
938938
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
939939
let block = self.llbb();
940940
let function = block.get_function();
941+
// NOTE(FractalFir): In some cases, we *should* skip the call to get_aligned.
942+
// For example, calling `get_aligned` on a i8 is pointless(since it can only be 1 aligned)
943+
// Calling get_aligned on a `u128`/`i128` causes the attribute to become "stacked"
944+
//
945+
// From GCCs perspective:
946+
// __int128_t __attribute__((aligned(16))) __attribute__((aligned(16)))
947+
// and:
948+
// __int128_t __attribute__((aligned(16)))
949+
// are 2 distinct, incompatible types.
950+
//
951+
// So, we skip the call to `get_aligned` in such a case. *Ideally*, we could do this for all the types,
952+
// but the GCC APIs to facilitate this just aren't quite there yet.
953+
954+
// This checks that we only skip `get_aligned` on 128 bit ints if they have the correct alignment.
955+
// Otherwise, this may be an under-aligned load, so we will still call get_aligned.
956+
let mut can_skip_align = (pointee_ty == self.cx.u128_type
957+
|| pointee_ty == self.cx.i128_type)
958+
&& align == self.int128_align;
959+
// We can skip the call to `get_aligned` for byte-sized types with alignment of 1.
960+
can_skip_align = can_skip_align
961+
|| (pointee_ty == self.cx.u8_type || pointee_ty == self.cx.i8_type)
962+
&& align.bytes() == 1;
963+
// Skip the call to `get_aligned` when possible.
964+
let aligned_type =
965+
if can_skip_align { pointee_ty } else { pointee_ty.get_aligned(align.bytes()) };
966+
967+
let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
941968
// NOTE: instead of returning the dereference here, we have to assign it to a variable in
942969
// the current basic block. Otherwise, it could be used in another basic block, causing a
943970
// dereference after a drop, for instance.
944-
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
945-
// Ideally, we shouldn't need to do this check.
946-
// FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
947-
// the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
948-
// under-aligned loads correctly.
949-
let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type)
950-
&& align == self.int128_align
951-
{
952-
pointee_ty
953-
} else {
954-
pointee_ty.get_aligned(align.bytes())
955-
};
956-
let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
957971
let deref = ptr.dereference(self.location).to_rvalue();
958972
let loaded_value = function.new_local(
959973
self.location,
@@ -1105,7 +1119,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
11051119
// TODO(antoyo)
11061120
}
11071121

1108-
fn store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
1122+
fn store(&mut self, mut val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
1123+
if self.structs_as_pointer.borrow().contains(&val) {
1124+
// NOTE: hack to workaround a limitation of the rustc API: see comment on
1125+
// CodegenCx.structs_as_pointer
1126+
val = val.dereference(self.location).to_rvalue();
1127+
}
1128+
11091129
self.store_with_flags(val, ptr, align, MemFlags::empty())
11101130
}
11111131

@@ -1551,16 +1571,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
15511571
aggregate_value
15521572
}
15531573

1554-
fn set_personality_fn(&mut self, _personality: RValue<'gcc>) {
1574+
fn set_personality_fn(&mut self, _personality: Function<'gcc>) {
15551575
#[cfg(feature = "master")]
1556-
{
1557-
let personality = self.rvalue_as_function(_personality);
1558-
self.current_func().set_personality_function(personality);
1559-
}
1576+
self.current_func().set_personality_function(_personality);
15601577
}
15611578

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

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

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

1594-
fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) {
1611+
fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) {
15951612
// TODO(antoyo): generate the correct landing pad
15961613
self.cleanup_landing_pad(pers_fn);
15971614
}

‎compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,19 +234,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
234234
match cv {
235235
Scalar::Int(int) => {
236236
let data = int.to_bits(layout.size(self));
237-
238-
// FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code
239-
// the paths for floating-point values.
240-
// TODO: Remove this code?
241-
/*if ty == self.float_type {
242-
return self
243-
.context
244-
.new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64);
245-
}
246-
if ty == self.double_type {
247-
return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64));
248-
}*/
249-
250237
let value = self.const_uint_big(self.type_ix(bitsize), data);
251238
let bytesize = layout.size(self).bytes();
252239
if bitsize > 1 && ty.is_integral() && bytesize as u32 == ty.get_size() {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /