use std::collections::VecDeque;
use std::ffi::{CStr, CString};
use std::fmt::Write;
use std::path::Path;
use std::sync::Once;
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::{TargetConfig, target_features};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_fs_util::path_to_c_string;
use rustc_middle::bug;
use rustc_session::Session;
use rustc_session::config::{NATIVE_CPU, PrintKind, PrintRequest};
use rustc_target::spec::{
    Arch, CfgAbi, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport,
};
use smallvec::{SmallVec, smallvec};

use crate::back::write::create_informational_target_machine;
use crate::{diagnostics, llvm};

static INIT: Once = Once::new();

pub(crate) fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        if !llvm::LLVMIsMultithreaded().is_true() {
            bug!("LLVM compiled without support for threads");
        }
        INIT.call_once(|| {
            configure_llvm(sess);
        });
    }
}

fn require_inited() {
    if !INIT.is_completed() {
        bug!("LLVM is not initialized");
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let n_args = sess.opts.cg.llvm_args.len() + sess.target.llvm_args.len();
    let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
    let mut llvm_args = Vec::with_capacity(n_args + 1);

    unsafe {
        llvm::LLVMRustInstallErrorHandlers();
    }
    // On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
    // box for the purpose of launching a debugger. However, on CI this will
    // cause it to hang until it times out, which can take several hours.
    if std::env::var_os("CI").is_some() {
        unsafe {
            llvm::LLVMRustDisableSystemDialogsOnCrash();
        }
    }

    fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
        full_arg.trim().split(|c: char| c == '=' || c.is_whitespace()).next().unwrap_or("")
    }

    let cg_opts = sess.opts.cg.llvm_args.iter().map(AsRef::as_ref);
    let tg_opts = sess.target.llvm_args.iter().map(AsRef::as_ref);
    // Target-spec args are passed to LLVM before user `-Cllvm-args`. LLVM's
    // `cl::opt` parser is last-wins, so this lets `-Cllvm-args=...` override
    // a value already set in the target spec (e.g. `-wasm-use-legacy-eh`).
    let sess_args = tg_opts.chain(cg_opts);

    let user_specified_args: FxHashSet<_> =
        sess_args.clone().map(|s| llvm_arg_to_arg_name(s)).filter(|s| !s.is_empty()).collect();

    {
        // This adds the given argument to LLVM. Unless `force` is true
        // user specified arguments are *not* overridden.
        let mut add = |arg: &str, force: bool| {
            if force || !user_specified_args.contains(llvm_arg_to_arg_name(arg)) {
                let s = CString::new(arg).unwrap();
                llvm_args.push(s.as_ptr());
                llvm_c_strs.push(s);
            }
        };
        // Set the llvm "program name" to make usage and invalid argument messages more clear.
        add("rustc -Cllvm-args=\"...\" with", true);
        if sess.opts.unstable_opts.time_llvm_passes {
            add("-time-passes", false);
        }
        if sess.opts.unstable_opts.print_llvm_passes {
            add("-debug-pass=Structure", false);
        }
        if sess.target.generate_arange_section
            && !sess.opts.unstable_opts.no_generate_arange_section
        {
            add("-generate-arange-section", false);
        }

        match sess.opts.unstable_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
            MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
            MergeFunctions::Aliases => {
                add("-mergefunc-use-aliases", false);
            }
        }

        if wants_wasm_eh(sess) {
            add("-wasm-enable-eh", false);
        }

        // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes
        // during inlining. Unfortunately these may block other optimizations.
        add("-preserve-alignment-assumptions-during-inlining=false", false);

        // Use non-zero `import-instr-limit` multiplier for cold callsites.
        add("-import-cold-multiplier=0.1", false);

        if sess.print_llvm_stats() || sess.print_llvm_stats_json().is_some() {
            add("-stats", false);
        }

        for arg in sess_args {
            add(&(*arg), true);
        }

        match (
            sess.opts.unstable_opts.small_data_threshold,
            sess.target.small_data_threshold_support(),
        ) {
            // Set up the small-data optimization limit for architectures that use
            // an LLVM argument to control this.
            (Some(threshold), SmallDataThresholdSupport::LlvmArg(arg)) => {
                add(&format!("--{arg}={threshold}"), false)
            }
            _ => (),
        };
    }

    if sess.opts.unstable_opts.llvm_time_trace {
        unsafe { llvm::LLVMRustTimeTraceProfilerInitialize() };
    }

    rustc_llvm::initialize_available_targets();

    unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) };
}

pub(crate) fn time_trace_profiler_finish(file_name: &Path) {
    unsafe {
        let file_name = path_to_c_string(file_name);
        llvm::LLVMRustTimeTraceProfilerFinish(file_name.as_ptr());
    }
}

enum TargetFeatureFoldStrength<'a> {
    // The feature is only tied when enabling the feature, disabling
    // this feature shouldn't disable the tied feature.
    EnableOnly(&'a str),
    // The feature is tied for both enabling and disabling this feature.
    Both(&'a str),
}

impl<'a> TargetFeatureFoldStrength<'a> {
    fn as_str(&self) -> &'a str {
        match self {
            TargetFeatureFoldStrength::EnableOnly(feat) => feat,
            TargetFeatureFoldStrength::Both(feat) => feat,
        }
    }
}

pub(crate) struct LLVMFeature<'a> {
    llvm_feature_name: &'a str,
    dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
}

impl<'a> LLVMFeature<'a> {
    fn new(llvm_feature_name: &'a str) -> Self {
        Self { llvm_feature_name, dependencies: SmallVec::new() }
    }

    fn with_dependencies(
        llvm_feature_name: &'a str,
        dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
    ) -> Self {
        Self { llvm_feature_name, dependencies }
    }
}

impl<'a> IntoIterator for LLVMFeature<'a> {
    type Item = &'a str;
    type IntoIter = impl Iterator<Item = &'a str>;

    fn into_iter(self) -> Self::IntoIter {
        let dependencies = self.dependencies.into_iter().map(|feat| feat.as_str());
        std::iter::once(self.llvm_feature_name).chain(dependencies)
    }
}

/// Convert a Rust feature name to an LLVM feature name. Returning `None` means the
/// feature should be skipped, usually because it is not supported by the current
/// LLVM version.
///
/// WARNING: the features after applying `to_llvm_features` must be known
/// to LLVM or the feature detection code will walk past the end of the feature
/// array, leading to crashes.
///
/// To find a list of LLVM's names, see llvm-project/llvm/lib/Target/{ARCH}/*.td
/// 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/>. The commit in use can be found via the
/// `llvm-project` submodule in <https://github.com/rust-lang/rust/tree/HEAD/src> Though note that
/// Rust can also be build with an external precompiled version of LLVM which might lead to failures
/// if the oldest tested / 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>> {
    let (major, _, _) = get_version();
    match sess.target.arch {
        Arch::AArch64 | Arch::Arm64EC => {
            match s {
                "rcpc2" => Some(LLVMFeature::new("rcpc-immo")),
                "dpb" => Some(LLVMFeature::new("ccpp")),
                "dpb2" => Some(LLVMFeature::new("ccdp")),
                "frintts" => Some(LLVMFeature::new("fptoint")),
                "fcma" => Some(LLVMFeature::new("complxnum")),
                "pmuv3" => Some(LLVMFeature::new("perfmon")),
                "paca" => Some(LLVMFeature::new("pauth")),
                "pacg" => Some(LLVMFeature::new("pauth")),
                "flagm2" => Some(LLVMFeature::new("altnzcv")),
                // Rust ties fp and neon together.
                "neon" => Some(LLVMFeature::with_dependencies(
                    "neon",
                    smallvec![TargetFeatureFoldStrength::Both("fp-armv8")],
                )),
                // In LLVM neon implicitly enables fp, but we manually enable
                // neon when a feature only implicitly enables fp
                "fhm" => Some(LLVMFeature::new("fp16fml")),
                "fp16" => Some(LLVMFeature::new("fullfp16")),
                // Filter out features that are not supported by the current LLVM version
                "fpmr" => None, // only existed in 18
                // Withdrawn by ARM; removed from LLVM in 22
                "tme" if major >= 22 => None,
                s => Some(LLVMFeature::new(s)),
            }
        }
        Arch::Arm => match s {
            "fp16" => Some(LLVMFeature::new("fullfp16")),
            s => Some(LLVMFeature::new(s)),
        },
        Arch::Bpf => match s {
            "allows-misaligned-mem-access" if major < 22 => None,
            s => Some(LLVMFeature::new(s)),
        },
        // Filter out features that are not supported by the current LLVM version
        Arch::PowerPC | Arch::PowerPC64 => match s {
            "power8-crypto" => Some(LLVMFeature::new("crypto")),
            s => Some(LLVMFeature::new(s)),
        },
        Arch::RiscV32 | Arch::RiscV64 => match s {
            // Filter out Rust-specific *virtual* target feature
            "zkne_or_zknd" => None,
            s => Some(LLVMFeature::new(s)),
        },
        Arch::Sparc | Arch::Sparc64 => match s {
            "leoncasa" => Some(LLVMFeature::new("hasleoncasa")),
            s => Some(LLVMFeature::new(s)),
        },
        Arch::Wasm32 | Arch::Wasm64 => match s {
            "gc" if major < 22 => None,
            s => Some(LLVMFeature::new(s)),
        },
        Arch::X86 | Arch::X86_64 => {
            match s {
                "sse4.2" => Some(LLVMFeature::with_dependencies(
                    "sse4.2",
                    smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")],
                )),
                "pclmulqdq" => Some(LLVMFeature::new("pclmul")),
                "rdrand" => Some(LLVMFeature::new("rdrnd")),
                "bmi1" => Some(LLVMFeature::new("bmi")),
                "cmpxchg16b" => Some(LLVMFeature::new("cx16")),
                "lahfsahf" => Some(LLVMFeature::new("sahf")),
                // Enable the evex512 target feature if an avx512 target feature is enabled.
                s if s.starts_with("avx512") && major < 22 => Some(LLVMFeature::with_dependencies(
                    s,
                    smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")],
                )),
                "avx10.1" if major < 22 => Some(LLVMFeature::new("avx10.1-512")),
                "avx10.2" if major < 22 => Some(LLVMFeature::new("avx10.2-512")),
                "apxf" => Some(LLVMFeature::with_dependencies(
                    "egpr",
                    smallvec![
                        TargetFeatureFoldStrength::Both("push2pop2"),
                        TargetFeatureFoldStrength::Both("ppx"),
                        TargetFeatureFoldStrength::Both("ndd"),
                        TargetFeatureFoldStrength::Both("ccmp"),
                        TargetFeatureFoldStrength::Both("cf"),
                        TargetFeatureFoldStrength::Both("nf"),
                        TargetFeatureFoldStrength::Both("zu"),
                    ],
                )),
                s => Some(LLVMFeature::new(s)),
            }
        }
        _ => Some(LLVMFeature::new(s)),
    }
}

