diff --git a/Cargo.lock b/Cargo.lock index 6c3dc4b82f9..c174628d0d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "object" -version = "0.37.1" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index abfa47a05bd..02be6d56c23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -object = { version = "0.37.0", default-features = false, features = ["std", "read"] } +object = { version = "0.39.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" gccjit = { version = "6.1.0", features = ["dlopen"] } #gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] } diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 2e9a67f9a8c..dc351960667 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -533,6 +533,16 @@ fn get_llvm_filecheck(env: &Env) -> Result { } } +fn which(env: &Env, program: &str) -> String { + match run_command_with_env(&[&"bash", &"-c", &format!("which {}", program)], None, Some(env)) { + Ok(cmd) => String::from_utf8_lossy(&cmd.stdout).trim().to_string(), + Err(_) => { + eprintln!("Failed to retrieve the path of {}, ignoring...", program); + String::new() + } + } +} + fn setup_rustc(env: &mut Env, args: &TestArg) -> Result { let toolchain = format!( "+{channel}-{host}", @@ -585,6 +595,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result { String::new() } }; + let llvm_config = which(env, "llvm-config"); let file_path = rust_dir_path.join("config.toml"); std::fs::write( &file_path, @@ -602,6 +613,7 @@ local-rebuild = true rustc = "{rustc}" [target.x86_64-unknown-linux-gnu] +llvm-config = "{llvm_config}" llvm-filecheck = "{llvm_filecheck}" [llvm] @@ -836,6 +848,8 @@ fn test_libcore_doctests(env: &Env, args: &TestArg) -> Result<(), String> { // `core::io::ErrorKind`'s `Display` impl declares `#![feature(core_io)]` upstream: without // it, that doctest fails to compile with `E0658` on any backend. &"-Zforce-unstable-if-unmarked", + // FIXME: one test cannot compile due to an upstream bug in the new trait solver. + &"-Znext-solver=coherence", ]; for flag in &rustflags { command.push(flag); @@ -1053,10 +1067,7 @@ fn contains_ui_error_patterns(file_path: &Path, keep_lto_tests: bool) -> Result< eprintln!("nothing found for {file_path:?}"); } // The files in this directory contain errors. - if file_path.contains("/error-emitter/") { - return Ok(true); - } - Ok(false) + Ok(file_path.contains("/error-emitter/")) } // # Parameters diff --git a/rust-toolchain b/rust-toolchain index d777360fd42..eaef2a3f848 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2026-08-04" +channel = "nightly-2026-09-04" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/abi.rs b/src/abi.rs index 240bba0e752..4ed30f9ba11 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -179,11 +179,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { )); continue; } - PassMode::Cast { ref cast, pad_i32 } => { - // add padding - if pad_i32 { - argument_tys.push(Reg::i32().gcc_type(cx)); - } + PassMode::Cast { ref cast, pad_i32_count } => { + // Add padding. + argument_tys.extend(std::iter::repeat_n( + Reg::i32().gcc_type(cx), + usize::from(pad_i32_count), + )); + let ty = cast.gcc_type(cx); apply_attrs(ty, &cast.attrs, argument_tys.len()) } diff --git a/src/asm.rs b/src/asm.rs index 8c5415172ce..6b5dd3d3fe6 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -749,7 +749,7 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r", InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg) => "f", InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for // "define_constraint". @@ -806,6 +806,9 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { unreachable!("clobber-only") } InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::dreg) => "e", + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::qreg) => "e", InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), InlineAsmRegClass::Err => unreachable!(), } @@ -859,6 +862,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl } InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::wreg) => cx.type_vector(cx.type_i32(), 4), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(), @@ -912,6 +916,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl unreachable!("clobber-only") } InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::freg) => cx.type_f32(), + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::dreg) => cx.type_f64(), + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::qreg) => cx.type_f128(), InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), @@ -938,6 +945,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, line_spans: &[Span], + _extra_rust_target_features: &[String], ) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); @@ -1100,7 +1108,9 @@ fn modifier_to_gcc( modifier } } - InlineAsmRegClass::Mips(_) => None, + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => None, + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => modifier, + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::wreg) => Some('w'), InlineAsmRegClass::Nvptx(_) => None, InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => { if modifier.is_none() { diff --git a/src/builder.rs b/src/builder.rs index 8ec72bb6f3a..dd7fc3ddc4e 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -109,8 +109,13 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { AtomicOrdering::AcqRel | AtomicOrdering::Release => AtomicOrdering::Acquire, _ => order, }; - let previous_value = - self.atomic_load(dst.get_type(), dst, load_ordering, Size::from_bytes(size)); + let previous_value = self.atomic_load( + dst.get_type(), + dst, + load_ordering, + /* volatile */ false, + Size::from_bytes(size), + ); let previous_var = func.new_local(self.location, previous_value.get_type(), "previous_value"); let return_value = self.new_temp(func, self.location, previous_value.get_type()); @@ -1087,6 +1092,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { _ty: Type<'gcc>, ptr: RValue<'gcc>, order: AtomicOrdering, + _volatile: bool, // FIXME we are always making the load volatile size: Size, ) -> RValue<'gcc> { // FIXME(antoyo): use ty. @@ -1256,6 +1262,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { value: RValue<'gcc>, ptr: RValue<'gcc>, order: AtomicOrdering, + _volatile: bool, // FIXME we are always making the store volatile size: Size, ) { // FIXME(antoyo): handle alignment. diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 2bbbe5faf0e..b6015a74d9e 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -63,22 +63,8 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::sqrtf64 => "sqrt", sym::powif32 => "__builtin_powif", sym::powif64 => "__builtin_powi", - sym::sinf32 => "sinf", - sym::sinf64 => "sin", - sym::cosf32 => "cosf", - sym::cosf64 => "cos", sym::powf32 => "powf", sym::powf64 => "pow", - sym::expf32 => "expf", - sym::expf64 => "exp", - sym::exp2f32 => "exp2f", - sym::exp2f64 => "exp2", - sym::logf32 => "logf", - sym::logf64 => "log", - sym::log10f32 => "log10f", - sym::log10f64 => "log10", - sym::log2f32 => "log2f", - sym::log2f64 => "log2", sym::fmaf32 => "fmaf", sym::fmaf64 => "fma", // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation @@ -116,11 +102,18 @@ fn get_simple_function_f128<'gcc, 'tcx>( let f128_type = cx.type_f128(); let func_name = match name { sym::ceilf128 => "ceilf128", + sym::cos => "cosf128", sym::fabs => "fabsf128", + sym::exp => "expf128", + sym::exp2 => "exp2f128", sym::floorf128 => "floorf128", + sym::log => "logf128", + sym::log2 => "log2f128", + sym::log10 => "log10f128", sym::truncf128 => "truncf128", sym::roundf128 => "roundf128", sym::round_ties_even_f128 => "roundevenf128", + sym::sin => "sinf128", sym::sqrtf128 => "sqrtf128", _ => span_bug!(span, "used get_simple_function_f128 for non-unary f128 intrinsic"), }; @@ -134,24 +127,6 @@ fn get_simple_function_f128<'gcc, 'tcx>( ) } -fn generic_f16_builtin<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, - args: &[OperandRef<'tcx, RValue<'gcc>>], -) -> RValue<'gcc> { - let f32_type = cx.type_f32(); - let builtin_name = match name { - sym::fabs => "fabsf", - _ => unreachable!(), - }; - - let func = cx.context.get_builtin_function(builtin_name); - let args: Vec<_> = - args.iter().map(|arg| cx.context.new_cast(None, arg.immediate(), f32_type)).collect(); - let result = cx.context.new_call(None, func, &args); - cx.context.new_cast(None, result, cx.type_f16()) -} - fn f16_builtin<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, @@ -161,10 +136,18 @@ fn f16_builtin<'gcc, 'tcx>( let builtin_name = match name { sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", + sym::cos => "cosf", + sym::exp => "expf", + sym::exp2 => "exp2f", + sym::fabs => "fabsf", sym::floorf16 => "__builtin_floorf", - sym::fmaf16 => "fmaf", + sym::log => "logf", + sym::log2 => "log2f", + sym::log10 => "log10f", + sym::powf16 => "__builtin_powf", sym::roundf16 => "__builtin_roundf", sym::round_ties_even_f16 => "__builtin_rintf", + sym::sin => "sinf", sym::sqrtf16 => "__builtin_sqrtf", sym::truncf16 => "__builtin_truncf", _ => unreachable!(), @@ -231,7 +214,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc sym::ceilf16 | sym::copysignf16 | sym::floorf16 - | sym::fmaf16 + | sym::powf16 | sym::roundf16 | sym::round_ties_even_f16 | sym::sqrtf16 @@ -427,16 +410,55 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } } } - sym::fabs => 'fabs: { + sym::fabs + | sym::exp + | sym::exp2 + | sym::log + | sym::log10 + | sym::log2 + | sym::sin + | sym::cos => 'float_unop: { let ty = args[0].layout.ty; let ty::Float(float_ty) = *ty.kind() else { span_bug!(span, "expected float type for fabs intrinsic: {:?}", ty); }; - let func = match float_ty { - ty::FloatTy::F16 => break 'fabs generic_f16_builtin(self, name, args), - ty::FloatTy::F32 => self.context.get_builtin_function("fabsf"), - ty::FloatTy::F64 => self.context.get_builtin_function("fabs"), - ty::FloatTy::F128 => get_simple_function_f128(span, self, name), + use ty::FloatTy::*; + let func = match (name, float_ty) { + (sym::fabs, F32) => self.context.get_builtin_function("fabsf"), + (sym::fabs, F64) => self.context.get_builtin_function("fabs"), + + (sym::exp, F32) => self.context.get_builtin_function("expf"), + (sym::exp, F64) => self.context.get_builtin_function("exp"), + + (sym::exp2, F32) => self.context.get_builtin_function("exp2f"), + (sym::exp2, F64) => self.context.get_builtin_function("exp2"), + + (sym::log, F32) => self.context.get_builtin_function("logf"), + (sym::log, F64) => self.context.get_builtin_function("log"), + + (sym::log10, F32) => self.context.get_builtin_function("log10f"), + (sym::log10, F64) => self.context.get_builtin_function("log10"), + + (sym::log2, F32) => self.context.get_builtin_function("log2f"), + (sym::log2, F64) => self.context.get_builtin_function("log2"), + + (sym::sin, F32) => self.context.get_builtin_function("sinf"), + (sym::sin, F64) => self.context.get_builtin_function("sin"), + + (sym::cos, F32) => self.context.get_builtin_function("cosf"), + (sym::cos, F64) => self.context.get_builtin_function("cos"), + + (_, F32 | F64) => unreachable!(), + + (_, F16) => break 'float_unop f16_builtin(self, name, args), + (_, F128) => { + if !self.cx.supports_f128_type { + // Fall back to default body + let fallback = Instance::new_raw(instance.def_id(), instance.args); + return IntrinsicResult::Fallback(fallback); + } + get_simple_function_f128(span, self, name) + } }; self.cx.context.new_call( self.location, diff --git a/src/lib.rs b/src/lib.rs index 7e22d6db50c..7abb2fa0d8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,7 @@ use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, ThinLtoInput, }; use rustc_codegen_ssa::base::codegen_crate; -use rustc_codegen_ssa::target_features::cfg_target_feature; +use rustc_codegen_ssa::target_features::internal_target_features; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; use rustc_data_structures::profiling::SelfProfilerRef; @@ -94,8 +94,8 @@ use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; -use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; +use rustc_session::{IncrCompSession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TargetTuple}; use tempfile::TempDir; @@ -306,13 +306,14 @@ impl CodegenBackend for GccCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, + incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") - .join(sess, crate_info) + .join(sess, incr_comp_session, crate_info) } fn target_config(&self, sess: &Session) -> TargetConfig { @@ -519,7 +520,7 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig { - let (unstable_target_features, target_features) = cfg_target_feature( + let internal_target_features = internal_target_features( sess, |feature| to_gcc_features(sess, feature), |feature| { @@ -543,8 +544,7 @@ fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128); TargetConfig { - target_features, - unstable_target_features, + internal_target_features, // There are no known bugs with GCC support for f16 or f128 has_reliable_f16, has_reliable_f16_math: has_reliable_f16, diff --git a/src/type_of.rs b/src/type_of.rs index 409343c6351..ce52ecab648 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -351,8 +351,8 @@ impl<'gcc, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn_abi.ptr_to_gcc_type(self) } - fn reg_backend_type(&self, _ty: &Reg) -> Type<'gcc> { - unimplemented!(); + fn reg_backend_type(&self, ty: &Reg) -> Type<'gcc> { + ty.gcc_type(self) } fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {