Reformat some comments.

So they are less than 100 chars.
This commit is contained in:
Nicholas Nethercote 2024-09-18 13:34:49 +10:00
parent 5fd16dffdc
commit 1f359405cb
15 changed files with 78 additions and 66 deletions

View File

@ -403,8 +403,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
to_add.push(AttributeKind::Naked.create_attr(cx.llcx)); to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
// HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions. // HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules. // And it is a module-level attribute, so the alternative is pulling naked functions into
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768 // new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
// https://github.com/rust-lang/rust/issues/98768
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx)); to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
if llvm_util::get_version() < (19, 0, 0) { if llvm_util::get_version() < (19, 0, 0) {
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to // Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
@ -454,7 +455,8 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
flags |= AllocKindFlags::Zeroed; flags |= AllocKindFlags::Zeroed;
} }
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags)); to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
// apply to return place instead of function (unlike all other attributes applied in this function) // apply to return place instead of function (unlike all other attributes applied in this
// function)
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx); let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]); attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
} }

View File

@ -156,15 +156,15 @@ fn get_bitcode_slice_from_object_data<'a>(
obj: &'a [u8], obj: &'a [u8],
cgcx: &CodegenContext<LlvmCodegenBackend>, cgcx: &CodegenContext<LlvmCodegenBackend>,
) -> Result<&'a [u8], LtoBitcodeFromRlib> { ) -> Result<&'a [u8], LtoBitcodeFromRlib> {
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR that // We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
// won't work. Fortunately, if that's what we have we can just return the object directly, so we sniff // that won't work. Fortunately, if that's what we have we can just return the object directly,
// the relevant magic strings here and return. // so we sniff the relevant magic strings here and return.
if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") { if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") {
return Ok(obj); return Ok(obj);
} }
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment name" // We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
// which in the public API for sections gets treated as part of the section name, but internally // name" which in the public API for sections gets treated as part of the section name, but
// in MachOObjectFile.cpp gets treated separately. // internally in MachOObjectFile.cpp gets treated separately.
let section_name = bitcode_section_name(cgcx).trim_start_matches("__LLVM,"); let section_name = bitcode_section_name(cgcx).trim_start_matches("__LLVM,");
let mut len = 0; let mut len = 0;
let data = unsafe { let data = unsafe {

View File

@ -86,15 +86,17 @@ impl Deref for OwnedTargetMachine {
type Target = llvm::TargetMachine; type Target = llvm::TargetMachine;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine // SAFETY: constructing ensures we have a valid pointer created by
// llvm::LLVMRustCreateTargetMachine.
unsafe { self.tm_unique.as_ref() } unsafe { self.tm_unique.as_ref() }
} }
} }
impl Drop for OwnedTargetMachine { impl Drop for OwnedTargetMachine {
fn drop(&mut self) { fn drop(&mut self) {
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine // SAFETY: constructing ensures we have a valid pointer created by
// OwnedTargetMachine is not copyable so there is no double free or use after free // llvm::LLVMRustCreateTargetMachine OwnedTargetMachine is not copyable so there is no
// double free or use after free.
unsafe { unsafe {
llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut()); llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
} }

View File

@ -157,7 +157,8 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel { fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
match relocation_model { match relocation_model {
RelocModel::Static => llvm::RelocModel::Static, RelocModel::Static => llvm::RelocModel::Static,
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra attribute. // LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra
// attribute.
RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC, RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC,
RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic, RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
RelocModel::Ropi => llvm::RelocModel::ROPI, RelocModel::Ropi => llvm::RelocModel::ROPI,
@ -188,8 +189,8 @@ pub(crate) fn target_machine_factory(
let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" { let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" {
sess.opts.cg.soft_float sess.opts.cg.soft_float
} else { } else {
// `validate_commandline_args_with_session_available` has already warned about this being ignored. // `validate_commandline_args_with_session_available` has already warned about this being
// Let's make sure LLVM doesn't suddenly start using this flag on more targets. // ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
false false
}; };

View File

@ -673,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
// for performance. LLVM doesn't seem to care about this, and will happily treat // for performance. LLVM doesn't seem to care about this, and will happily treat
// `!nontemporal` stores as-if they were normal stores (for reordering optimizations // `!nontemporal` stores as-if they were normal stores (for reordering optimizations
// etc) even on x86, despite later lowering them to MOVNT which do *not* behave like // etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
// regular stores but require special fences. // regular stores but require special fences. So we keep a list of architectures
// So we keep a list of architectures where `!nontemporal` is known to be truly just // where `!nontemporal` is known to be truly just a hint, and use regular stores
// a hint, and use regular stores everywhere else. // everywhere else. (In the future, we could alternatively ensure that an sfence
// (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt // gets emitted after a sequence of movnt before any kind of synchronizing
// before any kind of synchronizing operation. But it's not clear how to do that with LLVM.) // operation. But it's not clear how to do that with LLVM.)
// For more context, see <https://github.com/rust-lang/rust/issues/114582> and // For more context, see <https://github.com/rust-lang/rust/issues/114582> and
// <https://github.com/llvm/llvm-project/issues/64521>. // <https://github.com/llvm/llvm-project/issues/64521>.
const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] = const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] =

View File

@ -73,8 +73,8 @@ pub(crate) fn const_alloc_to_llvm<'ll>(
// Generating partially-uninit consts is limited to small numbers of chunks, // Generating partially-uninit consts is limited to small numbers of chunks,
// to avoid the cost of generating large complex const expressions. // to avoid the cost of generating large complex const expressions.
// For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element, // For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element, and
// and would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`. // would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`.
let max = cx.sess().opts.unstable_opts.uninit_const_chunk_threshold; let max = cx.sess().opts.unstable_opts.uninit_const_chunk_threshold;
let allow_uninit_chunks = chunks.clone().take(max.saturating_add(1)).count() <= max; let allow_uninit_chunks = chunks.clone().take(max.saturating_add(1)).count() <= max;
@ -249,8 +249,8 @@ impl<'ll> CodegenCx<'ll, '_> {
trace!(?instance); trace!(?instance);
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
// the llvm type from the actual evaluated initializer. // out the llvm type from the actual evaluated initializer.
let llty = if nested { let llty = if nested {
self.type_i8() self.type_i8()
} else { } else {
@ -320,15 +320,16 @@ impl<'ll> CodegenCx<'ll, '_> {
} }
if !def_id.is_local() { if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) && let needs_dll_storage_attr = self.use_dll_storage_attrs
&& !self.tcx.is_foreign_item(def_id)
// Local definitions can never be imported, so we must not apply // Local definitions can never be imported, so we must not apply
// the DLLImport annotation. // the DLLImport annotation.
!dso_local && && !dso_local
// ThinLTO can't handle this workaround in all cases, so we don't // ThinLTO can't handle this workaround in all cases, so we don't
// emit the attrs. Instead we make them unnecessary by disallowing // emit the attrs. Instead we make them unnecessary by disallowing
// dynamic linking when linker plugin based LTO is enabled. // dynamic linking when linker plugin based LTO is enabled.
!self.tcx.sess.opts.cg.linker_plugin_lto.enabled() && && !self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
self.tcx.sess.lto() != Lto::Thin; && self.tcx.sess.lto() != Lto::Thin;
// If this assertion triggers, there's something wrong with commandline // If this assertion triggers, there's something wrong with commandline
// argument validation. // argument validation.
@ -551,8 +552,8 @@ impl<'ll> CodegenCx<'ll, '_> {
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
// on other targets, in particular MachO targets have *their* static constructor // on other targets, in particular MachO targets have *their* static constructor
// lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However, // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
// that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`, // that check happens when assigning the `CodegenFnAttrFlags` in
// so we don't need to take care of it here. // `rustc_hir_analysis`, so we don't need to take care of it here.
self.add_compiler_used_global(g); self.add_compiler_used_global(g);
} }
if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {

View File

@ -231,7 +231,8 @@ pub(crate) unsafe fn create_module<'ll>(
} }
} }
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.) // Enable LTO unit splitting if specified or if CFI is enabled. (See
// https://reviews.llvm.org/D53891.)
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() { if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr(); let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
unsafe { unsafe {

View File

@ -121,7 +121,8 @@ mod mcdc {
num_conditions: u16, num_conditions: u16,
} }
// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257) // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at
// [19](https://github.com/llvm/llvm-project/pull/81257).
type LLVMConditionId = i16; type LLVMConditionId = i16;
/// Must match the layout of `LLVMRustMCDCBranchParameters`. /// Must match the layout of `LLVMRustMCDCBranchParameters`.

View File

@ -48,11 +48,10 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
self.function_coverage_map.replace(FxIndexMap::default()) self.function_coverage_map.replace(FxIndexMap::default())
} }
/// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap. /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is
/// In order to handle nested decisions, several condition bitmaps can be /// called condition bitmap. In order to handle nested decisions, several condition bitmaps can
/// allocated for a function body. /// be allocated for a function body. These values are named `mcdc.addr.{i}` and are a 32-bit
/// These values are named `mcdc.addr.{i}` and are a 32-bit integers. /// integers. They respectively hold the condition bitmaps for decisions with a depth of `i`.
/// They respectively hold the condition bitmaps for decisions with a depth of `i`.
fn try_get_mcdc_condition_bitmap( fn try_get_mcdc_condition_bitmap(
&self, &self,
instance: &Instance<'tcx>, instance: &Instance<'tcx>,
@ -157,8 +156,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
), ),
CoverageKind::CounterIncrement { id } => { CoverageKind::CounterIncrement { id } => {
func_coverage.mark_counter_id_seen(id); func_coverage.mark_counter_id_seen(id);
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`, // We need to explicitly drop the `RefMut` before calling into
// as that needs an exclusive borrow. // `instrprof_increment`, as that needs an exclusive borrow.
drop(coverage_map); drop(coverage_map);
// The number of counters passed to `llvm.instrprof.increment` might // The number of counters passed to `llvm.instrprof.increment` might

View File

@ -44,7 +44,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
// Add the pretty printers for the standard library first. // Add the pretty printers for the standard library first.
section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0"); section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0");
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute. // Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
// attribute.
let visualizers = collect_debugger_visualizers_transitive( let visualizers = collect_debugger_visualizers_transitive(
cx.tcx, cx.tcx,
DebuggerVisualizerType::GdbPrettyPrinter, DebuggerVisualizerType::GdbPrettyPrinter,

View File

@ -216,8 +216,9 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
// need to make sure that we don't break existing debuginfo consumers // need to make sure that we don't break existing debuginfo consumers
// by doing that (at least not without a warning period). // by doing that (at least not without a warning period).
let layout_type = if ptr_type.is_box() { let layout_type = if ptr_type.is_box() {
// The assertion at the start of this function ensures we have a ZST allocator. // The assertion at the start of this function ensures we have a ZST
// We'll make debuginfo "skip" all ZST allocators, not just the default allocator. // allocator. We'll make debuginfo "skip" all ZST allocators, not just the
// default allocator.
Ty::new_mut_ptr(cx.tcx, pointee_type) Ty::new_mut_ptr(cx.tcx, pointee_type)
} else { } else {
ptr_type ptr_type
@ -280,8 +281,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>, unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> { ) -> DINodeCreationResult<'ll> {
// It's possible to create a self-referential // It's possible to create a self-referential type in Rust by using 'impl trait':
// type in Rust by using 'impl trait':
// //
// fn foo() -> impl Copy { foo } // fn foo() -> impl Copy { foo }
// //
@ -573,14 +573,14 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
{ {
// If the compiler's working directory (which also is the DW_AT_comp_dir of // If the compiler's working directory (which also is the DW_AT_comp_dir of
// the compilation unit) is a prefix of the path we are about to emit, then // the compilation unit) is a prefix of the path we are about to emit, then
// only emit the part relative to the working directory. // only emit the part relative to the working directory. Because of path
// Because of path remapping we sometimes see strange things here: `abs_path` // remapping we sometimes see strange things here: `abs_path` might
// might actually look like a relative path // actually look like a relative path (e.g.
// (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without // `<crate-name-and-version>/src/lib.rs`), so if we emit it without taking
// taking the working directory into account, downstream tooling will // the working directory into account, downstream tooling will interpret it
// interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`, // as `<working-directory>/<crate-name-and-version>/src/lib.rs`, which
// which makes no sense. Usually in such cases the working directory will also // makes no sense. Usually in such cases the working directory will also be
// be remapped to `<crate-name-and-version>` or some other prefix of the path // remapped to `<crate-name-and-version>` or some other prefix of the path
// we are remapping, so we end up with // we are remapping, so we end up with
// `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`. // `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
// By moving the working directory portion into the `directory` part of the // By moving the working directory portion into the `directory` part of the

View File

@ -404,7 +404,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let llvm_name = let llvm_name =
&format!("llvm.fsh{}.i{}", if is_left { 'l' } else { 'r' }, width); &format!("llvm.fsh{}.i{}", if is_left { 'l' } else { 'r' }, width);
// llvm expects shift to be the same type as the values, but rust always uses `u32` // llvm expects shift to be the same type as the values, but rust
// always uses `u32`.
let raw_shift = self.intcast(raw_shift, self.val_ty(val), false); let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
self.call_intrinsic(llvm_name, &[val, val, raw_shift]) self.call_intrinsic(llvm_name, &[val, val, raw_shift])
@ -573,8 +574,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
span, span,
) { ) {
Ok(llval) => llval, Ok(llval) => llval,
// If there was an error, just skip this invocation... we'll abort compilation anyway, // If there was an error, just skip this invocation... we'll abort compilation
// but we can keep codegen'ing to find more errors. // anyway, but we can keep codegen'ing to find more errors.
Err(()) => return Ok(()), Err(()) => return Ok(()),
} }
} }
@ -1847,7 +1848,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
require!( require!(
matches!( matches!(
*pointer_ty.kind(), *pointer_ty.kind(),
ty::RawPtr(p_ty, p_mutbl) if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut() ty::RawPtr(p_ty, p_mutbl)
if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
), ),
InvalidMonomorphization::ExpectedElementType { InvalidMonomorphization::ExpectedElementType {
span, span,

View File

@ -2150,7 +2150,8 @@ unsafe extern "C" {
pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char; pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
// This function makes copies of pointed to data, so the data's lifetime may end after this function returns // This function makes copies of pointed to data, so the data's lifetime may end after this
// function returns.
pub fn LLVMRustCreateTargetMachine( pub fn LLVMRustCreateTargetMachine(
Triple: *const c_char, Triple: *const c_char,
CPU: *const c_char, CPU: *const c_char,

View File

@ -217,10 +217,10 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
// where `{ARCH}` is the architecture name. Look for instances of `SubtargetFeature`. // where `{ARCH}` is the architecture name. Look for instances of `SubtargetFeature`.
// //
// Check the current rustc fork of LLVM in the repo at https://github.com/rust-lang/llvm-project/. // Check the current rustc fork of LLVM in the repo at https://github.com/rust-lang/llvm-project/.
// The commit in use can be found via the `llvm-project` submodule in https://github.com/rust-lang/rust/tree/master/src // The commit in use can be found via the `llvm-project` submodule in
// Though note that Rust can also be build with an external precompiled version of LLVM // https://github.com/rust-lang/rust/tree/master/src Though note that Rust can also be build with
// which might lead to failures if the oldest tested / supported LLVM version // an external precompiled version of LLVM which might lead to failures if the oldest tested /
// doesn't yet support the relevant intrinsics // supported LLVM version doesn't yet support the relevant intrinsics.
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> { pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> {
let arch = if sess.target.arch == "x86_64" { let arch = if sess.target.arch == "x86_64" {
"x86" "x86"
@ -259,8 +259,8 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")), ("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
// Filter out features that are not supported by the current LLVM version // Filter out features that are not supported by the current LLVM version
("aarch64", "fpmr") if get_version().0 != 18 => None, ("aarch64", "fpmr") if get_version().0 != 18 => None,
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called // In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single
// `fast-unaligned-access`. In LLVM 19, it was split back out. // feature called `fast-unaligned-access`. In LLVM 19, it was split back out.
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => { ("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
Some(LLVMFeature::new("fast-unaligned-access")) Some(LLVMFeature::new("fast-unaligned-access"))
} }
@ -406,7 +406,8 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
.supported_target_features() .supported_target_features()
.iter() .iter()
.filter_map(|(feature, _gate, _implied)| { .filter_map(|(feature, _gate, _implied)| {
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these
// strings.
let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name; let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
let desc = let desc =
match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() { match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {

View File

@ -24,8 +24,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
) { ) {
let instance = Instance::mono(self.tcx, def_id); let instance = Instance::mono(self.tcx, def_id);
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
// the llvm type from the actual evaluated initializer. // out the llvm type from the actual evaluated initializer.
let ty = if nested { let ty = if nested {
self.tcx.types.unit self.tcx.types.unit
} else { } else {