Skip to content

Commit

Permalink
Rollup merge of rust-lang#130308 - davidtwco:tied-target-consolidatio…
Browse files Browse the repository at this point in the history
…n, r=wesleywiser

codegen_ssa: consolidate tied target checks

Fixes rust-lang#105110.
Fixes rust-lang#105111.

`rustc_codegen_llvm` and `rustc_codegen_gcc` duplicated logic for checking if tied target features were partially enabled. This PR consolidates these checks into `rustc_codegen_ssa` in the `codegen_fn_attrs` query, which also is run pre-monomorphisation for each function, which ensures that this check is run for unused functions, as would be expected.

Also adds a test confirming that enabling one tied feature doesn't imply another - the appropriate error for this was already being emitted. I did a bisect and narrowed it down to two patches it was likely to be - something in rust-lang#128796, probably rust-lang#128221 or rust-lang#128679.
  • Loading branch information
matthiaskrgr authored Oct 10, 2024
2 parents e0bb417 + 73c192b commit 2ca5753
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 80 deletions.
3 changes: 0 additions & 3 deletions messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ codegen_gcc_invalid_minimum_alignment =
codegen_gcc_lto_not_supported =
LTO is not supported. You may get a linker error.
codegen_gcc_tied_target_features = the target features {$features} must all be either enabled or disabled together
.help = add the missing features in a `target_feature` attribute
codegen_gcc_unwinding_inline_asm =
GCC backend does not support unwinding from inline asm
Expand Down
22 changes: 2 additions & 20 deletions src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ use rustc_attr::InstructionSetAttr;
#[cfg(feature = "master")]
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty;
use rustc_span::symbol::sym;

use crate::context::CodegenCx;
use crate::errors::TiedTargetFeatures;
use crate::gcc_util::{check_tied_features, to_gcc_features};
use crate::gcc_util::to_gcc_features;

/// Get GCC attribute for the provided inline heuristic.
#[cfg(feature = "master")]
Expand Down Expand Up @@ -72,26 +70,10 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
}
}

let function_features = codegen_fn_attrs
let mut function_features = codegen_fn_attrs
.target_features
.iter()
.map(|features| features.name.as_str())
.collect::<Vec<&str>>();

if let Some(features) = check_tied_features(
cx.tcx.sess,
&function_features.iter().map(|features| (*features, true)).collect(),
) {
let span = cx
.tcx
.get_attr(instance.def_id(), sym::target_feature)
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
cx.tcx.dcx().create_err(TiedTargetFeatures { features: features.join(", "), span }).emit();
return;
}

let mut function_features = function_features
.iter()
.flat_map(|feat| to_gcc_features(cx.tcx.sess, feat).into_iter())
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match *x {
InstructionSetAttr::ArmA32 => "-thumb-mode", // TODO(antoyo): support removing feature.
Expand Down
36 changes: 0 additions & 36 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;

use crate::fluent_generated as fluent;

#[derive(Diagnostic)]
#[diag(codegen_gcc_unknown_ctarget_feature_prefix)]
#[note]
Expand Down Expand Up @@ -45,15 +42,6 @@ pub(crate) struct InvalidMinimumAlignment {
pub err: String,
}

#[derive(Diagnostic)]
#[diag(codegen_gcc_tied_target_features)]
#[help]
pub(crate) struct TiedTargetFeatures {
#[primary_span]
pub span: Span,
pub features: String,
}

#[derive(Diagnostic)]
#[diag(codegen_gcc_copy_bitcode)]
pub(crate) struct CopyBitcode {
Expand All @@ -78,27 +66,3 @@ pub(crate) struct LtoDylib;
pub(crate) struct LtoBitcodeFromRlib {
pub gcc_err: String,
}

pub(crate) struct TargetFeatureDisableOrEnable<'a> {
pub features: &'a [&'a str],
pub span: Option<Span>,
pub missing_features: Option<MissingFeatures>,
}

#[derive(Subdiagnostic)]
#[help(codegen_gcc_missing_features)]
pub(crate) struct MissingFeatures;

impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable);
if let Some(span) = self.span {
diag.span(span);
};
if let Some(missing_features) = self.missing_features {
diag.subdiagnostic(missing_features);
}
diag.arg("features", self.features.join(", "));
diag
}
}
24 changes: 3 additions & 21 deletions src/gcc_util.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#[cfg(feature = "master")]
use gccjit::Context;
use rustc_codegen_ssa::codegen_attrs::check_tied_features;
use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::bug;
use rustc_session::Session;
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
use smallvec::{SmallVec, smallvec};

use crate::errors::{
PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature,
UnknownCTargetFeaturePrefix,
};
use crate::errors::{PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix};

/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
/// `--target` and similar).
Expand Down Expand Up @@ -185,23 +184,6 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
}
}

// Given a map from target_features to whether they are enabled or disabled,
// ensure only valid combinations are allowed.
pub fn check_tied_features(
sess: &Session,
features: &FxHashMap<&str, bool>,
) -> Option<&'static [&'static str]> {
for tied in sess.target.tied_target_features() {
// Tied features must be set to the same value, or not set at all
let mut tied_iter = tied.iter();
let enabled = features.get(tied_iter.next().unwrap());
if tied_iter.any(|feature| enabled != features.get(feature)) {
return Some(tied);
}
}
None
}

fn arch_to_gcc(name: &str) -> &str {
match name {
"M68020" => "68020",
Expand Down

0 comments on commit 2ca5753

Please sign in to comment.