/// Used to generate cfg variables and apply features.
/// Must express features in the way Rust understands them.
///
/// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled outside codegen.
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(
        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`.
            if let Some(feat) = to_llvm_features(sess, feature) {
                // All the LLVM features this expands to must be enabled.
                for llvm_feature in feat {
                    let cstr = SmallCStr::new(llvm_feature);
                    // `LLVMRustHasFeature` is moderately expensive. On targets with many
                    // features (e.g. x86) these calls take a non-trivial fraction of runtime
                    // when compiling very small programs.
                    if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } {
                        return false;
                    }
                }
                true
            } else {
                false
            }
        },
    );

    let mut cfg = TargetConfig {
        target_features,
        unstable_target_features,
        has_reliable_f16: true,
        has_reliable_f16_math: true,
        has_reliable_f128: true,
        has_reliable_f128_math: true,
    };

    update_target_reliable_float_cfg(sess, &mut cfg);
    cfg
}

/// Determine whether or not experimental float types are reliable based on known bugs.
fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) {
    let target_arch = &sess.target.arch;
    let target_os = &sess.target.options.os;
    let target_env = &sess.target.options.env;
    let target_abi = &sess.target.options.cfg_abi;
    let target_pointer_width = sess.target.pointer_width;
    let version = get_version();
    let (major, _, _) = version;

    cfg.has_reliable_f16 = match (target_arch, target_os) {
        // Unsupported <https://github.com/llvm/llvm-project/issues/94434> (fixed in llvm22)
        (Arch::Arm64EC, _) if major < 22 => false,
        // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
        (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => {
            false
        }
        // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
        (Arch::CSky, _) if major < 22 => false, // (fixed in llvm22)
        (Arch::PowerPC | Arch::PowerPC64, _) if major < 22 => false, // (fixed in llvm22)
        (Arch::Sparc | Arch::Sparc64, _) if major < 22 => false, // (fixed in llvm22)
        (Arch::Wasm32 | Arch::Wasm64, _) if major < 22 => false, // (fixed in llvm22)
        // `f16` support only requires that symbols converting to and from `f32` are available. We
        // provide these in `compiler-builtins`, so `f16` should be available on all platforms that
        // do not have other ABI issues or LLVM crashes.
        _ => true,
    };

    cfg.has_reliable_f128 = match (target_arch, target_os) {
        // Unsupported https://github.com/llvm/llvm-project/issues/121122
        (Arch::AmdGpu, _) => false,
        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
        (Arch::Arm64EC, _) => false,
        // Selection bug <https://github.com/llvm/llvm-project/issues/95471>. This issue is closed
        // but basic math still does not work.
        (Arch::Nvptx64, _) => false,
        // ABI bugs <https://github.com/rust-lang/rust/issues/125109> et al. (full
        // list at <https://github.com/rust-lang/rust/issues/116909>)
        (Arch::PowerPC | Arch::PowerPC64, _) => false,
        // ABI unsupported  <https://github.com/llvm/llvm-project/issues/41838> (fixed in llvm22)
        (Arch::Sparc, _) if major < 22 => false,
        // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
        (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => {
            false
        }
        // There are no known problems on other platforms, so the only requirement is that symbols
        // are available. `compiler-builtins` provides all symbols required for core `f128`
        // support, so this should work for everything else.
        _ => true,
    };

    // Assume that working `f16` means working `f16` math for most platforms, since
    // operations just go through `f32`.
    cfg.has_reliable_f16_math = cfg.has_reliable_f16;

    cfg.has_reliable_f128_math = match (target_arch, target_os) {
        // LLVM lowers `fp128` math to `long double` symbols even on platforms where
        // `long double` is not IEEE binary128. See
        // <https://github.com/llvm/llvm-project/issues/44744>.
        //
        // This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits
        // (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86`
        // (ld is 80-bit extended precision).
        //
        // musl does not implement the symbols required for f128 math at all.
        _ if *target_env == Env::Musl => false,
        (Arch::X86_64, _) => false,
        (_, Os::Linux) if target_pointer_width == 64 => true,
        _ => false,
    } && cfg.has_reliable_f128;
}

pub(crate) fn print_version() {
    let (major, minor, patch) = get_version();
    println!("LLVM version: {major}.{minor}.{patch}");
}

pub(crate) fn get_version() -> (u32, u32, u32) {
    // Can be called without initializing LLVM
    unsafe {
        (llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch())
    }
}

pub(crate) fn print_passes() {
    // Can be called without initializing LLVM
    unsafe {
        llvm::LLVMRustPrintPasses();
    }
}

fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
    let len = unsafe { llvm::LLVMRustGetTargetFeaturesCount(tm) };
    let mut ret = Vec::with_capacity(len);
    for i in 0..len {
        unsafe {
            let mut feature = ptr::null();
            let mut desc = ptr::null();
            llvm::LLVMRustGetTargetFeature(tm, i, &mut feature, &mut desc);
            if feature.is_null() || desc.is_null() {
                bug!("LLVM returned a `null` target feature string");
            }
            let feature = CStr::from_ptr(feature).to_str().unwrap_or_else(|e| {
                bug!("LLVM returned a non-utf8 feature string: {}", e);
            });
            let desc = CStr::from_ptr(desc).to_str().unwrap_or_else(|e| {
                bug!("LLVM returned a non-utf8 feature string: {}", e);
            });
            ret.push((feature, desc));
        }
    }
    ret
}

pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
    require_inited();
    let tm = create_informational_target_machine(sess, false);
    match req.kind {
        PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
        PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
        _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
    }
}

fn print_target_cpus(sess: &Session, tm: &llvm::TargetMachine, out: &mut String) {
    let cpu_names = llvm::build_string(|s| unsafe {
        llvm::LLVMRustPrintTargetCPUs(&tm, s);
    })
    .unwrap();

    struct Cpu<'a> {
        cpu_name: &'a str,
        remark: String,
    }
    // Compare CPU against current target to label the default.
    let target_cpu = handle_native(&sess.target.cpu);
    let make_remark = |cpu_name| {
        if cpu_name == target_cpu {
            // FIXME(#132514): This prints the LLVM target string, which can be
            // different from the Rust target string. Is that intended?
            let target = &sess.target.llvm_target;
            format!(
                " - This is the default target CPU for the current build target (currently {target})."
            )
        } else {
            "".to_owned()
        }
    };
    let mut cpus = cpu_names
        .lines()
        .filter(|cpu_name| {
            !sess.target.unsupported_cpus.contains(&std::borrow::Cow::Borrowed(*cpu_name))
        })
        .map(|cpu_name| Cpu { cpu_name, remark: make_remark(cpu_name) })
        .collect::<VecDeque<_>>();

    // Only print the "native" entry when host and target are the same arch,
    // since otherwise it could be wrong or misleading.
    // Also do not print it if `requires_consistent_cpu` is set, because in this case
    // "native" would be rejected.
    if sess.host.arch == sess.target.arch && !sess.target.requires_consistent_cpu {
        let host = get_host_cpu_name();
        cpus.push_front(Cpu {
            cpu_name: NATIVE_CPU,
            remark: format!(" - Select the CPU of the current host (currently {host})."),
        });
    }

    let max_name_width = cpus.iter().map(|cpu| cpu.cpu_name.len()).max().unwrap_or(0);
    writeln!(out, "Available CPUs for this target:").unwrap();
    for Cpu { cpu_name, remark } in cpus {
        // Only pad the CPU name if there's a remark to print after it.
        let width = if remark.is_empty() { 0 } else { max_name_width };
        writeln!(out, "    {cpu_name:<width$}{remark}").unwrap();
    }
}

