Skip to content

Commit 57f772f

Browse files
committed
Auto merge of #155978 - GuillaumeGomez:subtree-update_cg_gcc_2026-04-29, r=antoyo
GCC backend subtree sync r? ghost
2 parents a021a77 + f3d34dc commit 57f772f

35 files changed

Lines changed: 727 additions & 207 deletions

compiler/rustc_codegen_gcc/.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ jobs:
101101
102102
- name: Run y.sh cargo build
103103
run: |
104-
./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
104+
CARGO_PROFILE_DEV_LTO=no ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
105105
106106
- name: Clean
107107
run: |
@@ -119,7 +119,7 @@ jobs:
119119

120120
- name: Run tests
121121
run: |
122-
./y.sh test --release --clean --build-sysroot ${{ matrix.commands }}
122+
./y.sh test --release --clean --build-sysroot --no-builtins-tests ${{ matrix.commands }}
123123
124124
duplicates:
125125
runs-on: ubuntu-24.04

compiler/rustc_codegen_gcc/.github/workflows/failures.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ jobs:
4848

4949
- name: Install libgccjit12
5050
if: matrix.libgccjit_version.gcc == 'libgccjit12.so'
51-
run: sudo apt-get install libgccjit-12-dev
51+
run: |
52+
sudo apt-get update
53+
sudo apt-get install libgccjit-12-dev
5254
5355
- name: Setup path to libgccjit
5456
if: matrix.libgccjit_version.gcc == 'libgccjit12.so'

compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ jobs:
4646

4747
- name: Install packages
4848
# `llvm-14-tools` is needed to install the `FileCheck` binary which is used for asm tests.
49-
run: sudo apt-get install ninja-build ripgrep llvm-14-tools libgccjit-12-dev
49+
run: |
50+
sudo apt-get update
51+
sudo apt-get install ninja-build ripgrep llvm-14-tools libgccjit-12-dev
5052
5153
- name: Setup path to libgccjit
5254
run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml

compiler/rustc_codegen_gcc/.github/workflows/m68k.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
run: |
8484
./y.sh prepare --only-libcore --cross
8585
./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
86-
CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build -Zjson-target-spec --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
86+
CARGO_PROFILE_DEV_LTO=no CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build -Zjson-target-spec --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
8787
./y.sh clean all
8888
8989
- name: Build
@@ -110,7 +110,7 @@ jobs:
110110
111111
vm_dir=$(pwd)/vm
112112
cd tests/hello-world
113-
CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ../../y.sh cargo build --target m68k-unknown-linux-gnu
113+
CARGO_PROFILE_DEV_LTO=no CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ../../y.sh cargo build --target m68k-unknown-linux-gnu
114114
sudo cp target/m68k-unknown-linux-gnu/debug/hello_world $vm_dir/home/
115115
sudo chroot $vm_dir qemu-m68k-static /home/hello_world > hello_world_stdout
116116
expected_output="40"

compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ jobs:
5050
run: |
5151
mkdir intel-sde
5252
cd intel-sde
53-
dir=sde-external-9.33.0-2024-01-07-lin
53+
version=10.8.0-2026-03-15
54+
url_path=915934
55+
dir=sde-external-$version-lin
5456
file=$dir.tar.xz
55-
wget https://downloadmirror.intel.com/813591/$file
57+
wget https://downloadmirror.intel.com/$url_path/$file
5658
tar xvf $file
5759
sudo mkdir /usr/share/intel-sde
5860
sudo cp -r $dir/* /usr/share/intel-sde

compiler/rustc_codegen_gcc/Cargo.toml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,8 @@ license = "MIT OR Apache-2.0"
99
crate-type = ["dylib"]
1010

1111
[[test]]
12-
name = "lang_tests_debug"
13-
path = "tests/lang_tests_debug.rs"
14-
harness = false
15-
[[test]]
16-
name = "lang_tests_release"
17-
path = "tests/lang_tests_release.rs"
12+
name = "lang_tests"
13+
path = "tests/lang_tests.rs"
1814
harness = false
1915

2016
[features]

compiler/rustc_codegen_gcc/build_system/src/test.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ fn get_runners() -> Runners {
4343
runners.insert("--extended-regex-tests", ("Run extended regex tests", extended_regex_tests));
4444
runners.insert("--mini-tests", ("Run mini tests", mini_tests));
4545
runners.insert("--cargo-tests", ("Run cargo tests", cargo_tests));
46+
runners.insert("--no-builtins-tests", ("Test #![no_builtins] attribute", no_builtins_tests));
4647
runners
4748
}
4849

@@ -317,6 +318,65 @@ fn maybe_run_command_in_vm(
317318
Ok(())
318319
}
319320

321+
/// Compile a source file to an object file and check if it contains a memset reference.
322+
fn object_has_memset(
323+
env: &Env,
324+
args: &TestArg,
325+
src_file: &str,
326+
obj_file_name: &str,
327+
) -> Result<bool, String> {
328+
let cargo_target_dir = Path::new(&args.config_info.cargo_target_dir);
329+
let obj_file = cargo_target_dir.join(obj_file_name);
330+
let obj_file_str = obj_file.to_str().expect("obj_file to_str");
331+
332+
let mut command = args.config_info.rustc_command_vec();
333+
command.extend_from_slice(&[
334+
&src_file,
335+
&"--emit",
336+
&"obj",
337+
&"-O",
338+
&"--target",
339+
&args.config_info.target_triple,
340+
&"-o",
341+
]);
342+
command.push(&obj_file_str);
343+
run_command_with_env(&command, None, Some(env))?;
344+
345+
let nm_output = run_command_with_env(&[&"nm", &obj_file_str], None, Some(env))?;
346+
let nm_stdout = String::from_utf8_lossy(&nm_output.stdout);
347+
348+
Ok(nm_stdout.contains("memset"))
349+
}
350+
351+
fn no_builtins_tests(env: &Env, args: &TestArg) -> Result<(), String> {
352+
// Test that the #![no_builtins] attribute prevents GCC from replacing
353+
// code patterns (like loops) with calls to builtins (like memset).
354+
// See https://github.com/rust-lang/rustc_codegen_gcc/issues/570
355+
356+
// Test 1: WITH #![no_builtins] - memset should NOT be present
357+
println!("[TEST] no_builtins attribute (with #![no_builtins])");
358+
let has_memset =
359+
object_has_memset(env, args, "tests/no_builtins/no_builtins.rs", "no_builtins_test.o")?;
360+
if has_memset {
361+
return Err("no_builtins test FAILED: Found 'memset' in object file.\n\
362+
The #![no_builtins] attribute should prevent GCC from replacing \n\
363+
code patterns with builtin calls."
364+
.to_string());
365+
}
366+
367+
// Test 2: WITHOUT #![no_builtins] - memset SHOULD be present
368+
println!("[TEST] no_builtins attribute (without #![no_builtins])");
369+
let has_memset =
370+
object_has_memset(env, args, "tests/no_builtins/with_builtins.rs", "with_builtins_test.o")?;
371+
if !has_memset {
372+
return Err("no_builtins test FAILED: 'memset' NOT found in object file.\n\
373+
Without #![no_builtins], GCC should replace the loop with memset."
374+
.to_string());
375+
}
376+
377+
Ok(())
378+
}
379+
320380
fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
321381
let cargo_target_dir = Path::new(&args.config_info.cargo_target_dir);
322382
// FIXME: create a function "display_if_not_quiet" or something along the line.
@@ -1248,6 +1308,7 @@ fn run_all(env: &Env, args: &TestArg) -> Result<(), String> {
12481308
test_libcore(env, args)?;
12491309
extended_sysroot_tests(env, args)?;
12501310
cargo_tests(env, args)?;
1311+
no_builtins_tests(env, args)?;
12511312
test_rustc(env, args)?;
12521313

12531314
Ok(())

compiler/rustc_codegen_gcc/example/mini_core.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@
1515
#![no_core]
1616
#![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)]
1717

18+
#[lang = "pointee_trait"]
19+
pub trait Pointee: PointeeSized {
20+
#[lang = "metadata_type"]
21+
// needed so that layout_of will return `TooGeneric` instead of `Unknown`
22+
// when asked for the layout of `*const T`. Which is important for making
23+
// transmutes between raw pointers (and especially pattern types of raw pointers)
24+
// work.
25+
type Metadata: Copy + Sync + Unpin + Freeze;
26+
}
27+
28+
#[lang = "dyn_metadata"]
29+
pub struct DynMetadata<Dyn: PointeeSized> {
30+
_vtable_ptr: NonNull<VTable>,
31+
_phantom: PhantomData<Dyn>,
32+
}
33+
34+
unsafe extern "C" {
35+
/// Opaque type for accessing vtables.
36+
///
37+
/// Private implementation detail of `DynMetadata::size_of` etc.
38+
/// There is conceptually not actually any Abstract Machine memory behind this pointer.
39+
type VTable;
40+
}
41+
1842
#[no_mangle]
1943
unsafe extern "C" fn _Unwind_Resume() {
2044
intrinsics::unreachable();
@@ -113,7 +137,7 @@ unsafe impl<'a, T: PointeeSized> Sync for &'a T {}
113137
unsafe impl Sync for [u8; 16] {}
114138

115139
#[lang = "freeze"]
116-
unsafe auto trait Freeze {}
140+
pub unsafe auto trait Freeze {}
117141

118142
unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {}
119143
unsafe impl<T: PointeeSized> Freeze for *const T {}
@@ -592,6 +616,13 @@ macro_rules! pattern_type {
592616
};
593617
}
594618

619+
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<pattern_type!(*const U is !null)> for pattern_type!(*const T is !null) where
620+
T: Unsize<U>
621+
{
622+
}
623+
624+
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<pattern_type!(U is !null)> for pattern_type!(T is !null) {}
625+
595626
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
596627
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
597628

@@ -604,26 +635,37 @@ impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> wh
604635
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
605636

606637
#[lang = "owned_box"]
607-
pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A);
638+
pub struct Box<T: ?Sized, A = Global>(Unique<T>, A);
608639

609-
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
640+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
610641

611642
impl<T> Box<T> {
612643
pub fn new(val: T) -> Box<T> {
613644
unsafe {
614645
let size = size_of::<T>();
615646
let ptr = libc::malloc(size);
616647
intrinsics::copy(&val as *const T as *const u8, ptr, size);
617-
Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global)
648+
Box(
649+
Unique {
650+
pointer: NonNull(intrinsics::transmute::<
651+
*mut u8,
652+
pattern_type!(*const T is !null),
653+
>(ptr)),
654+
_marker: PhantomData,
655+
},
656+
Global,
657+
)
618658
}
619659
}
620660
}
621661

622-
impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
662+
impl<T: ?Sized, A> Drop for Box<T, A> {
623663
fn drop(&mut self) {
624-
// inner value is dropped by compiler.
664+
// inner value is dropped by compiler
625665
unsafe {
626-
libc::free(self.0.pointer.0 as *mut u8);
666+
libc::free(intrinsics::transmute::<pattern_type!(*const T is !null), *const T>(
667+
self.0.pointer.0,
668+
) as *mut u8);
627669
}
628670
}
629671
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
efdd0a7290c22f5438d7c5380105d353ee3e8518
1+
6f155cc3f5a2dff33afe6cc3ed6c2e0e605ae6a3
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2026-02-14"
2+
channel = "nightly-2026-04-29"
33
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

0 commit comments

Comments
 (0)