Skip to content

Commit 02f889a

Browse files
authored
Merge pull request #820 from rust-lang/sync_from_rust_2025_12_20
Sync from rust 2025/12/20
2 parents 059950e + 1ac26a7 commit 02f889a

File tree

12 files changed

+106
-111
lines changed

12 files changed

+106
-111
lines changed

build_system/src/build.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,20 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
111111

112112
// Symlink libgccjit.so to sysroot.
113113
let lib_path = start_dir.join("sysroot").join("lib");
114+
let rustlib_target_path = lib_path
115+
.join("rustlib")
116+
.join(&config.host_triple)
117+
.join("codegen-backends")
118+
.join("lib")
119+
.join(&config.target_triple);
114120
let libgccjit_path =
115121
PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point"))
116122
.join("libgccjit.so");
117-
let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so");
123+
let libgccjit_in_sysroot_path = rustlib_target_path.join("libgccjit.so");
118124
// First remove the file to be able to create the symlink even when the file already exists.
119125
let _ = fs::remove_file(&libgccjit_in_sysroot_path);
120-
create_dir(&lib_path)?;
121-
symlink(libgccjit_path, libgccjit_in_sysroot_path)
126+
create_dir(&rustlib_target_path)?;
127+
symlink(libgccjit_path, &libgccjit_in_sysroot_path)
122128
.map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?;
123129

124130
let library_dir = start_dir.join("sysroot_src").join("library");

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2025-11-24"
2+
channel = "nightly-2025-12-20"
33
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

src/allocator.rs

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#[cfg(feature = "master")]
22
use gccjit::FnAttribute;
3-
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
3+
use gccjit::{Context, FunctionType, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
55
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
66
};
77
use rustc_middle::bug;
88
use rustc_middle::ty::TyCtxt;
9-
use rustc_session::config::OomStrategy;
109
use rustc_symbol_mangling::mangle_internal_symbol;
1110

1211
use crate::GccContext;
@@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen(
5958
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
6059
}
6160

62-
create_const_value_function(
63-
tcx,
64-
context,
65-
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
66-
i8,
67-
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
68-
);
69-
7061
create_wrapper_function(
7162
tcx,
7263
context,
@@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen(
7768
);
7869
}
7970

80-
fn create_const_value_function(
81-
tcx: TyCtxt<'_>,
82-
context: &Context<'_>,
83-
name: &str,
84-
output: Type<'_>,
85-
value: RValue<'_>,
86-
) {
87-
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
88-
89-
#[cfg(feature = "master")]
90-
{
91-
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
92-
tcx.sess.default_visibility(),
93-
)));
94-
95-
// FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using
96-
// it here will causes linking errors when using LTO.
97-
func.add_attribute(FnAttribute::Inline);
98-
}
99-
100-
if tcx.sess.must_emit_unwind_tables() {
101-
// TODO(antoyo): emit unwind tables.
102-
}
103-
104-
let block = func.new_block("entry");
105-
block.end_with_return(None, value);
106-
}
107-
10871
fn create_wrapper_function(
10972
tcx: TyCtxt<'_>,
11073
context: &Context<'_>,

src/asm.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
209209
}
210210
("r", dummy_output_type(self.cx, reg.reg_class()))
211211
} else {
212-
// `clobber_abi` can add lots of clobbers that are not supported by the target,
213-
// such as AVX-512 registers, so we just ignore unsupported registers
214-
let is_target_supported =
215-
reg.reg_class().supported_types(asm_arch, true).iter().any(
212+
let is_target_supported = match reg.reg_class() {
213+
// `clobber_abi` clobbers spe_acc on all PowerPC targets. This
214+
// register is unique to the powerpc*spe target, and the target
215+
// is not supported by gcc. Ignore it.
216+
InlineAsmRegClass::PowerPC(
217+
PowerPCInlineAsmRegClass::spe_acc,
218+
) => false,
219+
// `clobber_abi` can add lots of clobbers that are not supported by the target,
220+
// such as AVX-512 registers, so we just ignore unsupported registers
221+
x => x.supported_types(asm_arch, true).iter().any(
216222
|&(_, feature)| {
217223
if let Some(feature) = feature {
218224
self.tcx
@@ -222,7 +228,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
222228
true // Register class is unconditionally supported
223229
}
224230
},
225-
);
231+
),
232+
};
226233

227234
if is_target_supported && !clobbers.contains(&reg_name) {
228235
clobbers.push(reg_name);
@@ -710,7 +717,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
710717
PowerPCInlineAsmRegClass::cr
711718
| PowerPCInlineAsmRegClass::ctr
712719
| PowerPCInlineAsmRegClass::lr
713-
| PowerPCInlineAsmRegClass::xer,
720+
| PowerPCInlineAsmRegClass::xer
721+
| PowerPCInlineAsmRegClass::spe_acc,
714722
) => {
715723
unreachable!("clobber-only")
716724
}
@@ -793,7 +801,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
793801
PowerPCInlineAsmRegClass::cr
794802
| PowerPCInlineAsmRegClass::ctr
795803
| PowerPCInlineAsmRegClass::lr
796-
| PowerPCInlineAsmRegClass::xer,
804+
| PowerPCInlineAsmRegClass::xer
805+
| PowerPCInlineAsmRegClass::spe_acc,
797806
) => {
798807
unreachable!("clobber-only")
799808
}

