From e62c26e39d5a6ffda051aa956efde35226262951 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 17 Feb 2022 14:16:52 +0000 Subject: [PATCH 1/2] On ARM, use relocation_model to detect whether r9 should be reserved The previous approach of checking for the reserve-r9 target feature didn't actually work because LLVM only sets this feature very late when initializing the per-function subtarget. --- src/inline_asm.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index c242c75ed18..10c2f06faf3 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -182,7 +182,12 @@ struct InlineAssemblyGenerator<'a, 'tcx> { impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { let sess = self.tcx.sess; - let map = allocatable_registers(self.arch, &sess.target_features, &sess.target); + let map = allocatable_registers( + self.arch, + sess.relocation_model(), + &sess.target_features, + &sess.target, + ); let mut allocated = FxHashMap::<_, (bool, bool)>::default(); let mut regs = vec![None; self.operands.len()]; @@ -315,6 +320,7 @@ fn allocate_stack_slots(&mut self) { // Allocate stack slots for saving clobbered registers let abi_clobber = InlineAsmClobberAbi::parse( self.arch, + self.tcx.sess.relocation_model(), &self.tcx.sess.target_features, &self.tcx.sess.target, sym::C, From 73cf3aaa7892d2f5d19324111f79de87978459ee Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 17 Feb 2022 18:16:04 +0000 Subject: [PATCH 2/2] Take CodegenFnAttrs into account when validating asm! register operands Checking of asm! register operands now properly takes function attributes such as #[target_feature] and #[instruction_set] into account. --- src/inline_asm.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 10c2f06faf3..deac5dfd3ec 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -106,6 +106,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( let mut asm_gen = InlineAssemblyGenerator { tcx: fx.tcx, arch: fx.tcx.sess.asm_arch.unwrap(), + enclosing_def_id: fx.instance.def_id(), template, operands, options, @@ -169,6 +170,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( struct InlineAssemblyGenerator<'a, 'tcx> { tcx: TyCtxt<'tcx>, arch: InlineAsmArch, + enclosing_def_id: DefId, template: &'a [InlineAsmTemplatePiece], operands: &'a [InlineAsmOperand<'tcx>], options: InlineAsmOptions, @@ -185,7 +187,7 @@ fn allocate_registers(&mut self) { let map = allocatable_registers( self.arch, sess.relocation_model(), - &sess.target_features, + self.tcx.asm_target_features(self.enclosing_def_id), &sess.target, ); let mut allocated = FxHashMap::<_, (bool, bool)>::default(); @@ -318,15 +320,9 @@ fn allocate_stack_slots(&mut self) { let mut new_slot = |x| new_slot_fn(&mut slot_size, x); // Allocate stack slots for saving clobbered registers - let abi_clobber = InlineAsmClobberAbi::parse( - self.arch, - self.tcx.sess.relocation_model(), - &self.tcx.sess.target_features, - &self.tcx.sess.target, - sym::C, - ) - .unwrap() - .clobbered_regs(); + let abi_clobber = InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, sym::C) + .unwrap() + .clobbered_regs(); for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) { let mut need_save = true; // If the register overlaps with a register clobbered by function call, then