From 8ad69573fa39ad50418cce830bce003dbe8cde64 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sat, 24 May 2025 19:50:11 +0200 Subject: [PATCH 01/32] Cleanup CodegenFnAttrFlags - Rename `USED` to `USED_COMPILER` to better reflect its behavior. - Reorder some items to group the used and allocator flags together - Renumber them without gaps --- src/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/consts.rs b/src/consts.rs index 033afc0f8fbf4..8aed04c836ac6 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -154,7 +154,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): set link section. } - if attrs.flags.contains(CodegenFnAttrFlags::USED) + if attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { self.add_used_global(global.to_rvalue()); From 03485093d406657ee58d83ea4f56a4964c4cea2f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 14:15:41 +0000 Subject: [PATCH 02/32] Pass PlaceRef rather than Bx::Value to codegen_intrinsic_call --- src/intrinsic/mod.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index ba65c8205a500..18dabe9ea16c2 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -22,7 +22,7 @@ use rustc_codegen_ssa::traits::{ }; use rustc_middle::bug; #[cfg(feature = "master")] -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; @@ -202,7 +202,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], - llresult: RValue<'gcc>, + result: PlaceRef<'tcx, RValue<'gcc>>, span: Span, ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; @@ -221,7 +221,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let name_str = name.as_str(); let llret_ty = self.layout_of(ret_ty).gcc_type(self); - let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); @@ -271,7 +270,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc args[0].immediate(), args[1].immediate(), args[2].immediate(), - llresult, + result, ); return Ok(()); } @@ -1230,14 +1229,13 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, - dest: RValue<'gcc>, + dest: PlaceRef<'tcx, RValue<'gcc>>, ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { bx.call(bx.type_void(), None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. - let ret_align = bx.tcx.data_layout.i32_align.abi; - bx.store(bx.const_i32(0), dest, ret_align); + OperandValue::Immediate(bx.const_i32(0)).store(bx, dest); } else { if wants_msvc_seh(bx.sess()) { unimplemented!(); @@ -1261,12 +1259,12 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. #[cfg(feature = "master")] -fn codegen_gnu_try<'gcc>( - bx: &mut Builder<'_, 'gcc, '_>, +fn codegen_gnu_try<'gcc, 'tcx>( + bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue<'gcc>, data: RValue<'gcc>, catch_func: RValue<'gcc>, - dest: RValue<'gcc>, + dest: PlaceRef<'tcx, RValue<'gcc>>, ) { let cx: &CodegenCx<'gcc, '_> = bx.cx; let (llty, func) = get_rust_try_fn(cx, &mut |mut bx| { @@ -1322,8 +1320,7 @@ fn codegen_gnu_try<'gcc>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // Helper function used to get a handle to the `__rust_try` function used to From f99471360fe9fd8abf4e5a24083b232a1a06c301 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 14:58:58 +0000 Subject: [PATCH 03/32] Remove usage of FnAbi in codegen_intrinsic_call --- src/intrinsic/mod.rs | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 18dabe9ea16c2..1bcb891a2504a 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, PassMode}; use rustc_target::spec::PanicStrategy; #[cfg(feature = "master")] @@ -200,7 +200,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc fn codegen_intrinsic_call( &mut self, instance: Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], result: PlaceRef<'tcx, RValue<'gcc>>, span: Span, @@ -285,17 +284,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::volatile_load | sym::unaligned_volatile_load => { - let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); - let layout = self.layout_of(tp_ty); - let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { - let gcc_ty = ty.gcc_type(self); - self.volatile_load(gcc_ty, ptr) - } else { - self.volatile_load(layout.gcc_type(self), ptr) - }; + let load = self.volatile_load(result.layout.gcc_type(self), ptr); // TODO(antoyo): set alignment. - if let BackendRepr::Scalar(scalar) = layout.backend_repr { + if let BackendRepr::Scalar(scalar) = result.layout.backend_repr { self.to_immediate_scalar(load, scalar) } else { load @@ -510,16 +502,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc _ => return Err(Instance::new_raw(instance.def_id(), instance.args)), }; - if !fn_abi.ret.is_ignore() { - if let PassMode::Cast { cast: ref ty, .. } = fn_abi.ret.mode { - let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); - let ptr = self.pointercast(result.val.llval, ptr_llty); - self.store(value, ptr, result.val.align); - } else { - OperandRef::from_immediate_or_packed_pair(self, value, result.layout) - .val - .store(self, result); - } + if result.layout.ty.is_bool() { + OperandRef::from_immediate_or_packed_pair(self, value, result.layout) + .val + .store(self, result); + } else if !result.layout.ty.is_unit() { + let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self)); + let ptr = self.pointercast(result.val.llval, ptr_llty); + self.store(value, ptr, result.val.align); } Ok(()) } From f6489c325f9d3df5cf20ac25491785906b9d62a5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:39:26 +0000 Subject: [PATCH 04/32] Remove codegen_unit from MiscCodegenMethods --- src/base.rs | 11 ++++++++--- src/context.rs | 4 ---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/base.rs b/src/base.rs index a9d7808c833bb..c3ba975d9645e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -219,17 +219,22 @@ pub fn compile_codegen_unit( let mono_items = cgu.items_in_deterministic_order(tcx); for &(mono_item, data) in &mono_items { - mono_item.predefine::>(&cx, data.linkage, data.visibility); + mono_item.predefine::>( + &cx, + cgu_name.as_str(), + data.linkage, + data.visibility, + ); } // ... and now that we have everything pre-defined, fill out those definitions. for &(mono_item, item_data) in &mono_items { - mono_item.define::>(&mut cx, item_data); + mono_item.define::>(&mut cx, cgu_name.as_str(), item_data); } // If this codegen unit contains the main function, also create the // wrapper here - maybe_create_entry_wrapper::>(&cx); + maybe_create_entry_wrapper::>(&cx, cx.codegen_unit); // Finalize debuginfo if cx.sess().opts.debuginfo != DebugInfo::None { diff --git a/src/context.rs b/src/context.rs index 73718994e6417..c6c43201f2163 100644 --- a/src/context.rs +++ b/src/context.rs @@ -470,10 +470,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.tcx.sess } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { - self.codegen_unit - } - fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) { // TODO(antoyo) } From 4d47f6d72d5629ae1ab4ca5a8789b53bf324b13f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:52:38 +0000 Subject: [PATCH 05/32] Remove a couple of uses of interior mutability around statics --- src/consts.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 8aed04c836ac6..fbf9e11c45e68 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -67,7 +67,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { } #[cfg_attr(not(feature = "master"), allow(unused_mut))] - fn codegen_static(&self, def_id: DefId) { + fn codegen_static(&mut self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else { @@ -162,11 +162,11 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { } /// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*. - fn add_used_global(&self, _global: RValue<'gcc>) { + fn add_used_global(&mut self, _global: RValue<'gcc>) { // TODO(antoyo) } - fn add_compiler_used_global(&self, global: RValue<'gcc>) { + fn add_compiler_used_global(&mut self, global: RValue<'gcc>) { // NOTE: seems like GCC does not make the distinction between compiler.used and used. self.add_used_global(global); } From f297400574d6385561a9398b363dcf3228a95c15 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:21:43 +0000 Subject: [PATCH 06/32] Make predefine methods take &mut self --- src/base.rs | 2 +- src/mono_item.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index c3ba975d9645e..c105916bbb2b5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -220,7 +220,7 @@ pub fn compile_codegen_unit( let mono_items = cgu.items_in_deterministic_order(tcx); for &(mono_item, data) in &mono_items { mono_item.predefine::>( - &cx, + &mut cx, cgu_name.as_str(), data.linkage, data.visibility, diff --git a/src/mono_item.rs b/src/mono_item.rs index a2df7b2596fcf..539e3ac850763 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -16,7 +16,7 @@ use crate::{attributes, base}; impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_static( - &self, + &mut self, def_id: DefId, _linkage: Linkage, visibility: Visibility, @@ -42,7 +42,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_fn( - &self, + &mut self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, From 96be6effa41880fbe8be4069433244c40dcb7fbe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:29:05 +0000 Subject: [PATCH 07/32] Remove methods from StaticCodegenMethods that are not called in cg_ssa itself --- src/consts.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index fbf9e11c45e68..deb13ddf7558d 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -160,19 +160,14 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { self.add_used_global(global.to_rvalue()); } } +} +impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*. - fn add_used_global(&mut self, _global: RValue<'gcc>) { + pub fn add_used_global(&mut self, _global: RValue<'gcc>) { // TODO(antoyo) } - fn add_compiler_used_global(&mut self, global: RValue<'gcc>) { - // NOTE: seems like GCC does not make the distinction between compiler.used and used. - self.add_used_global(global); - } -} - -impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] pub fn add_used_function(&self, function: Function<'gcc>) { #[cfg(feature = "master")] From 244ea125f11ae7ea4a643fe20f62a6500b4b1a52 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:41:19 +0000 Subject: [PATCH 08/32] Mark all optimize methods and the codegen method as safe There is no safety contract and I don't think any of them can actually cause UB in more ways than passing malicious source code to rustc can. While LtoModuleCodegen::optimize says that the returned ModuleCodegen points into the LTO module, the LTO module has already been dropped by the time this function returns, so if the returned ModuleCodegen indeed points into the LTO module, we would have seen crashes on every LTO compilation, which we don't. As such the comment is outdated. --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6994c385fc831..f79ba2dcfc7ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -391,7 +391,7 @@ impl WriteBackendMethods for GccCodegenBackend { unimplemented!() } - unsafe fn optimize( + fn optimize( _cgcx: &CodegenContext, _dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, @@ -409,14 +409,14 @@ impl WriteBackendMethods for GccCodegenBackend { Ok(()) } - unsafe fn optimize_thin( + fn optimize_thin( cgcx: &CodegenContext, thin: ThinModule, ) -> Result, FatalError> { back::lto::optimize_thin_module(thin, cgcx) } - unsafe fn codegen( + fn codegen( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, From 0c6f946b82d2a2d988a8fd3d2336fac1b36d3174 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:50:01 +0000 Subject: [PATCH 09/32] Remove unused arg_memory_ty method --- src/abi.rs | 7 +++---- src/intrinsic/mod.rs | 11 ----------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index d882d3eecf49a..0c499ba623794 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -15,7 +15,6 @@ use rustc_target::callconv::{Conv, RiscvInterruptKind}; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; impl AbiBuilderMethods for Builder<'_, '_, '_> { @@ -125,7 +124,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), PassMode::Cast { ref cast, .. } => cast.gcc_type(cx), PassMode::Indirect { .. } => { - argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); + argument_tys.push(cx.type_ptr_to(self.ret.layout.gcc_type(cx))); cx.type_void() } }; @@ -176,13 +175,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => { // This is a "byval" argument, so we don't apply the `restrict` attribute on it. on_stack_param_indices.insert(argument_tys.len()); - arg.memory_ty(cx) + arg.layout.gcc_type(cx) } PassMode::Direct(attrs) => { apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()) } PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { - apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()) + apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len()) } PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { assert!(!on_stack); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 1bcb891a2504a..ff1ae2d9d792c 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -574,14 +574,9 @@ impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { ) { arg_abi.store(self, val, dst) } - - fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> { - arg_abi.memory_ty(self) - } } pub trait ArgAbiExt<'gcc, 'tcx> { - fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn store( &self, bx: &mut Builder<'_, 'gcc, 'tcx>, @@ -597,12 +592,6 @@ pub trait ArgAbiExt<'gcc, 'tcx> { } impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { - /// Gets the LLVM type for a place of the original Rust type of - /// this argument/return, i.e., the result of `type_of::type_of`. - fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - self.layout.gcc_type(cx) - } - /// Stores a direct/indirect value described by this ArgAbi into a /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables From dbbfb6e08bfa9de32071d0bc20729a7b18e04202 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 May 2025 12:15:04 +0200 Subject: [PATCH 10/32] get rid of rustc_codegen_ssa::common::AtomicOrdering --- src/builder.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 4e2163201fd01..d1fb8d8f9d6b8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -12,7 +12,7 @@ use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout, WrappingRange}; use rustc_apfloat::{Float, Round, Status, ieee}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::{ - AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, + AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, }; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -26,7 +26,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{self, AtomicOrdering, Instance, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::def_id::DefId; use rustc_target::callconv::FnAbi; @@ -75,7 +75,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let load_ordering = match order { // TODO(antoyo): does this make sense? - AtomicOrdering::AcquireRelease | AtomicOrdering::Release => AtomicOrdering::Acquire, + AtomicOrdering::AcqRel | AtomicOrdering::Release => AtomicOrdering::Acquire, _ => order, }; let previous_value = @@ -2474,8 +2474,8 @@ impl ToGccOrdering for AtomicOrdering { AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, AtomicOrdering::Release => __ATOMIC_RELEASE, - AtomicOrdering::AcquireRelease => __ATOMIC_ACQ_REL, - AtomicOrdering::SequentiallyConsistent => __ATOMIC_SEQ_CST, + AtomicOrdering::AcqRel => __ATOMIC_ACQ_REL, + AtomicOrdering::SeqCst => __ATOMIC_SEQ_CST, }; ordering as i32 } From 5c4b7978deee0fd9282fab61dc859bf191b31df9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 09:25:27 +0000 Subject: [PATCH 11/32] Use layout field of OperandRef and PlaceRef in codegen_intrinsic_call This avoids having to get the function signature. --- src/intrinsic/mod.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index ff1ae2d9d792c..1c06bd730955e 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -212,15 +212,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc _ => bug!("expected fn item type, found {}", callee_ty), }; - let sig = callee_ty.fn_sig(tcx); - let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig); - let arg_tys = sig.inputs(); - let ret_ty = sig.output(); let name = tcx.item_name(def_id); let name_str = name.as_str(); - let llret_ty = self.layout_of(ret_ty).gcc_type(self); - let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); @@ -320,8 +314,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::rotate_right | sym::saturating_add | sym::saturating_sub => { - let ty = arg_tys[0]; - match int_type_width_signed(ty, self) { + match int_type_width_signed(args[0].layout.ty, self) { Some((width, signed)) => match name { sym::ctlz | sym::cttz => { let func = self.current_func.borrow().expect("func"); @@ -400,7 +393,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, - ty, + ty: args[0].layout.ty, }); return Ok(()); } @@ -492,7 +485,15 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } _ if name_str.starts_with("simd_") => { - match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { + match generic_simd_intrinsic( + self, + name, + callee_ty, + args, + result.layout.ty, + result.layout.gcc_type(self), + span, + ) { Ok(value) => value, Err(()) => return Ok(()), } From 926c8c80f680a6347c60a552a492a33145ef8380 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 09:39:11 +0000 Subject: [PATCH 12/32] Use layout field of OperandRef in generic_simd_intrinsic --- src/intrinsic/mod.rs | 1 - src/intrinsic/simd.rs | 87 ++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 1c06bd730955e..f6afb15aafe27 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -488,7 +488,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc match generic_simd_intrinsic( self, name, - callee_ty, args, result.layout.ty, result.layout.gcc_type(self), diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index b897d07924914..82ef0d0b13a45 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -28,7 +28,6 @@ use crate::context::CodegenCx; pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, - callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, @@ -54,24 +53,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }; } - let tcx = bx.tcx(); - let sig = tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), - callee_ty.fn_sig(tcx), - ); - let arg_tys = sig.inputs(); - if name == sym::simd_select_bitmask { require_simd!( - arg_tys[1], - InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + args[1].layout.ty, + InvalidMonomorphization::SimdArgument { span, name, ty: args[1].layout.ty } ); - let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); + let (len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx()); let expected_int_bits = (len.max(8) - 1).next_power_of_two(); let expected_bytes = len / 8 + ((len % 8 > 0) as u64); - let mask_ty = arg_tys[0]; + let mask_ty = args[0].layout.ty; let mut mask = match *mask_ty.kind() { ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), @@ -121,8 +113,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } // every intrinsic below takes a SIMD vector as its first argument - require_simd!(arg_tys[0], InvalidMonomorphization::SimdInput { span, name, ty: arg_tys[0] }); - let in_ty = arg_tys[0]; + require_simd!( + args[0].layout.ty, + InvalidMonomorphization::SimdInput { span, name, ty: args[0].layout.ty } + ); + let in_ty = args[0].layout.ty; let comparison = match name { sym::simd_eq => Some(BinOp::Eq), @@ -134,7 +129,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( _ => None, }; - let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx()); + let (in_len, in_elem) = args[0].layout.ty.simd_size_and_type(bx.tcx()); if let Some(cmp_op) = comparison { require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); @@ -401,13 +396,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( #[cfg(feature = "master")] if name == sym::simd_insert || name == sym::simd_insert_dyn { require!( - in_elem == arg_tys[2], + in_elem == args[2].layout.ty, InvalidMonomorphization::InsertedType { span, name, in_elem, in_ty, - out_ty: arg_tys[2] + out_ty: args[2].layout.ty } ); @@ -439,10 +434,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let m_elem_ty = in_elem; let m_len = in_len; require_simd!( - arg_tys[1], - InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + args[1].layout.ty, + InvalidMonomorphization::SimdArgument { span, name, ty: args[1].layout.ty } ); - let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); + let (v_len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx()); require!( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } @@ -911,18 +906,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // All types must be simd vector types require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); require_simd!( - arg_tys[1], - InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + args[1].layout.ty, + InvalidMonomorphization::SimdSecond { span, name, ty: args[1].layout.ty } ); require_simd!( - arg_tys[2], - InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + args[2].layout.ty, + InvalidMonomorphization::SimdThird { span, name, ty: args[2].layout.ty } ); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); // Of the same length: - let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); - let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); + let (out_len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx()); + let (out_len2, _) = args[2].layout.ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, InvalidMonomorphization::SecondArgumentLength { @@ -930,7 +925,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( name, in_len, in_ty, - arg_ty: arg_tys[1], + arg_ty: args[1].layout.ty, out_len } ); @@ -941,7 +936,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( name, in_len, in_ty, - arg_ty: arg_tys[2], + arg_ty: args[2].layout.ty, out_len: out_len2 } ); @@ -970,8 +965,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // The second argument must be a simd vector with an element type that's a pointer // to the element type of the first argument - let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); - let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); + let (_, element_ty0) = args[0].layout.ty.simd_size_and_type(bx.tcx()); + let (_, element_ty1) = args[1].layout.ty.simd_size_and_type(bx.tcx()); let (pointer_count, underlying_ty) = match *element_ty1.kind() { ty::RawPtr(p_ty, _) if p_ty == in_elem => { (ptr_count(element_ty1), non_ptr(element_ty1)) @@ -983,7 +978,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( span, name, expected_element: element_ty1, - second_arg: arg_tys[1], + second_arg: args[1].layout.ty, in_elem, in_ty, mutability: ExpectedPointerMutability::Not, @@ -998,7 +993,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // The element type of the third argument must be an integer type of any width: // TODO: also support unsigned integers. - let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); + let (_, element_ty2) = args[2].layout.ty.simd_size_and_type(bx.tcx()); match *element_ty2.kind() { ty::Int(_) => (), _ => { @@ -1030,17 +1025,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // All types must be simd vector types require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); require_simd!( - arg_tys[1], - InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + args[1].layout.ty, + InvalidMonomorphization::SimdSecond { span, name, ty: args[1].layout.ty } ); require_simd!( - arg_tys[2], - InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + args[2].layout.ty, + InvalidMonomorphization::SimdThird { span, name, ty: args[2].layout.ty } ); // Of the same length: - let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx()); - let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); + let (element_len1, _) = args[1].layout.ty.simd_size_and_type(bx.tcx()); + let (element_len2, _) = args[2].layout.ty.simd_size_and_type(bx.tcx()); require!( in_len == element_len1, InvalidMonomorphization::SecondArgumentLength { @@ -1048,7 +1043,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( name, in_len, in_ty, - arg_ty: arg_tys[1], + arg_ty: args[1].layout.ty, out_len: element_len1 } ); @@ -1059,7 +1054,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( name, in_len, in_ty, - arg_ty: arg_tys[2], + arg_ty: args[2].layout.ty, out_len: element_len2 } ); @@ -1082,9 +1077,9 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // The second argument must be a simd vector with an element type that's a pointer // to the element type of the first argument - let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); - let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); - let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); + let (_, element_ty0) = args[0].layout.ty.simd_size_and_type(bx.tcx()); + let (_, element_ty1) = args[1].layout.ty.simd_size_and_type(bx.tcx()); + let (_, element_ty2) = args[2].layout.ty.simd_size_and_type(bx.tcx()); let (pointer_count, underlying_ty) = match *element_ty1.kind() { ty::RawPtr(p_ty, mutbl) if p_ty == in_elem && mutbl == hir::Mutability::Mut => { (ptr_count(element_ty1), non_ptr(element_ty1)) @@ -1096,7 +1091,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( span, name, expected_element: element_ty1, - second_arg: arg_tys[1], + second_arg: args[1].layout.ty, in_elem, in_ty, mutability: ExpectedPointerMutability::Mut, @@ -1194,8 +1189,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return_error!(InvalidMonomorphization::ExpectedVectorElementType { span, name, - expected_element: arg_tys[0].simd_size_and_type(bx.tcx()).1, - vector_type: arg_tys[0], + expected_element: args[0].layout.ty.simd_size_and_type(bx.tcx()).1, + vector_type: args[0].layout.ty, }); } }; From 6c6c31d46184b8a566f4213ef6037615e96227c1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 09:39:43 +0000 Subject: [PATCH 13/32] Avoid computing function type for intrinsic instances --- src/intrinsic/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index f6afb15aafe27..2b1dca72d068a 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -23,7 +23,7 @@ use rustc_codegen_ssa::traits::{ use rustc_middle::bug; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +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}; @@ -205,15 +205,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc span: Span, ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; - let callee_ty = instance.ty(tcx, self.typing_env()); - let (def_id, fn_args) = match *callee_ty.kind() { - ty::FnDef(def_id, fn_args) => (def_id, fn_args), - _ => bug!("expected fn item type, found {}", callee_ty), - }; - - let name = tcx.item_name(def_id); + let name = tcx.item_name(instance.def_id()); let name_str = name.as_str(); + let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); From f383b17668e0f564aae978f01d8eef7b115aa8ca Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 10:04:35 +0000 Subject: [PATCH 14/32] Directly use from_immediate for handling bool --- src/intrinsic/mod.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 2b1dca72d068a..73be25ba92b7e 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -498,13 +498,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc }; if result.layout.ty.is_bool() { - OperandRef::from_immediate_or_packed_pair(self, value, result.layout) - .val - .store(self, result); + let val = self.from_immediate(value); + self.store_to_place(val, result.val); } else if !result.layout.ty.is_unit() { - let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self)); - let ptr = self.pointercast(result.val.llval, ptr_llty); - self.store(value, ptr, result.val.align); + self.store_to_place(value, result.val); } Ok(()) } From 2d7d0ee91c4406a42ae74b9dc80c940140fe2095 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 2 Jun 2025 14:35:19 -0400 Subject: [PATCH 15/32] Update to nightly-2025-06-02 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index bafe497a2a2a1..8be204c15810f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-05-21" +channel = "nightly-2025-06-02" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 38f134c7db8d88c28b1b300f37d05e9d6674b6b6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 2 Jun 2025 14:35:25 -0400 Subject: [PATCH 16/32] Remove unneeded patch --- ...001-Pin-compiler_builtins-to-0.1.160.patch | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 patches/0001-Pin-compiler_builtins-to-0.1.160.patch diff --git a/patches/0001-Pin-compiler_builtins-to-0.1.160.patch b/patches/0001-Pin-compiler_builtins-to-0.1.160.patch deleted file mode 100644 index 39266e081edee..0000000000000 --- a/patches/0001-Pin-compiler_builtins-to-0.1.160.patch +++ /dev/null @@ -1,39 +0,0 @@ -From cdb3d407740e4f15c3746051f8ba89b8e74e99d3 Mon Sep 17 00:00:00 2001 -From: None -Date: Fri, 30 May 2025 13:46:22 -0400 -Subject: [PATCH] Pin compiler_builtins to 0.1.160 - ---- - library/alloc/Cargo.toml | 2 +- - library/std/Cargo.toml | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml -index 9d0d957..365c9dc 100644 ---- a/library/alloc/Cargo.toml -+++ b/library/alloc/Cargo.toml -@@ -16,7 +16,7 @@ bench = false - - [dependencies] - core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.159", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.160", features = ['rustc-dep-of-std'] } - - [features] - compiler-builtins-mem = ['compiler_builtins/mem'] -diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml -index 4ff4895..31371f0 100644 ---- a/library/std/Cargo.toml -+++ b/library/std/Cargo.toml -@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } - panic_unwind = { path = "../panic_unwind", optional = true } - panic_abort = { path = "../panic_abort" } - core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.159" } -+compiler_builtins = { version = "=0.1.160" } - unwind = { path = "../unwind" } - hashbrown = { version = "0.15", default-features = false, features = [ - 'rustc-dep-of-std', --- -2.49.0 - From 2e89179368b3c8fc46699b008a37e0ffafeac44b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 5 Jun 2025 17:08:01 -0400 Subject: [PATCH 17/32] Make comment more specific --- src/context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/context.rs b/src/context.rs index 1d46d73cd2653..c9ce97c81ebdf 100644 --- a/src/context.rs +++ b/src/context.rs @@ -127,7 +127,8 @@ pub struct CodegenCx<'gcc, 'tcx> { pub pointee_infos: RefCell, Size), Option>>, /// NOTE: a hack is used because the rustc API is not suitable to libgccjit and as such, - /// `const_undef()` returns struct as pointer so that they can later be assigned a value. + /// `const_undef()` returns struct as pointer so that they can later be assigned a value (in + /// e.g. Builder::insert_value). /// As such, this set remembers which of these pointers were returned by this function so that /// they can be dereferenced later. /// FIXME(antoyo): fix the rustc API to avoid having this hack. From ed441b64ede18d483c65a6376e7bde8dea94294f Mon Sep 17 00:00:00 2001 From: michal kostrubiec Date: Sat, 14 Jun 2025 20:53:01 +0200 Subject: [PATCH 18/32] Added support for testing the backend with abi-cafe --- build_system/src/abi_test.rs | 62 ++++++++++++++++++++++++++++++++++++ build_system/src/main.rs | 8 +++-- 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 build_system/src/abi_test.rs diff --git a/build_system/src/abi_test.rs b/build_system/src/abi_test.rs new file mode 100644 index 0000000000000..421bc387ce84b --- /dev/null +++ b/build_system/src/abi_test.rs @@ -0,0 +1,62 @@ +use std::ffi::OsStr; +use std::path::Path; + +use crate::utils::run_command_with_output; + +fn show_usage() { + println!( + r#" +`abi-test` command help: + --help : Show this help"# + ); +} + +pub fn run() -> Result<(), String> { + let mut args = std::env::args().skip(2); + while let Some(arg) = args.next() { + match arg.as_str() { + "--help" => { + show_usage(); + return Ok(()); + } + _ => return Err(format!("Unknown option {}", arg)), + } + } + // Ensure that we have a cloned version of abi-cafe on hand. + crate::utils::git_clone( + "https://github.com/Gankra/abi-cafe.git", + Some("clones/abi-cafe".as_ref()), + true, + ) + .map_err(|err| (format!("Git clone failed with message: {err:?}!")))?; + // Configure abi-cafe to use the exact same rustc version we use - this is crucial. + // Otherwise, the concept of ABI compatibility becomes meanignless. + std::fs::copy("rust-toolchain", "clones/abi-cafe/rust-toolchain") + .expect("Could not copy toolchain configs!"); + // Get the backend path. + // We will use the *debug* build of the backend - it has more checks enabled. + let backend_path = std::path::absolute("target/debug/librustc_codegen_gcc.so").unwrap(); + let backend_arg = format!("--add-rustc-codegen-backend=cg_gcc:{}", backend_path.display()); + // Run ABI cafe using cargo. + let cmd: &[&dyn AsRef] = &[ + &"cargo", + &"run", + &"--release", + &"--", + &backend_arg, + // Test rust-LLVM to Rust-GCC calls + &"--pairs", + &"rustc_calls_cg_gcc", + &"--pairs", + &"cg_gcc_calls_rustc", + // Test Rust-GCC to C calls + &"--pairs", + &"cg_gcc_calls_c", + &"--pairs", + &"c_calls_cg_gcc", + ]; + // Run ABI cafe. + run_command_with_output(cmd, Some(&Path::new("clones/abi-cafe")))?; + + Ok(()) +} diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 078a4726ba80a..ae975c94fff25 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -1,5 +1,6 @@ use std::{env, process}; +mod abi_test; mod build; mod clean; mod clone_gcc; @@ -12,7 +13,6 @@ mod rust_tools; mod rustc_info; mod test; mod utils; - const BUILD_DIR: &str = "build"; macro_rules! arg_error { @@ -44,7 +44,8 @@ Commands: info : Displays information about the build environment and project configuration. clone-gcc : Clones the GCC compiler from a specified source. fmt : Runs rustfmt - fuzz : Fuzzes `cg_gcc` using rustlantis" + fuzz : Fuzzes `cg_gcc` using rustlantis + abi-test : Runs the abi-cafe test suite on the codegen, checking for ABI compatibility with LLVM" ); } @@ -59,6 +60,7 @@ pub enum Command { Info, Fmt, Fuzz, + AbiTest, } fn main() { @@ -77,6 +79,7 @@ fn main() { Some("test") => Command::Test, Some("info") => Command::Info, Some("clone-gcc") => Command::CloneGcc, + Some("abi-test") => Command::AbiTest, Some("fmt") => Command::Fmt, Some("fuzz") => Command::Fuzz, Some("--help") => { @@ -102,6 +105,7 @@ fn main() { Command::CloneGcc => clone_gcc::run(), Command::Fmt => fmt::run(), Command::Fuzz => fuzz::run(), + Command::AbiTest => abi_test::run(), } { eprintln!("Command failed to run: {e}"); process::exit(1); From b2b117ee281c817e1edbe34429a5a77faa2f3ece Mon Sep 17 00:00:00 2001 From: michal kostrubiec Date: Thu, 19 Jun 2025 13:45:14 +0200 Subject: [PATCH 19/32] Fixed some clippy warnings. --- build_system/src/abi_test.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build_system/src/abi_test.rs b/build_system/src/abi_test.rs index 421bc387ce84b..3c1531be27a52 100644 --- a/build_system/src/abi_test.rs +++ b/build_system/src/abi_test.rs @@ -13,13 +13,16 @@ fn show_usage() { pub fn run() -> Result<(), String> { let mut args = std::env::args().skip(2); + // FractalFir: In the future, I'd like to add some more subcommands / options. + // So, this loop ought to stay for that purpose. It should also stay as a while loop(to parse args) + #[allow(clippy::never_loop, clippy::while_let_on_iterator)] while let Some(arg) = args.next() { match arg.as_str() { "--help" => { show_usage(); return Ok(()); } - _ => return Err(format!("Unknown option {}", arg)), + _ => return Err(format!("Unknown option {arg:?}")), } } // Ensure that we have a cloned version of abi-cafe on hand. @@ -56,7 +59,7 @@ pub fn run() -> Result<(), String> { &"c_calls_cg_gcc", ]; // Run ABI cafe. - run_command_with_output(cmd, Some(&Path::new("clones/abi-cafe")))?; + run_command_with_output(cmd, Some(Path::new("clones/abi-cafe")))?; Ok(()) } From 8571aee6872ecfc489149eb9865d44add463e284 Mon Sep 17 00:00:00 2001 From: michal kostrubiec Date: Thu, 19 Jun 2025 23:31:18 +0200 Subject: [PATCH 20/32] Skip needless calls to get_align in some cases. --- src/builder.rs | 40 +++++++++++++++++++++++++++------------- src/context.rs | 7 +++++++ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 2c5ae3fff7be8..38ebf9974bf3a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -938,22 +938,36 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); + // NOTE(FractalFir): In some cases, we *should* skip the call to get_aligned. + // For example, calling `get_aligned` on a i8 is pointless(since it can only be 1 aligned) + // Calling get_aligned on a `u128`/`i128` causes the attribute to become "stacked" + // + // From GCCs perspective: + // __int128_t __attribute__((aligned(16))) __attribute__((aligned(16))) + // and: + // __int128_t __attribute__((aligned(16))) + // are 2 distinct, incompatible types. + // + // So, we skip the call to `get_aligned` in such a case. *Ideally*, we could do this for all the types, + // but the GCC APIs to facilitate this just aren't quite there yet. + + // This checks that we only skip `get_aligned` on 128 bit ints if they have the correct alignment. + // Otherwise, this may be an under-aligned load, so we will still call get_aligned. + let mut can_skip_align = (pointee_ty == self.cx.u128_type + || pointee_ty == self.cx.i128_type) + && align == self.int128_align; + // We can skip the call to `get_aligned` for byte-sized types with alignment of 1. + can_skip_align = can_skip_align + || (pointee_ty == self.cx.u8_type || pointee_ty == self.cx.i8_type) + && align.bytes() == 1; + // Skip the call to `get_aligned` when possible. + let aligned_type = + if can_skip_align { pointee_ty } else { pointee_ty.get_aligned(align.bytes()) }; + + let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer()); // NOTE: instead of returning the dereference here, we have to assign it to a variable in // the current basic block. Otherwise, it could be used in another basic block, causing a // dereference after a drop, for instance. - // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type. - // Ideally, we shouldn't need to do this check. - // FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if - // the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle - // under-aligned loads correctly. - let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type) - && align == self.int128_align - { - pointee_ty - } else { - pointee_ty.get_aligned(align.bytes()) - }; - let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer()); let deref = ptr.dereference(self.location).to_rvalue(); let loaded_value = function.new_local( self.location, diff --git a/src/context.rs b/src/context.rs index 8a2bf654ed2be..8454e49c66e33 100644 --- a/src/context.rs +++ b/src/context.rs @@ -157,6 +157,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type)) .unwrap(); let align = layout.align.abi.bytes(); + // For types with size 1, the alignment can be 1 and only 1 + // So, we can skip the call to ``get_aligned`. + // In the future, we can add a GCC API to query the type align, + // and call `get_aligned` if and only if that differs from Rust's expectations. + if layout.size.bytes() == 1 { + return context.new_c_type(ctype); + } #[cfg(feature = "master")] { context.new_c_type(ctype).get_aligned(align) From b03f7f87ff67d9589c51e56beac3734b0fb5349e Mon Sep 17 00:00:00 2001 From: michal kostrubiec Date: Wed, 25 Jun 2025 12:22:21 +0200 Subject: [PATCH 21/32] Refactored the codebase to use Function instead of RValue where possible. --- src/builder.rs | 3 +-- src/context.rs | 12 +++++------- src/debuginfo.rs | 6 +++--- src/declare.rs | 5 ++--- src/intrinsic/mod.rs | 7 +++---- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 2c5ae3fff7be8..0939c84144e76 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -520,8 +520,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block } - fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> { - let func = cx.rvalue_as_function(func); + fn append_block(_: &'a CodegenCx<'gcc, 'tcx>, func: Function<'gcc>, name: &str) -> Block<'gcc> { func.new_block(name) } diff --git a/src/context.rs b/src/context.rs index 8a2bf654ed2be..45b3bd06e13fc 100644 --- a/src/context.rs +++ b/src/context.rs @@ -375,8 +375,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { type Value = RValue<'gcc>; type Metadata = RValue<'gcc>; - // TODO(antoyo): change to Function<'gcc>. - type Function = RValue<'gcc>; + type Function = Function<'gcc>; type BasicBlock = Block<'gcc>; type Type = Type<'gcc>; @@ -394,11 +393,10 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self.vtables } - fn get_fn(&self, instance: Instance<'tcx>) -> RValue<'gcc> { + fn get_fn(&self, instance: Instance<'tcx>) -> Function<'gcc> { let func = get_fn(self, instance); *self.current_func.borrow_mut() = Some(func); - // FIXME(antoyo): this is a wrong cast. That requires changing the compiler API. - unsafe { std::mem::transmute(func) } + func } fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> { @@ -487,11 +485,11 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.codegen_unit } - fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) { + fn set_frame_pointer_type(&self, _llfn: Function<'gcc>) { // TODO(antoyo) } - fn apply_target_cpu_attr(&self, _llfn: RValue<'gcc>) { + fn apply_target_cpu_attr(&self, _llfn: Function<'gcc>) { // TODO(antoyo) } diff --git a/src/debuginfo.rs b/src/debuginfo.rs index e0597d0030d57..66ef12d2a855e 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -1,7 +1,7 @@ use std::ops::Range; use std::sync::Arc; -use gccjit::{Location, RValue}; +use gccjit::{Function, Location, RValue}; use rustc_abi::Size; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods}; @@ -225,7 +225,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self, instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - llfn: RValue<'gcc>, + llfn: Function<'gcc>, mir: &mir::Body<'tcx>, ) -> Option> { if self.sess().opts.debuginfo == DebugInfo::None { @@ -276,7 +276,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self, _instance: Instance<'tcx>, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - _maybe_definition_llfn: Option>, + _maybe_definition_llfn: Option>, ) -> Self::DIScope { // TODO(antoyo): implement. } diff --git a/src/declare.rs b/src/declare.rs index bed82073e2c41..691fd8729e39a 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -94,7 +94,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { _fn_type: Type<'gcc>, #[cfg(feature = "master")] callconv: Option>, #[cfg(not(feature = "master"))] callconv: Option<()>, - ) -> RValue<'gcc> { + ) -> Function<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::().make_pointer().make_pointer(); let return_type = self.type_i32(); @@ -111,8 +111,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { // NOTE: it is needed to set the current_func here as well, because get_fn() is not called // for the main function. *self.current_func.borrow_mut() = Some(func); - // FIXME(antoyo): this is a wrong cast. That requires changing the compiler API. - unsafe { std::mem::transmute(func) } + func } pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Function<'gcc> { diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index ba85bc2beff7b..8401e78bd2ffe 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -1484,10 +1484,9 @@ fn gen_fn<'a, 'gcc, 'tcx>( // FIXME(eddyb) find a nicer way to do this. cx.linkage.set(FunctionType::Internal); let func = cx.declare_fn(name, fn_abi); - let func_val = unsafe { std::mem::transmute::, RValue<'gcc>>(func) }; - cx.set_frame_pointer_type(func_val); - cx.apply_target_cpu_attr(func_val); - let block = Builder::append_block(cx, func_val, "entry-block"); + cx.set_frame_pointer_type(func); + cx.apply_target_cpu_attr(func); + let block = Builder::append_block(cx, func, "entry-block"); let bx = Builder::build(cx, block); codegen(bx); (return_type, func) From 413821fcbd3ac0f7448b37334f6fe60cb2bc10a3 Mon Sep 17 00:00:00 2001 From: michal kostrubiec Date: Thu, 26 Jun 2025 11:00:31 +0200 Subject: [PATCH 22/32] Remove unnecesary uses of the 'current_func' field, replacing it with a call to function. --- src/intrinsic/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 8401e78bd2ffe..4bebfee170b0d 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -426,7 +426,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc match int_type_width_signed(ty, self) { Some((width, signed)) => match name { sym::ctlz | sym::cttz => { - let func = self.current_func.borrow().expect("func"); + let func = self.current_func(); let then_block = func.new_block("then"); let else_block = func.new_block("else"); let after_block = func.new_block("after"); @@ -1108,7 +1108,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // for (int counter = 0; value != 0; counter++) { // value &= value - 1; // } - let func = self.current_func.borrow().expect("func"); + let func = self.current_func(); let loop_head = func.new_block("head"); let loop_body = func.new_block("body"); let loop_tail = func.new_block("tail"); @@ -1187,7 +1187,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let result_type = lhs.get_type(); if signed { // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 - let func = self.current_func.borrow().expect("func"); + let func = self.current_func(); let res = func.new_local(self.location, result_type, "saturating_sum"); let supports_native_type = self.is_native_int_type(result_type); let overflow = if supports_native_type { @@ -1258,7 +1258,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let result_type = lhs.get_type(); if signed { // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 - let func = self.current_func.borrow().expect("func"); + let func = self.current_func(); let res = func.new_local(self.location, result_type, "saturating_diff"); let supports_native_type = self.is_native_int_type(result_type); let overflow = if supports_native_type { From 7c71c8388fbe1a06a160e43ff6a37e335cc8e00f Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 14:44:54 -0400 Subject: [PATCH 23/32] Fix type_name intrinsic --- src/builder.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index 96e3773c7c486..f995220f75d8f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1105,7 +1105,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // TODO(antoyo) } - fn store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { + fn store(&mut self, mut val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { + if self.structs_as_pointer.borrow().contains(&val) { + // NOTE: hack to workaround a limitation of the rustc API: see comment on + // CodegenCx.structs_as_pointer + val = val.dereference(self.location).to_rvalue(); + } + self.store_with_flags(val, ptr, align, MemFlags::empty()) } From 144989400e64298805690dc923f50a97fbf41c9d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 14:51:16 -0400 Subject: [PATCH 24/32] Fix to use Function instead of RValue --- src/builder.rs | 11 ++++------- src/context.rs | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 148180cf9f1e8..102821f6d737c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1570,16 +1570,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { aggregate_value } - fn set_personality_fn(&mut self, _personality: RValue<'gcc>) { + fn set_personality_fn(&mut self, _personality: Function<'gcc>) { #[cfg(feature = "master")] - { - let personality = self.rvalue_as_function(_personality); - self.current_func().set_personality_function(personality); - } + self.current_func().set_personality_function(_personality); } #[cfg(feature = "master")] - fn cleanup_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + fn cleanup_landing_pad(&mut self, pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { self.set_personality_fn(pers_fn); // NOTE: insert the current block in a variable so that a later call to invoke knows to @@ -1610,7 +1607,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (value1, value2) } - fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { // TODO(antoyo): generate the correct landing pad self.cleanup_landing_pad(pers_fn) } diff --git a/src/context.rs b/src/context.rs index 42f7b4eecb0b2..08b47d6cbbb96 100644 --- a/src/context.rs +++ b/src/context.rs @@ -120,7 +120,7 @@ pub struct CodegenCx<'gcc, 'tcx> { /// A counter that is used for generating local symbol names local_gen_sym_counter: Cell, - eh_personality: Cell>>, + eh_personality: Cell>>, #[cfg(feature = "master")] pub rust_try_fn: Cell, Function<'gcc>)>>, @@ -428,7 +428,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { ptr } - fn eh_personality(&self) -> RValue<'gcc> { + fn eh_personality(&self) -> Function<'gcc> { // The exception handling personality function. // // If our compilation unit has the `eh_personality` lang item somewhere @@ -466,9 +466,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let symbol_name = tcx.symbol_name(instance).name; let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); self.linkage.set(FunctionType::Extern); - let func = self.declare_fn(symbol_name, fn_abi); - let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - func + self.declare_fn(symbol_name, fn_abi) } _ => { let name = if wants_msvc_seh(self.sess()) { @@ -476,8 +474,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } else { "rust_eh_personality" }; - let func = self.declare_func(name, self.type_i32(), &[], true); - unsafe { std::mem::transmute::, RValue<'gcc>>(func) } + self.declare_func(name, self.type_i32(), &[], true) } }; // TODO(antoyo): apply target cpu attributes. From eb4d42951556853481ea3d5834403f23b6e9f133 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 14:55:31 -0400 Subject: [PATCH 25/32] Fix for libgccjit 12 --- src/builder.rs | 2 +- src/intrinsic/mod.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 102821f6d737c..05620c621a90f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1597,7 +1597,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } #[cfg(not(feature = "master"))] - fn cleanup_landing_pad(&mut self, _pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + fn cleanup_landing_pad(&mut self, _pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { let value1 = self .current_func() .new_local(self.location, self.u8_type.make_pointer(), "landing_pad0") diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index c7bda8a597870..d2396b276cf9f 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -4,7 +4,9 @@ mod simd; #[cfg(feature = "master")] use std::iter; -use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp}; +#[cfg(feature = "master")] +use gccjit::Type; +use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout}; From c7c16223ce2fd4deab0269dd1ff2504042f88772 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 15:17:42 -0400 Subject: [PATCH 26/32] Ignore failing test --- tests/failing-ui-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index d931f0d3b5ebb..544d0bfc71050 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -9,6 +9,7 @@ tests/ui/iterators/iter-sum-overflow-debug.rs tests/ui/iterators/iter-sum-overflow-overflow-checks.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs +tests/ui/mir/mir_match_guard_let_chains_drop_order.rs tests/ui/oom_unwind.rs tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs tests/ui/panic-runtime/abort.rs From 49e65a04590250edd90561fa9e717988a23aaf7b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 15:38:35 -0400 Subject: [PATCH 27/32] Remove commented code --- src/common.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/common.rs b/src/common.rs index 58ff2f1f8f064..fdd47821b515b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -234,19 +234,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { match cv { Scalar::Int(int) => { let data = int.to_bits(layout.size(self)); - - // FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code - // the paths for floating-point values. - // TODO: Remove this code? - /*if ty == self.float_type { - return self - .context - .new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64); - } - if ty == self.double_type { - return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64)); - }*/ - let value = self.const_uint_big(self.type_ix(bitsize), data); let bytesize = layout.size(self).bytes(); if bitsize > 1 && ty.is_integral() && bytesize as u32 == ty.get_size() { From f876b18783906cdd5a4910ead475351c33c947ab Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 15:40:48 -0400 Subject: [PATCH 28/32] Add TODOs --- src/builder.rs | 1 + src/intrinsic/mod.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/builder.rs b/src/builder.rs index 05620c621a90f..100091692bab9 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -781,6 +781,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { return self.context.new_call(self.location, fmod, &[a, b]); } TypeKind::FP128 => { + // TODO(antoyo): use get_simple_function_f128_2args. let f128_type = self.type_f128(); let fmodf128 = self.context.new_function( None, diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index d2396b276cf9f..6d6f363225d4a 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -266,6 +266,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); + // TODO(antoyo): Only call get_simple_function_f128 and get_simple_function_f128_2args when + // it is the symbols for the supported f128 builtins. let simple_func = get_simple_function(self, name) .or_else(|| get_simple_function_f128(self, name)) .or_else(|| get_simple_function_f128_2args(self, name)); From 8385f3c4b0b888f4d4fb41ce10b892ca19e4ddce Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 28 Jun 2025 15:41:58 -0400 Subject: [PATCH 29/32] Stop skipping libcore's f16::test_total_cmp --- build_system/src/test.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index bcaab0fb526ba..f1f31f83ca244 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -738,14 +738,7 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { let path = get_sysroot_dir().join("sysroot_src/library/coretests"); let _ = remove_dir_all(path.join("target")); // TODO(antoyo): run in release mode when we fix the failures. - // TODO(antoyo): remove the --skip f16::test_total_cmp when this issue is fixed: - // https://github.com/rust-lang/rust/issues/141503 - run_cargo_command( - &[&"test", &"--", &"--skip", &"f16::test_total_cmp"], - Some(&path), - env, - args, - )?; + run_cargo_command(&[&"test"], Some(&path), env, args)?; Ok(()) } From 13d0ef30c9acf216d3c666a868639d0d84f257a8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 28 Jun 2025 23:50:00 +0200 Subject: [PATCH 30/32] Remove unwanted semi-colon in `rustc_codegen_gcc` --- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index a4454cd9c7345..805f68cd74ce0 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1610,7 +1610,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { // TODO(antoyo): generate the correct landing pad - self.cleanup_landing_pad(pers_fn); + self.cleanup_landing_pad(pers_fn) } #[cfg(feature = "master")] From a420d39afb992093bd0105aecfa033a640115c0a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 29 Jun 2025 00:00:58 +0200 Subject: [PATCH 31/32] Fix signature of `filter_landing_pad` --- compiler/rustc_codegen_gcc/src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 805f68cd74ce0..7f16d804103df 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1608,9 +1608,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (value1, value2) } - fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) -> () { // TODO(antoyo): generate the correct landing pad - self.cleanup_landing_pad(pers_fn) + self.cleanup_landing_pad(pers_fn); } #[cfg(feature = "master")] From 3dcbc1e5bcddfade60a459caad642fd8c37e8f68 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 29 Jun 2025 00:20:15 +0200 Subject: [PATCH 32/32] Remove `()` returned value --- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 7f16d804103df..1fce547ad1b49 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1608,7 +1608,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (value1, value2) } - fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) -> () { + fn filter_landing_pad(&mut self, pers_fn: Function<'gcc>) { // TODO(antoyo): generate the correct landing pad self.cleanup_landing_pad(pers_fn); }