Merge pull request #820 from rust-lang/sync_from_rust_2025_12_20

Sync from rust 2025/12/20
This commit is contained in:
antoyo 2025-12-20 18:08:23 -05:00 committed by GitHub
commit 02f889aec5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 106 additions and 111 deletions

View file

@ -111,14 +111,20 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
// Symlink libgccjit.so to sysroot.
let lib_path = start_dir.join("sysroot").join("lib");
let rustlib_target_path = lib_path
.join("rustlib")
.join(&config.host_triple)
.join("codegen-backends")
.join("lib")
.join(&config.target_triple);
let libgccjit_path =
PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point"))
.join("libgccjit.so");
let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so");
let libgccjit_in_sysroot_path = rustlib_target_path.join("libgccjit.so");
// First remove the file to be able to create the symlink even when the file already exists.
let _ = fs::remove_file(&libgccjit_in_sysroot_path);
create_dir(&lib_path)?;
symlink(libgccjit_path, libgccjit_in_sysroot_path)
create_dir(&rustlib_target_path)?;
symlink(libgccjit_path, &libgccjit_in_sysroot_path)
.map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?;
let library_dir = start_dir.join("sysroot_src").join("library");

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-11-24"
channel = "nightly-2025-12-20"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View file

@ -1,12 +1,11 @@
#[cfg(feature = "master")]
use gccjit::FnAttribute;
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
use gccjit::{Context, FunctionType, ToRValue, Type};
use rustc_ast::expand::allocator::{
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::OomStrategy;
use rustc_symbol_mangling::mangle_internal_symbol;
use crate::GccContext;
@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen(
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
}
create_const_value_function(
tcx,
context,
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
i8,
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
);
create_wrapper_function(
tcx,
context,
@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen(
);
}
fn create_const_value_function(
tcx: TyCtxt<'_>,
context: &Context<'_>,
name: &str,
output: Type<'_>,
value: RValue<'_>,
) {
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
#[cfg(feature = "master")]
{
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
tcx.sess.default_visibility(),
)));
// FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using
// it here will causes linking errors when using LTO.
func.add_attribute(FnAttribute::Inline);
}
if tcx.sess.must_emit_unwind_tables() {
// TODO(antoyo): emit unwind tables.
}
let block = func.new_block("entry");
block.end_with_return(None, value);
}
fn create_wrapper_function(
tcx: TyCtxt<'_>,
context: &Context<'_>,

View file

@ -209,10 +209,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
}
("r", dummy_output_type(self.cx, reg.reg_class()))
} else {
// `clobber_abi` can add lots of clobbers that are not supported by the target,
// such as AVX-512 registers, so we just ignore unsupported registers
let is_target_supported =
reg.reg_class().supported_types(asm_arch, true).iter().any(
let is_target_supported = match reg.reg_class() {
// `clobber_abi` clobbers spe_acc on all PowerPC targets. This
// register is unique to the powerpc*spe target, and the target
// is not supported by gcc. Ignore it.
InlineAsmRegClass::PowerPC(
PowerPCInlineAsmRegClass::spe_acc,
) => false,
// `clobber_abi` can add lots of clobbers that are not supported by the target,
// such as AVX-512 registers, so we just ignore unsupported registers
x => x.supported_types(asm_arch, true).iter().any(
|&(_, feature)| {
if let Some(feature) = feature {
self.tcx
@ -222,7 +228,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
true // Register class is unconditionally supported
}
},
);
),
};
if is_target_supported && !clobbers.contains(&reg_name) {
clobbers.push(reg_name);
@ -710,7 +717,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}
@ -793,7 +801,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}

View file

@ -500,12 +500,12 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
}
fn set_rvalue_location<'a, 'gcc, 'tcx>(
bx: &mut Builder<'a, 'gcc, 'tcx>,
_bx: &mut Builder<'a, 'gcc, 'tcx>,
rvalue: RValue<'gcc>,
) -> RValue<'gcc> {
if bx.location.is_some() {
#[cfg(feature = "master")]
rvalue.set_location(bx.location.unwrap());
#[cfg(feature = "master")]
if let Some(location) = _bx.location {
rvalue.set_location(location);
}
rvalue
}
@ -943,6 +943,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
.get_address(self.location)
}
fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> {
todo!()
}
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
let block = self.llbb();
let function = block.get_function();

