Merge pull request #851 from rust-lang/sync_from_rust_2026_02_12
Sync from rust 2026/02/12
This commit is contained in:
commit
1920fb1d35
14 changed files with 72 additions and 70 deletions
2
.github/workflows/m68k.yml
vendored
2
.github/workflows/m68k.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2026-01-30"
|
||||
channel = "nightly-2026-02-13"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
15
src/int.rs
15
src/int.rs
|
|
@ -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])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
22
src/lib.rs
22
src/lib.rs
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue