diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/attributes.rs')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/attributes.rs | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index fde95104093..92a857c2adc 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,6 +1,6 @@ //! Set and unset common attributes on LLVM values. -pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; @@ -17,13 +17,13 @@ use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace use crate::value::Value; use crate::{attributes, llvm_util}; -pub fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { +pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { if !attrs.is_empty() { llvm::AddFunctionAttributes(llfn, idx, attrs); } } -pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) { +pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) { if !attrs.is_empty() { llvm::AddCallSiteAttributes(callsite, idx, attrs); } @@ -80,7 +80,7 @@ fn patchable_function_entry_attrs<'ll>( /// Get LLVM sanitize attributes. #[inline] -pub fn sanitize_attrs<'ll>( +pub(crate) fn sanitize_attrs<'ll>( cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, ) -> SmallVec<[&'ll Attribute; 4]> { @@ -120,7 +120,7 @@ pub fn sanitize_attrs<'ll>( /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] -pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute { +pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute { // NOTE: We should determine if we even need async unwind tables, as they // take have more overhead and if we can use sync unwind tables we // probably should. @@ -128,7 +128,7 @@ pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Att llvm::CreateUWTableAttr(llcx, async_unwind) } -pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { let mut fp = cx.sess().target.frame_pointer; let opts = &cx.sess().opts; // "mcount" function relies on stack pointer. @@ -280,19 +280,19 @@ fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None } } -pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { +pub(crate) fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { let target_cpu = llvm_util::target_cpu(cx.tcx.sess); llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) } -pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { llvm_util::tune_cpu(cx.tcx.sess) .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu)) } /// Get the `NonLazyBind` LLVM attribute, /// if the codegen options allow skipping the PLT. -pub fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { // Don't generate calls through PLT if it's not necessary if !cx.sess().needs_plt() { Some(AttributeKind::NonLazyBind.create_attr(cx.llcx)) @@ -327,7 +327,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute { /// Helper for `FnAbi::apply_attrs_llfn`: /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. -pub fn llfn_attrs_from_instance<'ll, 'tcx>( +pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>, @@ -521,13 +521,20 @@ pub fn llfn_attrs_from_instance<'ll, 'tcx>( let function_features = function_features .iter() - .flat_map(|feat| { - llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}")) - }) + // Convert to LLVMFeatures and filter out unavailable ones + .flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat)) + // Convert LLVMFeatures & dependencies to +<feats>s + .flat_map(|feat| feat.into_iter().map(|f| format!("+{f}"))) .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x { InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(), InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(), })) + // HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled + // It only exists as a feature in LLVM 18, cannot be passed down for any other version + .chain(match &*cx.tcx.sess.target.arch { + "aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()], + _ => vec![], + }) .collect::<Vec<String>>(); if cx.tcx.sess.target.is_like_wasm { |