src/builder.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,12 +500,12 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
500500
}
501501

502502
fn set_rvalue_location<'a, 'gcc, 'tcx>(
503-
bx: &mut Builder<'a, 'gcc, 'tcx>,
503+
_bx: &mut Builder<'a, 'gcc, 'tcx>,
504504
rvalue: RValue<'gcc>,
505505
) -> RValue<'gcc> {
506-
if bx.location.is_some() {
507-
#[cfg(feature = "master")]
508-
rvalue.set_location(bx.location.unwrap());
506+
#[cfg(feature = "master")]
507+
if let Some(location) = _bx.location {
508+
rvalue.set_location(location);
509509
}
510510
rvalue
511511
}
@@ -943,6 +943,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
943943
.get_address(self.location)
944944
}
945945

946+
fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> {
947+
todo!()
948+
}
949+
946950
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
947951
let block = self.llbb();
948952
let function = block.get_function();

src/debuginfo.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -297,29 +297,11 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
297297
let pos = span.lo();
298298
let DebugLoc { file, line, col } = self.lookup_debug_loc(pos);
299299
match file.name {
300-
rustc_span::FileName::Real(ref name) => match *name {
301-
rustc_span::RealFileName::LocalPath(ref name) => {
302-
if let Some(name) = name.to_str() {
303-
self.context.new_location(name, line as i32, col as i32)
304-
} else {
305-
Location::null()
306-
}
307-
}
308-
rustc_span::RealFileName::Remapped {
309-
ref local_path,
310-
virtual_name: ref _unused,
311-
} => {
312-
if let Some(name) = local_path.as_ref() {
313-
if let Some(name) = name.to_str() {
314-
self.context.new_location(name, line as i32, col as i32)
315-
} else {
316-
Location::null()
317-
}
318-
} else {
319-
Location::null()
320-
}
321-
}
322-
},
300+
rustc_span::FileName::Real(ref name) => self.context.new_location(
301+
name.path(rustc_span::RemapPathScopeComponents::DEBUGINFO).to_string_lossy(),
302+
line as i32,
303+
col as i32,
304+
),
323305
_ => Location::null(),
324306
}
325307
}