View file

@ -297,29 +297,11 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
let pos = span.lo();
let DebugLoc { file, line, col } = self.lookup_debug_loc(pos);
match file.name {
rustc_span::FileName::Real(ref name) => match *name {
rustc_span::RealFileName::LocalPath(ref name) => {
if let Some(name) = name.to_str() {
self.context.new_location(name, line as i32, col as i32)
} else {
Location::null()
}
}
rustc_span::RealFileName::Remapped {
ref local_path,
virtual_name: ref _unused,
} => {
if let Some(name) = local_path.as_ref() {
if let Some(name) = name.to_str() {
self.context.new_location(name, line as i32, col as i32)
} else {
Location::null()
}
} else {
Location::null()
}
}
},
rustc_span::FileName::Real(ref name) => self.context.new_location(
name.path(rustc_span::RemapPathScopeComponents::DEBUGINFO).to_string_lossy(),
line as i32,
col as i32,
),
_ => Location::null(),
}
}

View file

@ -33,11 +33,7 @@ pub(crate) fn global_gcc_features(sess: &Session) -> Vec<String> {
// should be taken in cases like these.
let mut features = vec![];
// Features implied by an implicit or explicit `--target`.
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
// -Ctarget-features
target_features::flag_to_backend_features(sess, |feature, enable| {
let mut extend_backend_features = |feature: &str, enable: bool| {
// We run through `to_gcc_features` when
// passing requests down to GCC. This means that all in-language
// 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> {
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
.map(|feature| if !enable { format!("-{}", feature) } else { feature.to_string() }),
);
});
};
// Features implied by an implicit or explicit `--target`.
target_features::target_spec_to_backend_features(sess, &mut extend_backend_features);
// -Ctarget-features
target_features::flag_to_backend_features(sess, extend_backend_features);
gcc_features_by_flags(sess, &mut features);
@ -66,6 +68,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
(&Arch::X86 | &Arch::X86_64, "rdrand") => smallvec!["rdrnd"],
(&Arch::X86 | &Arch::X86_64, "bmi1") => smallvec!["bmi"],
(&Arch::X86 | &Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"],
(&Arch::X86 | &Arch::X86_64, "lahfsahf") => smallvec!["sahf"],
(&Arch::X86 | &Arch::X86_64, "avx512vaes") => smallvec!["vaes"],
(&Arch::X86 | &Arch::X86_64, "avx512gfni") => smallvec!["gfni"],
(&Arch::X86 | &Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"],

View file

@ -424,9 +424,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
}
sym::bitreverse => self.bit_reverse(width, args[0].immediate()),
sym::rotate_left | sym::rotate_right => {
// TODO(antoyo): implement using algorithm from:
// Using optimized branchless algorithm from:
// https://blog.regehr.org/archives/1063
// for other platforms.
// This implementation uses the pattern (x<<n) | (x>>(-n&(width-1)))
// which generates efficient code for other platforms.
let is_left = name == sym::rotate_left;
let val = args[0].immediate();
let raw_shift = args[1].immediate();
@ -467,7 +468,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
let layout = self.layout_of(tp_ty).layout;
let _use_integer_compare = match layout.backend_repr() {
Scalar(_) | ScalarPair(_, _) => true,
SimdVector { .. } => false,
SimdVector { .. } | ScalableVector { .. } => false,
Memory { .. } => {
// For rusty ABIs, small aggregates are actually passed
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

View file

@ -774,24 +774,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
return Err(());
}};
}
let (elem_ty_str, elem_ty, cast_type) = if let ty::Float(ref f) = *in_elem.kind() {
let elem_ty = bx.cx.type_float_from_ty(*f);
match f.bit_width() {
16 => ("", elem_ty, Some(bx.cx.double_type)),
32 => ("f", elem_ty, None),
64 => ("", elem_ty, None),
_ => {
return_error!(InvalidMonomorphization::FloatingPointVector {
span,
name,
f_ty: *f,
in_ty
});
}
}
} else {
let ty::Float(ref f) = *in_elem.kind() else {
return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty });
};
let elem_ty = bx.cx.type_float_from_ty(*f);
let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() {
16 => ("", elem_ty, Some(bx.cx.double_type)),
32 => ("f", elem_ty, None),
64 => ("", elem_ty, None),
_ => {
return_error!(InvalidMonomorphization::FloatingPointVector {
span,
name,
f_ty: *f,
in_ty
});
}
};
let vec_ty = bx.cx.type_vector(elem_ty, in_len);

View file

@ -181,18 +181,12 @@ pub struct GccCodegenBackend {
static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false);
fn libgccjit_path(sysroot_path: &Path) -> PathBuf {
let sysroot_lib_dir = sysroot_path.join("lib");
sysroot_lib_dir.join("libgccjit.so")
}
fn load_libgccjit_if_needed(sysroot_path: &Path) {
fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {
if gccjit::is_loaded() {
// Do not load a libgccjit second time.
return;
}
let libgccjit_target_lib_file = libgccjit_path(sysroot_path);
let path = libgccjit_target_lib_file.to_str().expect("libgccjit path");
let string = CString::new(path).expect("string to libgccjit path");
@ -212,17 +206,38 @@ impl CodegenBackend for GccCodegenBackend {
}
fn init(&self, sess: &Session) {
fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf {
let rustlib_path =
rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target);
sysroot_path
.join(rustlib_path)
.join("codegen-backends")
.join("lib")
.join(sess.target.llvm_target.as_ref())
.join("libgccjit.so")
}
// We use all_paths() instead of only path() in case the path specified by --sysroot is
// invalid.
// This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null.
for path in sess.opts.sysroot.all_paths() {
let libgccjit_target_lib_file = libgccjit_path(path);
if let Ok(true) = fs::exists(libgccjit_target_lib_file) {
load_libgccjit_if_needed(path);
let libgccjit_target_lib_file = file_path(path, sess);
if let Ok(true) = fs::exists(&libgccjit_target_lib_file) {
load_libgccjit_if_needed(&libgccjit_target_lib_file);
break;
}
}
if !gccjit::is_loaded() {
let mut paths = vec![];
for path in sess.opts.sysroot.all_paths() {
let libgccjit_target_lib_file = file_path(path, sess);
paths.push(libgccjit_target_lib_file);
}
panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths);
}
#[cfg(feature = "master")]
{
let target_cpu = target_cpu(sess);

View file

@ -85,6 +85,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(
);
}
BackendRepr::Memory { .. } => {}
BackendRepr::ScalableVector { .. } => todo!(),
}
let name = match *layout.ty.kind() {
@ -179,6 +180,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
fn is_gcc_immediate(&self) -> bool {
match self.backend_repr {
BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true,
// FIXME(rustc_scalable_vector): Not yet implemented in rustc_codegen_gcc.
BackendRepr::ScalableVector { .. } => todo!(),
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
}
}
@ -188,6 +191,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
BackendRepr::ScalarPair(..) => true,
BackendRepr::Scalar(_)
| BackendRepr::SimdVector { .. }
| BackendRepr::ScalableVector { .. }
| BackendRepr::Memory { .. } => false,
}
}

View file

@ -88,3 +88,12 @@ tests/ui/test-attrs/test-panic-while-printing.rs
tests/ui/thir-print/offset_of.rs
tests/ui/iterators/rangefrom-overflow-debug.rs
tests/ui/iterators/rangefrom-overflow-overflow-checks.rs
tests/ui/iterators/iter-filter-count-debug-check.rs
tests/ui/eii/codegen_single_crate.rs
tests/ui/eii/codegen_cross_crate.rs
tests/ui/eii/default/local_crate.rs
tests/ui/eii/multiple_impls.rs
tests/ui/eii/default/call_default.rs
tests/ui/eii/same-symbol.rs
tests/ui/eii/privacy1.rs
tests/ui/eii/default/call_impl.rs