Merge pull request #851 from rust-lang/sync_from_rust_2026_02_12

Sync from rust 2026/02/12
This commit is contained in:
antoyo 2026-02-13 12:13:29 -05:00 committed by GitHub
commit 1920fb1d35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 72 additions and 70 deletions

View file

@ -83,7 +83,7 @@ jobs:
run: |
./y.sh prepare --only-libcore --cross
./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
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
./y.sh clean all
- name: Build

View file

@ -141,6 +141,10 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
}
let mut args: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"build", &"--target", &config.target];
if config.target.ends_with(".json") {
args.push(&"-Zjson-target-spec");
}
for feature in &config.features {
args.push(&"--features");
args.push(feature);

View file

@ -1,8 +0,0 @@
codegen_gcc_unwinding_inline_asm =
GCC backend does not support unwinding from inline asm
codegen_gcc_copy_bitcode = failed to copy bitcode to object file: {$err}
codegen_gcc_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$gcc_err})
codegen_gcc_explicit_tail_calls_unsupported = explicit tail calls with the 'become' keyword are not implemented in the GCC backend

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2026-01-30"
channel = "nightly-2026-02-13"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View file

@ -50,7 +50,7 @@ struct LtoData {
}
fn prepare_lto(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
each_linked_rlib_for_lto: &[PathBuf],
dcx: DiagCtxtHandle<'_>,
) -> LtoData {
@ -111,7 +111,7 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> {
/// Performs fat LTO by merging all modules into a single one and returning it
/// for further optimization.
pub(crate) fn run_fat(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
shared_emitter: &SharedEmitter,
each_linked_rlib_for_lto: &[PathBuf],
modules: Vec<FatLtoInput<GccCodegenBackend>>,
@ -132,7 +132,7 @@ pub(crate) fn run_fat(
}
fn fat_lto(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
_dcx: DiagCtxtHandle<'_>,
modules: Vec<FatLtoInput<GccCodegenBackend>>,
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
@ -283,7 +283,7 @@ impl ModuleBufferMethods for ModuleBuffer {
/// lists, one of the modules that need optimization and another for modules that
/// can simply be copied over from the incr. comp. cache.
pub(crate) fn run_thin(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
dcx: DiagCtxtHandle<'_>,
each_linked_rlib_for_lto: &[PathBuf],
modules: Vec<(String, ThinBuffer)>,
@ -345,7 +345,7 @@ pub(crate) fn prepare_thin(module: ModuleCodegen<GccContext>) -> (String, ThinBu
/// all of the `LtoModuleCodegen` units returned below and destroyed once
/// they all go out of scope.
fn thin_lto(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
_dcx: DiagCtxtHandle<'_>,
modules: Vec<(String, ThinBuffer)>,
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
@ -520,11 +520,9 @@ fn thin_lto(
pub fn optimize_thin_module(
thin_module: ThinModule<GccCodegenBackend>,
_cgcx: &CodegenContext<GccCodegenBackend>,
_cgcx: &CodegenContext,
) -> ModuleCodegen<GccContext> {
//let module_name = &thin_module.shared.module_names[thin_module.idx];
/*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/
// Right now the implementation we've got only works over serialized
// modules, so we create a fresh new LLVM context and parse the module

View file

@ -14,10 +14,10 @@ use rustc_target::spec::SplitDebuginfo;
use crate::base::add_pic_option;
use crate::errors::CopyBitcode;
use crate::{GccCodegenBackend, GccContext, LtoMode};
use crate::{GccContext, LtoMode};
pub(crate) fn codegen(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
shared_emitter: &SharedEmitter,
module: ModuleCodegen<GccContext>,
config: &ModuleConfig,
@ -227,7 +227,7 @@ pub(crate) fn codegen(
}
pub(crate) fn save_temp_bitcode(
cgcx: &CodegenContext<GccCodegenBackend>,
cgcx: &CodegenContext,
_module: &ModuleCodegen<GccContext>,
_name: &str,
) {

View file

@ -1873,32 +1873,31 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
let int_max = |signed: bool, int_width: u64| -> u128 {
fn int_max(signed: bool, int_width: u64) -> u128 {
let shift_amount = 128 - int_width;
if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount }
};
let int_min = |signed: bool, int_width: u64| -> i128 {
}
fn int_min(signed: bool, int_width: u64) -> i128 {
if signed { i128::MIN >> (128 - int_width) } else { 0 }
};
}
let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) {
// TODO: rewrite using a generic function with <F: Float>.
let compute_clamp_bounds_half = |signed: bool, int_width: u64| -> (u128, u128) {
let rounded_min =
ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero);
assert_eq!(rounded_min.status, Status::OK);
ieee::Half::from_i128_r(int_min(signed, int_width), Round::TowardZero);
//assert_eq!(rounded_min.status, Status::OK);
let rounded_max =
ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero);
ieee::Half::from_u128_r(int_max(signed, int_width), Round::TowardZero);
assert!(rounded_max.value.is_finite());
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
};
let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) {
let rounded_min =
ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero);
fn compute_clamp_bounds<F: Float>(signed: bool, int_width: u64) -> (u128, u128) {
let rounded_min = F::from_i128_r(int_min(signed, int_width), Round::TowardZero);
assert_eq!(rounded_min.status, Status::OK);
let rounded_max =
ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero);
let rounded_max = F::from_u128_r(int_max(signed, int_width), Round::TowardZero);
assert!(rounded_max.value.is_finite());
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
};
}
// To implement saturation, we perform the following steps:
//
// 1. Cast val to an integer with fpto[su]i. This may result in undef.
@ -1928,15 +1927,19 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let float_bits_to_llval = |bx: &mut Self, bits| {
let bits_llval = match float_width {
16 => bx.cx().const_u16(bits as u16),
32 => bx.cx().const_u32(bits as u32),
64 => bx.cx().const_u64(bits as u64),
128 => bx.cx().const_u128(bits),
n => bug!("unsupported float width {}", n),
};
bx.bitcast(bits_llval, float_ty)
};
let (f_min, f_max) = match float_width {
32 => compute_clamp_bounds_single(signed, int_width),
64 => compute_clamp_bounds_double(signed, int_width),
16 => compute_clamp_bounds_half(signed, int_width),
32 => compute_clamp_bounds::<ieee::Single>(signed, int_width),
64 => compute_clamp_bounds::<ieee::Double>(signed, int_width),
128 => compute_clamp_bounds::<ieee::Quad>(signed, int_width),
n => bug!("unsupported float width {}", n),
};
let f_min = float_bits_to_llval(self, f_min);

View file

@ -20,6 +20,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
bytes_in_context(self, bytes)
}
pub fn const_u16(&self, i: u16) -> RValue<'gcc> {
self.const_uint(self.type_u16(), i as u64)
}
fn global_string(&self, string: &str) -> LValue<'gcc> {
// TODO(antoyo): handle non-null-terminated strings.
let string = self.context.new_string_literal(string);

View file

@ -2,24 +2,24 @@ use rustc_macros::Diagnostic;
use rustc_span::Span;
#[derive(Diagnostic)]
#[diag(codegen_gcc_unwinding_inline_asm)]
#[diag("GCC backend does not support unwinding from inline asm")]
pub(crate) struct UnwindingInlineAsm {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc_copy_bitcode)]
#[diag("failed to copy bitcode to object file: {$err}")]
pub(crate) struct CopyBitcode {
pub err: std::io::Error,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc_lto_bitcode_from_rlib)]
#[diag("failed to get bitcode from object file for LTO ({$gcc_err})")]
pub(crate) struct LtoBitcodeFromRlib {
pub gcc_err: String,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc_explicit_tail_calls_unsupported)]
#[diag("explicit tail calls with the 'become' keyword are not implemented in the GCC backend")]
pub(crate) struct ExplicitTailCallsUnsupported;

View file

@ -942,7 +942,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
fn float_to_int_cast(
&self,
signed: bool,
value: RValue<'gcc>,
mut value: RValue<'gcc>,
dest_typ: Type<'gcc>,
) -> RValue<'gcc> {
let value_type = value.get_type();
@ -951,16 +951,22 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
debug_assert!(dest_typ.dyncast_array().is_some());
let (dest_type, param_type) = match self.type_kind(value_type) {
TypeKind::Half => (Some(self.float_type), self.float_type),
_ => (None, value_type),
};
let name_suffix = match self.type_kind(value_type) {
// cSpell:disable
TypeKind::Float => "sfti",
// Since we will cast Half to a float, we use sfti for both.
TypeKind::Half | TypeKind::Float => "sfti",
TypeKind::Double => "dfti",
TypeKind::FP128 => "tfti",
// cSpell:enable
kind => panic!("cannot cast a {:?} to non-native integer", kind),
};
let sign = if signed { "" } else { "uns" };
let func_name = format!("__fix{}{}", sign, name_suffix);
let param = self.context.new_parameter(None, value_type, "n");
let param = self.context.new_parameter(None, param_type, "n");
let func = self.context.new_function(
None,
FunctionType::Extern,
@ -969,6 +975,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
func_name,
false,
);
if let Some(dest_type) = dest_type {
value = self.context.new_cast(None, value, dest_type);
}
self.context.new_call(None, func, &[value])
}

View file

@ -22,13 +22,18 @@ use rustc_codegen_ssa::traits::{
ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods,
};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::bug;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
#[cfg(feature = "master")]
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, PassMode};
use crate::abi::{FnAbiGccExt, GccType};
#[cfg(feature = "master")]
use crate::abi::FnAbiGccExt;
use crate::abi::GccType;
use crate::builder::Builder;
use crate::common::{SignType, TypeReflection};
use crate::context::CodegenCx;
@ -584,8 +589,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
*func
} else {
self.linkage.set(FunctionType::Extern);
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
let fn_ty = fn_abi.gcc_type(self);
let func = match sym {
"llvm.fma.f16" => {
@ -598,13 +601,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
self.intrinsics.borrow_mut().insert(sym.to_string(), func);
self.on_stack_function_params
.borrow_mut()
.insert(func, fn_ty.on_stack_param_indices);
#[cfg(feature = "master")]
for fn_attr in fn_ty.fn_attributes {
func.add_attribute(fn_attr);
}
self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default());
crate::attributes::from_fn_attrs(self, func, instance);

View file

@ -27,7 +27,6 @@ extern crate rustc_ast;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_fluent_macro;
extern crate rustc_fs_util;
extern crate rustc_hir;
extern crate rustc_index;
@ -105,8 +104,6 @@ use tempfile::TempDir;
use crate::back::lto::ModuleBuffer;
use crate::gcc_util::{target_cpu, to_gcc_features};
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub struct PrintOnPanic<F: Fn() -> String>(pub F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
@ -197,10 +194,6 @@ fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {
}
impl CodegenBackend for GccCodegenBackend {
fn locale_resource(&self) -> &'static str {
crate::DEFAULT_LOCALE_RESOURCE
}
fn name(&self) -> &'static str {
"gcc"
}
@ -383,7 +376,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
_features: &[String],
) -> TargetMachineFactoryFn<Self> {
// TODO(antoyo): set opt level.
Arc::new(|_| Ok(()))
Arc::new(|_, _| ())
}
}
@ -430,14 +423,14 @@ unsafe impl Sync for SyncContext {}
impl WriteBackendMethods for GccCodegenBackend {
type Module = GccContext;
type TargetMachine = ();
type TargetMachineError = ();
type ModuleBuffer = ModuleBuffer;
type ThinData = ThinData;
type ThinBuffer = ThinBuffer;
fn run_and_optimize_fat_lto(
cgcx: &CodegenContext<Self>,
cgcx: &CodegenContext,
shared_emitter: &SharedEmitter,
_tm_factory: TargetMachineFactoryFn<Self>,
// FIXME(bjorn3): Limit LTO exports to these symbols
_exported_symbols_for_lto: &[String],
each_linked_rlib_for_lto: &[PathBuf],
@ -447,7 +440,7 @@ impl WriteBackendMethods for GccCodegenBackend {
}
fn run_thin_lto(
cgcx: &CodegenContext<Self>,
cgcx: &CodegenContext,
dcx: DiagCtxtHandle<'_>,
// FIXME(bjorn3): Limit LTO exports to these symbols
_exported_symbols_for_lto: &[String],
@ -467,7 +460,7 @@ impl WriteBackendMethods for GccCodegenBackend {
}
fn optimize(
_cgcx: &CodegenContext<Self>,
_cgcx: &CodegenContext,
_shared_emitter: &SharedEmitter,
module: &mut ModuleCodegen<Self::Module>,
config: &ModuleConfig,
@ -476,15 +469,16 @@ impl WriteBackendMethods for GccCodegenBackend {
}
fn optimize_thin(
cgcx: &CodegenContext<Self>,
cgcx: &CodegenContext,
_shared_emitter: &SharedEmitter,
_tm_factory: TargetMachineFactoryFn<Self>,
thin: ThinModule<Self>,
) -> ModuleCodegen<Self::Module> {
back::lto::optimize_thin_module(thin, cgcx)
}
fn codegen(
cgcx: &CodegenContext<Self>,
cgcx: &CodegenContext,
shared_emitter: &SharedEmitter,
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,

View file

@ -11,4 +11,4 @@ tests/run-make/foreign-exceptions/
tests/run-make/glibc-staticlib-args/
tests/run-make/lto-smoke-c/
tests/run-make/return-non-c-like-enum/
tests/run-make/short-ice

View file

@ -98,3 +98,4 @@ tests/ui/eii/linking/same-symbol.rs
tests/ui/eii/privacy1.rs
tests/ui/eii/default/call_impl.rs
tests/ui/c-variadic/copy.rs
tests/ui/asm/x86_64/global_asm_escape.rs