src/gcc_util.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ pub(crate) fn global_gcc_features(sess: &Session) -> Vec<String> {
3333
// should be taken in cases like these.
3434
let mut features = vec![];
3535

36-
// Features implied by an implicit or explicit `--target`.
37-
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
38-
39-
// -Ctarget-features
40-
target_features::flag_to_backend_features(sess, |feature, enable| {
36+
let mut extend_backend_features = |feature: &str, enable: bool| {
4137
// We run through `to_gcc_features` when
4238
// passing requests down to GCC. This means that all in-language
4339
// features also work on the command line instead of having two
@@ -48,7 +44,13 @@ pub(crate) fn global_gcc_features(sess: &Session) -> Vec<String> {
4844
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
4945
.map(|feature| if !enable { format!("-{}", feature) } else { feature.to_string() }),
5046
);
51-
});
47+
};
48+
49+
// Features implied by an implicit or explicit `--target`.
50+
target_features::target_spec_to_backend_features(sess, &mut extend_backend_features);
51+
52+
// -Ctarget-features
53+
target_features::flag_to_backend_features(sess, extend_backend_features);
5254

5355
gcc_features_by_flags(sess, &mut features);
5456

@@ -66,6 +68,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
6668
(&Arch::X86 | &Arch::X86_64, "rdrand") => smallvec!["rdrnd"],
6769
(&Arch::X86 | &Arch::X86_64, "bmi1") => smallvec!["bmi"],
6870
(&Arch::X86 | &Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"],
71+
(&Arch::X86 | &Arch::X86_64, "lahfsahf") => smallvec!["sahf"],
6972
(&Arch::X86 | &Arch::X86_64, "avx512vaes") => smallvec!["vaes"],
7073
(&Arch::X86 | &Arch::X86_64, "avx512gfni") => smallvec!["gfni"],
7174
(&Arch::X86 | &Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"],

src/intrinsic/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
424424
}
425425
sym::bitreverse => self.bit_reverse(width, args[0].immediate()),
426426
sym::rotate_left | sym::rotate_right => {
427-
// TODO(antoyo): implement using algorithm from:
427+
// Using optimized branchless algorithm from:
428428
// https://blog.regehr.org/archives/1063
429-
// for other platforms.
429+
// This implementation uses the pattern (x<<n) | (x>>(-n&(width-1)))
430+
// which generates efficient code for other platforms.
430431
let is_left = name == sym::rotate_left;
431432
let val = args[0].immediate();
432433
let raw_shift = args[1].immediate();
@@ -467,7 +468,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
467468
let layout = self.layout_of(tp_ty).layout;
468469
let _use_integer_compare = match layout.backend_repr() {
469470
Scalar(_) | ScalarPair(_, _) => true,
470-
SimdVector { .. } => false,
471+
SimdVector { .. } | ScalableVector { .. } => false,
471472
Memory { .. } => {
472473
// For rusty ABIs, small aggregates are actually passed
473474
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

src/intrinsic/simd.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -774,24 +774,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
774774
return Err(());
775775
}};
776776
}
777-
let (elem_ty_str, elem_ty, cast_type) = if let ty::Float(ref f) = *in_elem.kind() {
778-
let elem_ty = bx.cx.type_float_from_ty(*f);
779-
match f.bit_width() {
780-
16 => ("", elem_ty, Some(bx.cx.double_type)),
781-
32 => ("f", elem_ty, None),
782-
64 => ("", elem_ty, None),
783-
_ => {
784-
return_error!(InvalidMonomorphization::FloatingPointVector {
785-
span,
786-
name,
787-
f_ty: *f,
788-
in_ty
789-
});
790-
}
791-
}
792-
} else {
777+
let ty::Float(ref f) = *in_elem.kind() else {
793778
return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty });
794779
};
780+
let elem_ty = bx.cx.type_float_from_ty(*f);
781+
let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() {
782+
16 => ("", elem_ty, Some(bx.cx.double_type)),
783+
32 => ("f", elem_ty, None),
784+
64 => ("", elem_ty, None),
785+
_ => {
786+
return_error!(InvalidMonomorphization::FloatingPointVector {
787+
span,
788+
name,
789+
f_ty: *f,
790+
in_ty
791+
});
792+
}
793+
};
795794

796795
let vec_ty = bx.cx.type_vector(elem_ty, in_len);
797796

src/lib.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,18 +181,12 @@ pub struct GccCodegenBackend {
181181

182182
static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false);
183183

184-
fn libgccjit_path(sysroot_path: &Path) -> PathBuf {
185-
let sysroot_lib_dir = sysroot_path.join("lib");
186-
sysroot_lib_dir.join("libgccjit.so")
187-
}
188-
189-
fn load_libgccjit_if_needed(sysroot_path: &Path) {
184+
fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {
190185
if gccjit::is_loaded() {
191186
// Do not load a libgccjit second time.
192187
return;
193188
}
194189

195-
let libgccjit_target_lib_file = libgccjit_path(sysroot_path);
196190
let path = libgccjit_target_lib_file.to_str().expect("libgccjit path");
197191

198192
let string = CString::new(path).expect("string to libgccjit path");
@@ -212,17 +206,38 @@ impl CodegenBackend for GccCodegenBackend {
212206
}
213207

214208
fn init(&self, sess: &Session) {
209+
fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf {
210+
let rustlib_path =
211+
rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target);
212+
sysroot_path
213+
.join(rustlib_path)
214+
.join("codegen-backends")
215+
.join("lib")
216+
.join(sess.target.llvm_target.as_ref())
217+
.join("libgccjit.so")
218+
}
219+
215220
// We use all_paths() instead of only path() in case the path specified by --sysroot is
216221
// invalid.
217222
// This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null.
218223
for path in sess.opts.sysroot.all_paths() {
219-
let libgccjit_target_lib_file = libgccjit_path(path);
220-
if let Ok(true) = fs::exists(libgccjit_target_lib_file) {
221-
load_libgccjit_if_needed(path);
224+
let libgccjit_target_lib_file = file_path(path, sess);
225+
if let Ok(true) = fs::exists(&libgccjit_target_lib_file) {
226+
load_libgccjit_if_needed(&libgccjit_target_lib_file);
222227
break;
223228
}
224229
}
225230

231+
if !gccjit::is_loaded() {
232+
let mut paths = vec![];
233+
for path in sess.opts.sysroot.all_paths() {
234+
let libgccjit_target_lib_file = file_path(path, sess);
235+
paths.push(libgccjit_target_lib_file);
236+
}
237+
238+
panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths);
239+
}
240+
226241
#[cfg(feature = "master")]
227242
{
228243
let target_cpu = target_cpu(sess);

0 commit comments

Comments
 (0)