fn print_target_features(sess: &Session, tm: &llvm::TargetMachine, out: &mut String) {
    let mut llvm_target_features = llvm_target_features(tm);
    let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
    let mut rustc_target_features = sess
        .target
        .rust_target_features()
        .iter()
        .filter_map(|(feature, gate, _implied)| {
            if !gate.in_cfg() {
                // Only list (experimentally) supported features.
                return None;
            }
            // 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 desc =
                match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
                    Some(index) => {
                        known_llvm_target_features.insert(llvm_feature);
                        llvm_target_features[index].1
                    }
                    None => "",
                };

            Some((*feature, desc))
        })
        .collect::<Vec<_>>();

    // Since we add this at the end ...
    rustc_target_features.extend_from_slice(&[(
        "crt-static",
        "Enables C Run-time Libraries to be statically linked",
    )]);
    // ... we need to sort the list again.
    rustc_target_features.sort();

    llvm_target_features.retain(|(f, _d)| !known_llvm_target_features.contains(f));

    let max_feature_len = llvm_target_features
        .iter()
        .chain(rustc_target_features.iter())
        .map(|(feature, _desc)| feature.len())
        .max()
        .unwrap_or(0);

    writeln!(out, "Features supported by rustc for this target:").unwrap();
    for (feature, desc) in &rustc_target_features {
        writeln!(out, "    {feature:max_feature_len$} - {desc}.").unwrap();
    }
    writeln!(out, "\nCode-generation features supported by LLVM for this target:").unwrap();
    for (feature, desc) in &llvm_target_features {
        writeln!(out, "    {feature:max_feature_len$} - {desc}.").unwrap();
    }
    if llvm_target_features.is_empty() {
        writeln!(out, "    Target features listing is not supported by this LLVM version.")
            .unwrap();
    }
    writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.").unwrap();
    writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n")
        .unwrap();
    writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],").unwrap();
    writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n").unwrap();
}

/// Returns the host CPU name, according to LLVM.
fn get_host_cpu_name() -> &'static str {
    let mut len = 0;
    // SAFETY: The underlying C++ global function returns a `StringRef` that
    // isn't tied to any particular backing buffer, so it must be 'static.
    let slice: &'static [u8] = unsafe {
        let ptr = llvm::LLVMRustGetHostCPUName(&mut len);
        assert!(!ptr.is_null());
        slice::from_raw_parts(ptr, len)
    };
    str::from_utf8(slice).expect("host CPU name should be UTF-8")
}

/// If the given string is `"native"`, returns the host CPU name according to
/// LLVM. Otherwise, the string is returned as-is.
fn handle_native(cpu_name: &str) -> &str {
    match cpu_name {
        NATIVE_CPU => get_host_cpu_name(),
        _ => cpu_name,
    }
}

pub(crate) fn target_cpu(sess: &Session) -> &str {
    let cpu_name = sess.opts.cg.target_cpu.as_deref().unwrap_or_else(|| &sess.target.cpu);
    handle_native(cpu_name)
}

/// The target features for compiler flags other than `-Ctarget-features`.
fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
    if wants_wasm_eh(sess) && sess.panic_strategy() == PanicStrategy::Unwind {
        features.push("+exception-handling".into());
    }

    target_features::retpoline_features_by_flags(sess, features);
    target_features::sanitizer_features_by_flags(sess, features);

    // -Zfixed-x18
    if sess.opts.unstable_opts.fixed_x18 {
        if sess.target.arch != Arch::AArch64 {
            sess.dcx()
                .emit_fatal(diagnostics::FixedX18InvalidArch { arch: sess.target.arch.desc() });
        } else {
            features.push("+reserve-x18".into());
        }
    }
}

