Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match asm::InlineAsmClobberAbi::parse(
asm_arch,
&self.tcx.sess.target,
&self.tcx.sess.unstable_target_features,
&self.tcx.sess.internal_target_features,
*abi_name,
) {
Ok(abi) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/inline_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
let abi_clobber = InlineAsmClobberAbi::parse(
self.arch,
&self.tcx.sess.target,
&self.tcx.sess.unstable_target_features,
&self.tcx.sess.internal_target_features,
sym::C,
)
.unwrap()
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::settings::{self, Configurable};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back};
use rustc_data_structures::unord::UnordSet;
use rustc_log::tracing::info;
use rustc_middle::dep_graph::WorkProductMap;
use rustc_session::Session;
Expand Down Expand Up @@ -170,8 +171,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
},
_ => vec![],
};
// FIXME do `unstable_target_features` properly
let unstable_target_features = target_features.clone();

// FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU
// targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128`
Expand All @@ -186,8 +185,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
let has_reliable_f128_math = has_reliable_f16_f128 && sess.target.env == Env::Gnu;

TargetConfig {
target_features,
unstable_target_features,
internal_target_features: UnordSet::from_iter(target_features),
// `rustc_codegen_cranelift` polyfills functionality not yet
// available in Cranelift.
has_reliable_f16: has_reliable_f16_f128,
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ use rustc_codegen_ssa::back::write::{
CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, ThinLtoInput,
};
use rustc_codegen_ssa::base::codegen_crate;
use rustc_codegen_ssa::target_features::cfg_target_feature;
use rustc_codegen_ssa::target_features::internal_target_features;
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods};
use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
use rustc_data_structures::profiling::SelfProfilerRef;
Expand Down Expand Up @@ -531,7 +531,7 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {

/// Returns the features that should be set in `cfg(target_feature)`.
fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig {
let (unstable_target_features, target_features) = cfg_target_feature(
let internal_target_features = internal_target_features(
sess,
|feature| to_gcc_features(sess, feature),
|feature| {
Expand All @@ -555,8 +555,7 @@ fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig
let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128);

TargetConfig {
target_features,
unstable_target_features,
internal_target_features,
// There are no known bugs with GCC support for f16 or f128
has_reliable_f16,
has_reliable_f16_math: has_reliable_f16,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -970,14 +970,14 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
Hexagon(HexagonInlineAsmRegClass::vreg) => {
// HVX vector register size depends on the HVX mode.
// LLVM's "v" constraint requires the exact vector width.
if cx.tcx.sess.unstable_target_features.contains(&sym::hvx_length128b) {
if cx.tcx.sess.internal_target_features.contains(&sym::hvx_length128b) {
cx.type_vector(cx.type_i32(), 32) // 1024-bit for 128B mode
} else {
cx.type_vector(cx.type_i32(), 16) // 512-bit for 64B mode
}
}
Hexagon(HexagonInlineAsmRegClass::vreg_pair) => {
if cx.tcx.sess.unstable_target_features.contains(&sym::hvx_length128b) {
if cx.tcx.sess.internal_target_features.contains(&sym::hvx_length128b) {
cx.type_vector(cx.type_i32(), 64) // 2048-bit for 128B mode
} else {
cx.type_vector(cx.type_i32(), 32) // 1024-bit for 64B mode
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,9 @@ fn packed_stack_attr<'ll>(

// The backchain and softfloat flags can be set via -Ctarget-features=...
// or via #[target_features(enable = ...)] so we have to check both possibilities
let have_backchain = sess.unstable_target_features.contains(&sym::backchain)
let have_backchain = sess.internal_target_features.contains(&sym::backchain)
|| function_attributes.iter().any(|feature| feature.name == sym::backchain);
let have_softfloat = sess.unstable_target_features.contains(&sym::soft_float)
let have_softfloat = sess.internal_target_features.contains(&sym::soft_float)
|| function_attributes.iter().any(|feature| feature.name == sym::soft_float);

// If both, backchain and packedstack, are enabled LLVM cannot generate valid function entry points
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub(crate) fn target_machine_factory(
let code_model = to_llvm_code_model(sess.code_model());

// This is used to set cfg_has_threads, so all logic must be in this method.
let singlethread = sess.target.singlethread(&sess.target_features);
let singlethread = sess.target.singlethread(&sess.internal_target_features);

let triple = SmallCStr::new(&versioned_llvm_target(sess));
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{ptr, slice, str};

use libc::c_int;
use rustc_codegen_ssa::base::wants_wasm_eh;
use rustc_codegen_ssa::target_features::cfg_target_feature;
use rustc_codegen_ssa::target_features::internal_target_features;
use rustc_codegen_ssa::{TargetConfig, target_features};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::small_c_str::SmallCStr;
Expand Down Expand Up @@ -314,17 +314,17 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
pub(crate) fn target_config(sess: &Session) -> TargetConfig {
let target_machine = create_informational_target_machine(sess, true);

let (unstable_target_features, target_features) = cfg_target_feature(
let internal_target_features = internal_target_features(
sess,
|feature| {
to_llvm_features(sess, feature)
.map(|f| SmallVec::<[&str; 2]>::from_iter(f.into_iter()))
.unwrap_or_default()
},
|feature| {
// This closure determines whether the target CPU has the feature according to LLVM. We do
// *not* consider the `-Ctarget-feature`s here, as that will be handled later in
// `cfg_target_feature`.
// This closure determines whether the target CPU has the feature according to LLVM. We
// do *not* consider the `-Ctarget-feature`s here, as that will be handled later in
// `internal_target_features`.
if let Some(feat) = to_llvm_features(sess, feature) {
// All the LLVM features this expands to must be enabled.
for llvm_feature in feat {
Expand All @@ -344,8 +344,7 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
);

let mut cfg = TargetConfig {
target_features,
unstable_target_features,
internal_target_features,
has_reliable_f16: true,
has_reliable_f16_math: true,
has_reliable_f128: true,
Expand Down Expand Up @@ -730,7 +729,10 @@ pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) ->
target_features::flag_to_backend_features(sess, extend_backend_features);
}

// We add this in the "base target" so that these show up in `sess.unstable_target_features`.
// `-C` flags that map to LLVM target features.
// We need to include them even with `only_base_features` as this is used to populate
// `sess.internal_target_features` where we very much want them to be present (e.g. the inline
// asm logic uses that to check which registers may be used).
llvm_features_by_flags(sess, &mut features);

features
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
// It is important that the order of reservation matches the order of writing.
// The object crate contains many debug asserts that fire if you get this wrong.

let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.internal_target_features)
else {
sess.dcx().fatal(format!(
"raw-dylib is not supported for the architecture `{}`",
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
Endian::Big => Endianness::Big,
};
let Some((architecture, sub_architecture)) =
sess.target.object_architecture(&sess.unstable_target_features)
sess.target.object_architecture(&sess.internal_target_features)
else {
return None;
};
Expand Down Expand Up @@ -328,12 +328,12 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
let mut e_flags: u32 = 0x0;

// Check if compression is enabled
if sess.target_features.contains(&sym::zca) {
if sess.internal_target_features.contains(&sym::zca) {
e_flags |= elf::EF_RISCV_RVC;
}

// Check if RVTSO is enabled
if sess.target_features.contains(&sym::ztso) {
if sess.internal_target_features.contains(&sym::ztso) {
e_flags |= elf::EF_RISCV_TSO;
}
Comment on lines -331 to 338

@RalfJung RalfJung Aug 4, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to check whether the feature is in cfg(target_feature) rather than checking whether the feature is enabled. I don't think that makes a ton of sense... it means that with -Ctarget-feature=+zca on stable, we do enable that target feature (with a warning), but we don't set the flags here.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually these features are stable so this diff is a non-functional change.


Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ pub(crate) struct TargetFeatureSafeTrait {

#[derive(Diagnostic)]
#[diag("target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason}")]
pub(crate) struct ForbiddenTargetFeatureAttr<'a> {
pub(crate) struct InternalOnlyTargetFeatureAttr<'a> {
#[primary_span]
pub span: Span,
pub feature: &'a str,
Expand Down Expand Up @@ -1233,7 +1233,7 @@ pub(crate) struct UnstableCTargetFeature<'a> {

#[derive(Diagnostic)]
#[diag("target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}")]
pub(crate) struct ForbiddenCTargetFeature<'a> {
pub(crate) struct InternalOnlyCTargetFeature<'a> {
pub feature: &'a str,
pub enabled: &'a str,
pub reason: &'a str,
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::sync::Arc;

use rustc_abi::Size;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordMap;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind};
use rustc_hir::def_id::CrateNum;
Expand Down Expand Up @@ -306,14 +306,12 @@ pub struct CrateInfo {
pub exported_symbols_for_lto: Vec<String>,
}

/// Target-specific options that get set in `cfg(...)`.
/// Target-specific options that get set in `sess`/`cfg(...)`.
///
/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
pub struct TargetConfig {
/// Options to be set in `cfg(target_features)`.
pub target_features: Vec<Symbol>,
/// Options to be set in `cfg(target_features)`, but including unstable features.
pub unstable_target_features: Vec<Symbol>,
/// Options to be set in `sess.internal_target_features`.
pub internal_target_features: UnordSet<Symbol>,
/// Option for `cfg(target_has_reliable_f16)`, true if `f16` basic arithmetic works.
pub has_reliable_f16: bool,
/// Option for `cfg(target_has_reliable_f16_math)`, true if `f16` math calls work.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ fn prefix_and_suffix<'tcx>(
let asm_binary_format = &tcx.sess.target.binary_format;

let is_arm = tcx.sess.target.arch == Arch::Arm;
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
let is_thumb = tcx.sess.internal_target_features.contains(&sym::thumb_mode);
let function_sections =
tcx.sess.opts.unstable_opts.function_sections.unwrap_or(tcx.sess.target.function_sections);

Expand Down
Loading