diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/attributes.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm_util.rs | 14 |
2 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index e7669470026..3877460fcdb 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -271,6 +271,17 @@ fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { Some(sspattr.create_attr(cx.llcx)) } +fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { + if cx.sess().target.arch != "s390x" { + return None; + } + + let requested_features = cx.sess().opts.cg.target_feature.split(','); + let found_positive = requested_features.clone().any(|r| r == "+backchain"); + + if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None } +} + pub 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) @@ -447,6 +458,9 @@ pub fn from_fn_attrs<'ll, 'tcx>( if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); } + if let Some(backchain) = backchain_attr(cx) { + to_add.push(backchain); + } to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 98dc8ac86d2..4d56d1d3b1a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -14,7 +14,7 @@ use rustc_session::config::{PrintKind, PrintRequest}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; -use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; +use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES}; use std::ffi::{c_char, c_void, CStr, CString}; use std::fmt::Write; @@ -321,6 +321,10 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> { } }) .filter(|feature| { + // skip checking special features, as LLVM may not understands them + if RUSTC_SPECIAL_FEATURES.contains(feature) { + return true; + } // check that all features in a given smallvec are enabled for llvm_feature in to_llvm_features(sess, feature) { let cstr = SmallCStr::new(llvm_feature); @@ -546,6 +550,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str // -Ctarget-features let supported_features = sess.target.supported_target_features(); + let (llvm_major, _, _) = get_version(); let mut featsmap = FxHashMap::default(); let feats = sess .opts @@ -604,6 +609,13 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str if RUSTC_SPECIFIC_FEATURES.contains(&feature) { return None; } + + // if the target-feature is "backchain" and LLVM version is greater than 18 + // then we also need to add "+backchain" to the target-features attribute. + // otherwise, we will only add the naked `backchain` attribute to the attribute-group. + if feature == "backchain" && llvm_major < 18 { + return None; + } // ... otherwise though we run through `to_llvm_features` when // passing requests down to LLVM. This means that all in-language // features also work on the command line instead of having two |