/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
/// `--target` and similar).
///
/// If `for_cfg` is `true` then we are assembling the feature list for the purpose of populating
/// [`rustc_codegen_ssa::TargetConfig`] based on what LLVM actually enables in this configuration.
/// `-Ctarget-feature` should be ignored in that case since it is already processed separately.
pub(crate) fn global_llvm_features(sess: &Session, for_cfg: bool) -> Vec<String> {
    // Features that come earlier are overridden by conflicting features later in the string.
    // Typically we'll want more explicit settings to override the implicit ones, so:
    //
    // * Features from -Ctarget-cpu=*; are overridden by [^1]
    // * Features implied by --target; are overridden by
    // * Features from -Ctarget-feature; are overridden by
    // * function specific features.
    //
    // [^1]: target-cpu=native is handled here, other target-cpu values are handled implicitly
    // through LLVM TargetMachine implementation.
    //
    // FIXME(nagisa): it isn't clear what's the best interaction between features implied by
    // `-Ctarget-cpu` and `--target` are. On one hand, you'd expect CLI arguments to always
    // override anything that's implicit, so e.g. when there's no `--target` flag, features implied
    // the host target are overridden by `-Ctarget-cpu=*`. On the other hand, what about when both
    // `--target` and `-Ctarget-cpu=*` are specified? Both then imply some target features and both
    // flags are specified by the user on the CLI. It isn't as clear-cut which order of precedence
    // should be taken in cases like these.
    let mut features = vec![];

    // -Ctarget-cpu=native
    match sess.opts.cg.target_cpu {
        Some(ref s) if s == NATIVE_CPU => {
            // We have already figured out the actual CPU name with `LLVMRustGetHostCPUName` and set
            // that for LLVM, so the features implied by that CPU name will be available everywhere.
            // However, that is not sufficient: e.g. `skylake` alone is not sufficient to tell if
            // some of the instructions are available or not. So we have to also explicitly ask for
            // the exact set of features available on the host, and enable all of them.
            let features_string = unsafe {
                let ptr = llvm::LLVMGetHostCPUFeatures();
                let features_string = if !ptr.is_null() {
                    CStr::from_ptr(ptr)
                        .to_str()
                        .unwrap_or_else(|e| {
                            bug!("LLVM returned a non-utf8 features string: {}", e);
                        })
                        .to_owned()
                } else {
                    bug!("could not allocate host CPU features, LLVM returned a `null` string");
                };

                llvm::LLVMDisposeMessage(ptr);

                features_string
            };
            if !features_string.is_empty() {
                features.extend(features_string.split(',').map(String::from));
            }
        }
        Some(_) | None => {}
    };

    let mut extend_backend_features = |feature: &str, enable: bool| {
        let enable_disable = if enable { '+' } else { '-' };
        // 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
        // different names when the LLVM name and the Rust name differ.
        let Some(llvm_feature) = to_llvm_features(sess, feature) else { return };

        features.extend(
            std::iter::once(format!("{}{}", enable_disable, llvm_feature.llvm_feature_name)).chain(
                llvm_feature.dependencies.into_iter().filter_map(move |feat| {
                    match (enable, feat) {
                        (_, TargetFeatureFoldStrength::Both(f))
                        | (true, TargetFeatureFoldStrength::EnableOnly(f)) => {
                            Some(format!("{enable_disable}{f}"))
                        }
                        _ => None,
                    }
                }),
            ),
        );
    };

    // Features implied by an implicit or explicit `--target`.
    target_features::target_spec_to_backend_features(sess, &mut extend_backend_features);

    // -Ctarget-features. Skipped for `cfg` as there we parse -Ctarget-features directly instead of
    // going via an LLVM target machine (which avoids accidentally picking up LLVM-level target
    // feature implications that we do not want).
    if !for_cfg {
        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`.
    llvm_features_by_flags(sess, &mut features);

    // `-Zllvm-target-features`, all the way at the end to overwrite everything.
    // Should be picked up by `cfg` (e.g. if someone enables AVX this way).
    for feature in sess.opts.unstable_opts.llvm_target_feature.split(',') {
        if feature.is_empty() {
            continue;
        }
        if feature.starts_with('+') || feature.starts_with('-') {
            features.push(feature.to_owned());
        } else {
            // LLVM seems to silently ignore entries without leading `+`/`-`. Let's emit a warning
            // to avoid confusion. But only emit this warning once, under `for_cfg`.
            if for_cfg {
                sess.dcx().emit_warn(diagnostics::UnknownLlvmTargetFeaturePrefix { feature });
            }
        }
    }

    features
}

pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
    let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
    Some(handle_native(name))
}

pub(crate) fn target_has_mnemonic(sess: &Session, mnemonic: &str) -> bool {
    require_inited();
    let tm = create_informational_target_machine(sess, false);
    let cstr = SmallCStr::new(mnemonic);
    unsafe { llvm::LLVMRustTargetHasMnemonic(tm.raw(), cstr.as_ptr()) }
}
