use std::assert_matches::assert_matches;

use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::mir::operand::OperandValue;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::Instance;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{bug, span_bug};
use rustc_span::{Pos, Span, Symbol, sym};
use rustc_target::asm::*;
use smallvec::SmallVec;
use tracing::debug;

use crate::builder::Builder;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{attributes, llvm};

impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
    fn codegen_inline_asm(
        &mut self,
        template: &[InlineAsmTemplatePiece],
        operands: &[InlineAsmOperandRef<'tcx, Self>],
        options: InlineAsmOptions,
        line_spans: &[Span],
        instance: Instance<'_>,
        dest: Option<Self::BasicBlock>,
        catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>,
    ) {
        let asm_arch = self.tcx.sess.asm_arch.unwrap();

        // Collect the types of output operands
        let mut constraints = vec![];
        let mut clobbers = vec![];
        let mut output_types = vec![];
        let mut op_idx = FxHashMap::default();
        let mut clobbered_x87 = false;
        for (idx, op) in operands.iter().enumerate() {
            match *op {
                InlineAsmOperandRef::Out { reg, late, place } => {
                    let is_target_supported = |reg_class: InlineAsmRegClass| {
                        for &(_, feature) in reg_class.supported_types(asm_arch, true) {
                            if let Some(feature) = feature {
                                if self
                                    .tcx
                                    .asm_target_features(instance.def_id())
                                    .contains(&feature)
                                {
                                    return true;
                                }
                            } else {
                                // Register class is unconditionally supported
                                return true;
                            }
                        }
                        false
                    };

                    let mut layout = None;
                    let ty = if let Some(ref place) = place {
                        layout = Some(&place.layout);
                        llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout, instance)
                    } else if matches!(
                        reg.reg_class(),
                        InlineAsmRegClass::X86(
                            X86InlineAsmRegClass::mmx_reg | X86InlineAsmRegClass::x87_reg
                        )
                    ) {
                        // Special handling for x87/mmx registers: we always
                        // clobber the whole set if one register is marked as
                        // clobbered. This is due to the way LLVM handles the
                        // FP stack in inline assembly.
                        if !clobbered_x87 {
                            clobbered_x87 = true;
                            clobbers.push("~{st}".to_string());
                            for i in 1..=7 {
                                clobbers.push(format!("~{{st({})}}", i));
                            }
                        }
                        continue;
                    } else if !is_target_supported(reg.reg_class())
                        || reg.reg_class().is_clobber_only(asm_arch, true)
                    {
                        // We turn discarded outputs into clobber constraints
                        // if the target feature needed by the register class is
                        // disabled. This is necessary otherwise LLVM will try
                        // to actually allocate a register for the dummy output.
                        assert_matches!(reg, InlineAsmRegOrRegClass::Reg(_));
                        clobbers.push(format!("~{}", reg_to_llvm(reg, None)));
                        continue;
                    } else {
                        // If the output is discarded, we don't really care what
                        // type is used. We're just using this to tell LLVM to
                        // reserve the register.
                        dummy_output_type(self.cx, reg.reg_class())
                    };
                    output_types.push(ty);
                    op_idx.insert(idx, constraints.len());
                    let prefix = if late { "=" } else { "=&" };
                    constraints.push(format!("{}{}", prefix, reg_to_llvm(reg, layout)));
                }
                InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => {
                    let layout = if let Some(ref out_place) = out_place {
                        &out_place.layout
                    } else {
                        // LLVM required tied operands to have the same type,
                        // so we just use the type of the input.
                        &in_value.layout
                    };
                    let ty = llvm_fixup_output_type(self.cx, reg.reg_class(), layout, instance);
                    output_types.push(ty);
                    op_idx.insert(idx, constraints.len());
                    let prefix = if late { "=" } else { "=&" };
                    constraints.push(format!("{}{}", prefix, reg_to_llvm(reg, Some(layout))));
                }
                _ => {}
            }
        }

        // Collect input operands
        let mut inputs = vec![];
        for (idx, op) in operands.iter().enumerate() {
            match *op {
                InlineAsmOperandRef::In { reg, value } => {
                    let llval = llvm_fixup_input(
                        self,
                        value.immediate(),
                        reg.reg_class(),
                        &value.layout,
                        instance,
                    );
                    inputs.push(llval);
                    op_idx.insert(idx, constraints.len());
                    constraints.push(reg_to_llvm(reg, Some(&value.layout)));
                }
                InlineAsmOperandRef::InOut { reg, late, in_value, out_place: _ } => {
                    let value = llvm_fixup_input(
                        self,
                        in_value.immediate(),
                        reg.reg_class(),
                        &in_value.layout,
                        instance,
                    );
                    inputs.push(value);

                    // In the case of fixed registers, we have the choice of
                    // either using a tied operand or duplicating the constraint.
                    // We prefer the latter because it matches the behavior of
                    // Clang.
                    if late && matches!(reg, InlineAsmRegOrRegClass::Reg(_)) {
                        constraints.push(reg_to_llvm(reg, Some(&in_value.layout)));
                    } else {
                        constraints.push(format!("{}", op_idx[&idx]));
                    }
                }
                InlineAsmOperandRef::SymFn { instance } => {
                    inputs.push(self.cx.get_fn(instance));
                    op_idx.insert(idx, constraints.len());
                    constraints.push("s".to_string());
                }
                InlineAsmOperandRef::SymStatic { def_id } => {
                    inputs.push(self.cx.get_static(def_id));
                    op_idx.insert(idx, constraints.len());
                    constraints.push("s".to_string());
                }
                _ => {}
            }
        }

        // Build the template string
        let mut labels = vec![];
        let mut template_str = String::new();
        for piece in template {
            match *piece {
                InlineAsmTemplatePiece::String(ref s) => {
                    if s.contains('$') {
                        for c in s.chars() {
                            if c == '$' {
                                template_str.push_str("$$");
                            } else {
                                template_str.push(c);
                            }
                        }
                    } else {
                        template_str.push_str(s)
                    }
                }
                InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span: _ } => {
                    match operands[operand_idx] {
                        InlineAsmOperandRef::In { reg, .. }
                        | InlineAsmOperandRef::Out { reg, .. }
                        | InlineAsmOperandRef::InOut { reg, .. } => {
                            let modifier = modifier_to_llvm(asm_arch, reg.reg_class(), modifier);
                            if let Some(modifier) = modifier {
                                template_str.push_str(&format!(
                                    "${{{}:{}}}",
                                    op_idx[&operand_idx], modifier
                                ));
                            } else {
                                template_str.push_str(&format!("${{{}}}", op_idx[&operand_idx]));
                            }
                        }
                        InlineAsmOperandRef::Const { ref string } => {
                            // Const operands get injected directly into the template
                            template_str.push_str(string);
                        }
                        InlineAsmOperandRef::SymFn { .. }
                        | InlineAsmOperandRef::SymStatic { .. } => {
                            // Only emit the raw symbol name
                            template_str.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
                        }
                        InlineAsmOperandRef::Label { label } => {
                            template_str.push_str(&format!("${{{}:l}}", constraints.len()));
                            constraints.push("!i".to_owned());
                            labels.push(label);
                        }
                    }
                }
            }
        }

        constraints.append(&mut clobbers);
        if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) {
            match asm_arch {
                InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC | InlineAsmArch::Arm => {
                    constraints.push("~{cc}".to_string());
                }
                InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
                    constraints.extend_from_slice(&[
                        "~{dirflag}".to_string(),
                        "~{fpsr}".to_string(),
                        "~{flags}".to_string(),
                    ]);
                }
                InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
                    constraints.extend_from_slice(&[
                        "~{vtype}".to_string(),
                        "~{vl}".to_string(),
                        "~{vxsat}".to_string(),
                        "~{vxrm}".to_string(),
                    ]);
                }
                InlineAsmArch::Avr => {
                    constraints.push("~{sreg}".to_string());
                }
                InlineAsmArch::Nvptx64 => {}
                InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
                InlineAsmArch::Hexagon => {}
                InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
                    constraints.extend_from_slice(&[
                        "~{$fcc0}".to_string(),
                        "~{$fcc1}".to_string(),
                        "~{$fcc2}".to_string(),
                        "~{$fcc3}".to_string(),
                        "~{$fcc4}".to_string(),
                        "~{$fcc5}".to_string(),
                        "~{$fcc6}".to_string(),
                        "~{$fcc7}".to_string(),
                    ]);
                }
                InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
                InlineAsmArch::S390x => {
                    constraints.push("~{cc}".to_string());
                }
                InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
                    // In LLVM, ~{icc} represents icc and xcc in 64-bit code.
                    // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.td#L64
                    constraints.push("~{icc}".to_string());
                    constraints.push("~{fcc0}".to_string());
                    constraints.push("~{fcc1}".to_string());
                    constraints.push("~{fcc2}".to_string());
                    constraints.push("~{fcc3}".to_string());
                }
                InlineAsmArch::SpirV => {}
                InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
                InlineAsmArch::Bpf => {}
                InlineAsmArch::Msp430 => {
                    constraints.push("~{sr}".to_string());
                }
                InlineAsmArch::M68k => {
                    constraints.push("~{ccr}".to_string());
                }
                InlineAsmArch::CSKY => {
                    constraints.push("~{psr}".to_string());
                }
            }
        }
        if !options.contains(InlineAsmOptions::NOMEM) {
            // This is actually ignored by LLVM, but it's probably best to keep
            // it just in case. LLVM instead uses the ReadOnly/ReadNone
            // attributes on the call instruction to optimize.
            constraints.push("~{memory}".to_string());
        }
        let volatile = !options.contains(InlineAsmOptions::PURE);
        let alignstack = !options.contains(InlineAsmOptions::NOSTACK);
        let output_type = match &output_types[..] {
            [] => self.type_void(),
            [ty] => ty,
            tys => self.type_struct(tys, false),
        };
        let dialect = match asm_arch {
            InlineAsmArch::X86 | InlineAsmArch::X86_64
                if !options.contains(InlineAsmOptions::ATT_SYNTAX) =>
            {
                llvm::AsmDialect::Intel
            }
            _ => llvm::AsmDialect::Att,
        };
        let result = inline_asm_call(
            self,
            &template_str,
            &constraints.join(","),
            &inputs,
            output_type,
            &labels,
            volatile,
            alignstack,
            dialect,
            line_spans,
            options.contains(InlineAsmOptions::MAY_UNWIND),
            dest,
            catch_funclet,
        )
        .unwrap_or_else(|| span_bug!(line_spans[0], "LLVM asm constraint validation failed"));

        let mut attrs = SmallVec::<[_; 2]>::new();
        if options.contains(InlineAsmOptions::PURE) {
            if options.contains(InlineAsmOptions::NOMEM) {
                attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx));
            } else if options.contains(InlineAsmOptions::READONLY) {
                attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx));
            }
            attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
        } else if options.contains(InlineAsmOptions::NOMEM) {
            attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
        } else {
            // LLVM doesn't have an attribute to represent ReadOnly + SideEffect
        }
        attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });

        // Write results to outputs. We need to do this for all possible control flow.
        //
        // Note that `dest` maybe populated with unreachable_block when asm goto with outputs
        // is used (because we need to codegen callbr which always needs a destination), so
        // here we use the NORETURN option to determine if `dest` should be used.
        for block in (if options.contains(InlineAsmOptions::NORETURN) { None } else { Some(dest) })
            .into_iter()
            .chain(labels.iter().copied().map(Some))
        {
            if let Some(block) = block {
                self.switch_to_block(block);
            }

            for (idx, op) in operands.iter().enumerate() {
                if let InlineAsmOperandRef::Out { reg, place: Some(place), .. }
                | InlineAsmOperandRef::InOut { reg, out_place: Some(place), .. } = *op
                {
                    let value = if output_types.len() == 1 {
                        result
                    } else {
                        self.extract_value(result, op_idx[&idx] as u64)
                    };
                    let value =
                        llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance);
                    OperandValue::Immediate(value).store(self, place);
                }
            }
        }
    }
}

impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
    fn codegen_global_asm(
        &mut self,
        template: &[InlineAsmTemplatePiece],
        operands: &[GlobalAsmOperandRef<'tcx>],
        options: InlineAsmOptions,
        _line_spans: &[Span],
    ) {
        let asm_arch = self.tcx.sess.asm_arch.unwrap();

        // Build the template string
        let mut template_str = String::new();

        // On X86 platforms there are two assembly syntaxes. Rust uses intel by default,
        // but AT&T can be specified explicitly.
        if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) {
            if options.contains(InlineAsmOptions::ATT_SYNTAX) {
                template_str.push_str(".att_syntax\n")
            } else {
                template_str.push_str(".intel_syntax\n")
            }
        }

        for piece in template {
            match *piece {
                InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
                InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => {
                    match operands[operand_idx] {
                        GlobalAsmOperandRef::Const { ref string } => {
                            // Const operands get injected directly into the
                            // template. Note that we don't need to escape $
                            // here unlike normal inline assembly.
                            template_str.push_str(string);
                        }
                        GlobalAsmOperandRef::SymFn { instance } => {
                            let llval = self.get_fn(instance);
                            self.add_compiler_used_global(llval);
                            let symbol = llvm::build_string(|s| unsafe {
                                llvm::LLVMRustGetMangledName(llval, s);
                            })
                            .expect("symbol is not valid UTF-8");
                            template_str.push_str(&symbol);
                        }
                        GlobalAsmOperandRef::SymStatic { def_id } => {
                            let llval = self
                                .renamed_statics
                                .borrow()
                                .get(&def_id)
                                .copied()
                                .unwrap_or_else(|| self.get_static(def_id));
                            self.add_compiler_used_global(llval);
                            let symbol = llvm::build_string(|s| unsafe {
                                llvm::LLVMRustGetMangledName(llval, s);
                            })
                            .expect("symbol is not valid UTF-8");
                            template_str.push_str(&symbol);
                        }
                    }
                }
            }
        }

        // Just to play it safe, if intel was used, reset the assembly syntax to att.
        if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64)
            && !options.contains(InlineAsmOptions::ATT_SYNTAX)
        {
            template_str.push_str("\n.att_syntax\n");
        }

        llvm::append_module_inline_asm(self.llmod, template_str.as_bytes());
    }

    fn mangled_name(&self, instance: Instance<'tcx>) -> String {
        let llval = self.get_fn(instance);
        llvm::build_string(|s| unsafe {
            llvm::LLVMRustGetMangledName(llval, s);
        })
        .expect("symbol is not valid UTF-8")
    }
}

pub(crate) fn inline_asm_call<'ll>(
    bx: &mut Builder<'_, 'll, '_>,
    asm: &str,
    cons: &str,
    inputs: &[&'ll Value],
    output: &'ll llvm::Type,
    labels: &[&'ll llvm::BasicBlock],
    volatile: bool,
    alignstack: bool,
    dia: llvm::AsmDialect,
    line_spans: &[Span],
    unwind: bool,
    dest: Option<&'ll llvm::BasicBlock>,
    catch_funclet: Option<(&'ll llvm::BasicBlock, Option<&Funclet<'ll>>)>,
) -> Option<&'ll Value> {
    let volatile = if volatile { llvm::True } else { llvm::False };
    let alignstack = if alignstack { llvm::True } else { llvm::False };
    let can_throw = if unwind { llvm::True } else { llvm::False };

    let argtys = inputs
        .iter()
        .map(|v| {
            debug!("Asm Input Type: {:?}", *v);
            bx.cx.val_ty(*v)
        })
        .collect::<Vec<_>>();

    debug!("Asm Output Type: {:?}", output);
    let fty = bx.cx.type_func(&argtys, output);

    // Ask LLVM to verify that the constraints are well-formed.
    let constraints_ok = unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr(), cons.len()) };
    debug!("constraint verification result: {:?}", constraints_ok);
    if !constraints_ok {
        // LLVM has detected an issue with our constraints, so bail out.
        return None;
    }

    let v = unsafe {
        llvm::LLVMGetInlineAsm(
            fty,
            asm.as_ptr(),
            asm.len(),
            cons.as_ptr(),
            cons.len(),
            volatile,
            alignstack,
            dia,
            can_throw,
        )
    };

    let call = if !labels.is_empty() {
        assert!(catch_funclet.is_none());
        bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
    } else if let Some((catch, funclet)) = catch_funclet {
        bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
    } else {
        bx.call(fty, None, None, v, inputs, None, None)
    };

    // Store mark in a metadata node so we can map LLVM errors
    // back to source locations. See #17552.
    let key = "srcloc";
    let kind = bx.get_md_kind_id(key);

    // `srcloc` contains one 64-bit integer for each line of assembly code,
    // where the lower 32 bits hold the lo byte position and the upper 32 bits
    // hold the hi byte position.
    let mut srcloc = vec![];
    if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
        // LLVM inserts an extra line to add the ".intel_syntax", so add
        // a dummy srcloc entry for it.
        //
        // Don't do this if we only have 1 line span since that may be
        // due to the asm template string coming from a macro. LLVM will
        // default to the first srcloc for lines that don't have an
        // associated srcloc.
        srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
    }
    srcloc.extend(line_spans.iter().map(|span| {
        llvm::LLVMValueAsMetadata(
            bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
        )
    }));
    let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
    let md = bx.get_metadata_value(md);
    llvm::LLVMSetMetadata(call, kind, md);

    Some(call)
}

/// If the register is an xmm/ymm/zmm register then return its index.
fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
    use X86InlineAsmReg::*;
    match reg {
        InlineAsmReg::X86(reg) if reg as u32 >= xmm0 as u32 && reg as u32 <= xmm15 as u32 => {
            Some(reg as u32 - xmm0 as u32)
        }
        InlineAsmReg::X86(reg) if reg as u32 >= ymm0 as u32 && reg as u32 <= ymm15 as u32 => {
            Some(reg as u32 - ymm0 as u32)
        }
        InlineAsmReg::X86(reg) if reg as u32 >= zmm0 as u32 && reg as u32 <= zmm31 as u32 => {
            Some(reg as u32 - zmm0 as u32)
        }
        _ => None,
    }
}

/// If the register is an AArch64 integer register then return its index.
fn a64_reg_index(reg: InlineAsmReg) -> Option<u32> {
    match reg {
        InlineAsmReg::AArch64(r) => r.reg_index(),
        _ => None,
    }
}

/// If the register is an AArch64 vector register then return its index.
fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
    match reg {
        InlineAsmReg::AArch64(reg) => reg.vreg_index(),
        _ => None,
    }
}

/// Converts a register class to an LLVM constraint code.
fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> String {
    use InlineAsmRegClass::*;
    match reg {
        // For vector registers LLVM wants the register name to match the type size.
        InlineAsmRegOrRegClass::Reg(reg) => {
            if let Some(idx) = xmm_reg_index(reg) {
                let class = if let Some(layout) = layout {
                    match layout.size.bytes() {
                        64 => 'z',
                        32 => 'y',
                        _ => 'x',
                    }
                } else {
                    // We use f32 as the type for discarded outputs
                    'x'
                };
                format!("{{{}mm{}}}", class, idx)
            } else if let Some(idx) = a64_reg_index(reg) {
                let class = if let Some(layout) = layout {
                    match layout.size.bytes() {
                        8 => 'x',
                        _ => 'w',
                    }
                } else {
                    // We use i32 as the type for discarded outputs
                    'w'
                };
                if class == 'x' && reg == InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) {
                    // LLVM doesn't recognize x30. use lr instead.
                    "{lr}".to_string()
                } else {
                    format!("{{{}{}}}", class, idx)
                }
            } else if let Some(idx) = a64_vreg_index(reg) {
                let class = if let Some(layout) = layout {
                    match layout.size.bytes() {
                        16 => 'q',
                        8 => 'd',
                        4 => 's',
                        2 => 'h',
                        1 => 'd', // We fixup i8 to i8x8
                        _ => unreachable!(),
                    }
                } else {
                    // We use i64x2 as the type for discarded outputs
                    'q'
                };
                format!("{{{}{}}}", class, idx)
            } else if reg == InlineAsmReg::Arm(ArmInlineAsmReg::r14) {
                // LLVM doesn't recognize r14
                "{lr}".to_string()
            } else {
                format!("{{{}}}", reg.name())
            }
        }
        // The constraints can be retrieved from
        // https://llvm.org/docs/LangRef.html#supported-constraint-code-list
        InlineAsmRegOrRegClass::RegClass(reg) => match reg {
            AArch64(AArch64InlineAsmRegClass::reg) => "r",
            AArch64(AArch64InlineAsmRegClass::vreg) => "w",
            AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
            AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
            Arm(ArmInlineAsmRegClass::reg) => "r",
            Arm(ArmInlineAsmRegClass::sreg)
            | Arm(ArmInlineAsmRegClass::dreg_low16)
            | Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
            Arm(ArmInlineAsmRegClass::sreg_low16)
            | Arm(ArmInlineAsmRegClass::dreg_low8)
            | Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
            Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w",
            Hexagon(HexagonInlineAsmRegClass::reg) => "r",
            Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"),
            LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
            LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
            Mips(MipsInlineAsmRegClass::reg) => "r",
            Mips(MipsInlineAsmRegClass::freg) => "f",
            Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
            Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
            Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
            PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
            PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
            PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
            PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
            PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
                unreachable!("clobber-only")
            }
            RiscV(RiscVInlineAsmRegClass::reg) => "r",
            RiscV(RiscVInlineAsmRegClass::freg) => "f",
            RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
            X86(X86InlineAsmRegClass::reg) => "r",
            X86(X86InlineAsmRegClass::reg_abcd) => "Q",
            X86(X86InlineAsmRegClass::reg_byte) => "q",
            X86(X86InlineAsmRegClass::xmm_reg) | X86(X86InlineAsmRegClass::ymm_reg) => "x",
            X86(X86InlineAsmRegClass::zmm_reg) => "v",
            X86(X86InlineAsmRegClass::kreg) => "^Yk",
            X86(
                X86InlineAsmRegClass::x87_reg
                | X86InlineAsmRegClass::mmx_reg
                | X86InlineAsmRegClass::kreg0
                | X86InlineAsmRegClass::tmm_reg,
            ) => unreachable!("clobber-only"),
            Wasm(WasmInlineAsmRegClass::local) => "r",
            Bpf(BpfInlineAsmRegClass::reg) => "r",
            Bpf(BpfInlineAsmRegClass::wreg) => "w",
            Avr(AvrInlineAsmRegClass::reg) => "r",
            Avr(AvrInlineAsmRegClass::reg_upper) => "d",
            Avr(AvrInlineAsmRegClass::reg_pair) => "r",
            Avr(AvrInlineAsmRegClass::reg_iw) => "w",
            Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
            S390x(S390xInlineAsmRegClass::reg) => "r",
            S390x(S390xInlineAsmRegClass::reg_addr) => "a",
            S390x(S390xInlineAsmRegClass::freg) => "f",
            S390x(S390xInlineAsmRegClass::vreg) => "v",
            S390x(S390xInlineAsmRegClass::areg) => {
                unreachable!("clobber-only")
            }
            Sparc(SparcInlineAsmRegClass::reg) => "r",
            Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
            Msp430(Msp430InlineAsmRegClass::reg) => "r",
            M68k(M68kInlineAsmRegClass::reg) => "r",
            M68k(M68kInlineAsmRegClass::reg_addr) => "a",
            M68k(M68kInlineAsmRegClass::reg_data) => "d",
            CSKY(CSKYInlineAsmRegClass::reg) => "r",
            CSKY(CSKYInlineAsmRegClass::freg) => "f",
            SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
            Err => unreachable!(),
        }
        .to_string(),
    }
}

/// Converts a modifier into LLVM's equivalent modifier.
fn modifier_to_llvm(
    arch: InlineAsmArch,
    reg: InlineAsmRegClass,
    modifier: Option<char>,
) -> Option<char> {
    use InlineAsmRegClass::*;
    // The modifiers can be retrieved from
    // https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
    match reg {
        AArch64(AArch64InlineAsmRegClass::reg) => modifier,
        AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
            if modifier == Some('v') {
                None
            } else {
                modifier
            }
        }
        AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
        Arm(ArmInlineAsmRegClass::reg) => None,
        Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => None,
        Arm(ArmInlineAsmRegClass::dreg)
        | Arm(ArmInlineAsmRegClass::dreg_low16)
        | Arm(ArmInlineAsmRegClass::dreg_low8) => Some('P'),
        Arm(ArmInlineAsmRegClass::qreg)
        | Arm(ArmInlineAsmRegClass::qreg_low8)
        | Arm(ArmInlineAsmRegClass::qreg_low4) => {
            if modifier.is_none() {
                Some('q')
            } else {
                modifier
            }
        }
        Hexagon(_) => None,
        LoongArch(_) => None,
        Mips(_) => None,
        Nvptx(_) => None,
        PowerPC(_) => None,
        RiscV(RiscVInlineAsmRegClass::reg) | RiscV(RiscVInlineAsmRegClass::freg) => None,
        RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
        X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => match modifier {
            None if arch == InlineAsmArch::X86_64 => Some('q'),
            None => Some('k'),
            Some('l') => Some('b'),
            Some('h') => Some('h'),
            Some('x') => Some('w'),
            Some('e') => Some('k'),
            Some('r') => Some('q'),
            _ => unreachable!(),
        },
        X86(X86InlineAsmRegClass::reg_byte) => None,
        X86(reg @ X86InlineAsmRegClass::xmm_reg)
        | X86(reg @ X86InlineAsmRegClass::ymm_reg)
        | X86(reg @ X86InlineAsmRegClass::zmm_reg) => match (reg, modifier) {
            (X86InlineAsmRegClass::xmm_reg, None) => Some('x'),
            (X86InlineAsmRegClass::ymm_reg, None) => Some('t'),
            (X86InlineAsmRegClass::zmm_reg, None) => Some('g'),
            (_, Some('x')) => Some('x'),
            (_, Some('y')) => Some('t'),
            (_, Some('z')) => Some('g'),
            _ => unreachable!(),
        },
        X86(X86InlineAsmRegClass::kreg) => None,
        X86(
            X86InlineAsmRegClass::x87_reg
            | X86InlineAsmRegClass::mmx_reg
            | X86InlineAsmRegClass::kreg0
            | X86InlineAsmRegClass::tmm_reg,
        ) => unreachable!("clobber-only"),
        Wasm(WasmInlineAsmRegClass::local) => None,
        Bpf(_) => None,
        Avr(AvrInlineAsmRegClass::reg_pair)
        | Avr(AvrInlineAsmRegClass::reg_iw)
        | Avr(AvrInlineAsmRegClass::reg_ptr) => match modifier {
            Some('h') => Some('B'),
            Some('l') => Some('A'),
            _ => None,
        },
        Avr(_) => None,
        S390x(_) => None,
        Sparc(_) => None,
        Msp430(_) => None,
        SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
        M68k(_) => None,
        CSKY(_) => None,
        Err => unreachable!(),
    }
}

/// Type to use for outputs that are discarded. It doesn't really matter what
/// the type is, as long as it is valid for the constraint code.
fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'ll Type {
    use InlineAsmRegClass::*;
    match reg {
        AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
        AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
            cx.type_vector(cx.type_i64(), 2)
        }
        AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
        Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
        Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
        Arm(ArmInlineAsmRegClass::dreg)
        | Arm(ArmInlineAsmRegClass::dreg_low16)
        | Arm(ArmInlineAsmRegClass::dreg_low8) => cx.type_f64(),
        Arm(ArmInlineAsmRegClass::qreg)
        | Arm(ArmInlineAsmRegClass::qreg_low8)
        | Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2),
        Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
        Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"),
        LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
        LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
        Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
        Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
        Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
        Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
        Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
        PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
        PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
        PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
        PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
        PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
            unreachable!("clobber-only")
        }
        RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
        RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
        RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
        X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(),
        X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(),
        X86(X86InlineAsmRegClass::xmm_reg)
        | X86(X86InlineAsmRegClass::ymm_reg)
        | X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
        X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
        X86(
            X86InlineAsmRegClass::x87_reg
            | X86InlineAsmRegClass::mmx_reg
            | X86InlineAsmRegClass::kreg0
            | X86InlineAsmRegClass::tmm_reg,
        ) => unreachable!("clobber-only"),
        Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
        Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
        Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
        Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
        Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(),
        Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(),
        Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(),
        Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
        S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
        S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
        S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2),
        S390x(S390xInlineAsmRegClass::areg) => {
            unreachable!("clobber-only")
        }
        Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),
        Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
        Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
        M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
        M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
        M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
        CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
        CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
        SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
        Err => unreachable!(),
    }
}

/// Helper function to get the LLVM type for a Scalar. Pointers are returned as
/// the equivalent integer type.
fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Type {
    let dl = &cx.tcx.data_layout;
    match scalar.primitive() {
        Primitive::Int(Integer::I8, _) => cx.type_i8(),
        Primitive::Int(Integer::I16, _) => cx.type_i16(),
        Primitive::Int(Integer::I32, _) => cx.type_i32(),
        Primitive::Int(Integer::I64, _) => cx.type_i64(),
        Primitive::Float(Float::F16) => cx.type_f16(),
        Primitive::Float(Float::F32) => cx.type_f32(),
        Primitive::Float(Float::F64) => cx.type_f64(),
        Primitive::Float(Float::F128) => cx.type_f128(),
        // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
        Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
        _ => unreachable!(),
    }
}

fn any_target_feature_enabled(
    cx: &CodegenCx<'_, '_>,
    instance: Instance<'_>,
    features: &[Symbol],
) -> bool {
    let enabled = cx.tcx.asm_target_features(instance.def_id());
    features.iter().any(|feat| enabled.contains(feat))
}

/// Fix up an input value to work around LLVM bugs.
fn llvm_fixup_input<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    mut value: &'ll Value,
    reg: InlineAsmRegClass,
    layout: &TyAndLayout<'tcx>,
    instance: Instance<'_>,
) -> &'ll Value {
    use InlineAsmRegClass::*;
    let dl = &bx.tcx.data_layout;
    match (reg, layout.backend_repr) {
        (AArch64(AArch64InlineAsmRegClass::vreg), BackendRepr::Scalar(s)) => {
            if let Primitive::Int(Integer::I8, _) = s.primitive() {
                let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
                bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
            } else {
                value
            }
        }
        (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Scalar(s))
            if s.primitive() != Primitive::Float(Float::F128) =>
        {
            let elem_ty = llvm_asm_scalar_type(bx.cx, s);
            let count = 16 / layout.size.bytes();
            let vec_ty = bx.cx.type_vector(elem_ty, count);
            // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
            if let Primitive::Pointer(_) = s.primitive() {
                let t = bx.type_from_integer(dl.ptr_sized_integer());
                value = bx.ptrtoint(value, t);
            }
            bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
        }
        (
            AArch64(AArch64InlineAsmRegClass::vreg_low16),
            BackendRepr::SimdVector { element, count },
        ) if layout.size.bytes() == 8 => {
            let elem_ty = llvm_asm_scalar_type(bx.cx, element);
            let vec_ty = bx.cx.type_vector(elem_ty, count);
            let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect();
            bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
        }
        (X86(X86InlineAsmRegClass::reg_abcd), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            bx.bitcast(value, bx.cx.type_i64())
        }
        (
            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
            BackendRepr::SimdVector { .. },
        ) if layout.size.bytes() == 64 => bx.bitcast(value, bx.cx.type_vector(bx.cx.type_f64(), 8)),
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if bx.sess().asm_arch == Some(InlineAsmArch::X86)
            && s.primitive() == Primitive::Float(Float::F128) =>
        {
            bx.bitcast(value, bx.type_vector(bx.type_i32(), 4))
        }
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if s.primitive() == Primitive::Float(Float::F16) => {
            let value = bx.insert_element(
                bx.const_undef(bx.type_vector(bx.type_f16(), 8)),
                value,
                bx.const_usize(0),
            );
            bx.bitcast(value, bx.type_vector(bx.type_i16(), 8))
        }
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::SimdVector { element, count: count @ (8 | 16) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
        }
        (
            Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I32, _) = s.primitive() {
                bx.bitcast(value, bx.cx.type_f32())
            } else {
                value
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16,
            ),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I64, _) = s.primitive() {
                bx.bitcast(value, bx.cx.type_f64())
            } else {
                value
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16
                | ArmInlineAsmRegClass::qreg
                | ArmInlineAsmRegClass::qreg_low4
                | ArmInlineAsmRegClass::qreg_low8,
            ),
            BackendRepr::SimdVector { element, count: count @ (4 | 8) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
        }
        (LoongArch(LoongArchInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16) =>
        {
            // Smaller floats are always "NaN-boxed" inside larger floats on LoongArch.
            let value = bx.bitcast(value, bx.type_i16());
            let value = bx.zext(value, bx.type_i32());
            let value = bx.or(value, bx.const_u32(0xFFFF_0000));
            bx.bitcast(value, bx.type_f32())
        }
        (Mips(MipsInlineAsmRegClass::reg), BackendRepr::Scalar(s)) => {
            match s.primitive() {
                // MIPS only supports register-length arithmetics.
                Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
                Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_i32()),
                Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_i64()),
                _ => value,
            }
        }
        (RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16)
                && !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
        {
            // Smaller floats are always "NaN-boxed" inside larger floats on RISC-V.
            let value = bx.bitcast(value, bx.type_i16());
            let value = bx.zext(value, bx.type_i32());
            let value = bx.or(value, bx.const_u32(0xFFFF_0000));
            bx.bitcast(value, bx.type_f32())
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F32) =>
        {
            let value = bx.insert_element(
                bx.const_undef(bx.type_vector(bx.type_f32(), 4)),
                value,
                bx.const_usize(0),
            );
            bx.bitcast(value, bx.type_vector(bx.type_f32(), 4))
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            let value = bx.insert_element(
                bx.const_undef(bx.type_vector(bx.type_f64(), 2)),
                value,
                bx.const_usize(0),
            );
            bx.bitcast(value, bx.type_vector(bx.type_f64(), 2))
        }
        _ => value,
    }
}

/// Fix up an output value to work around LLVM bugs.
fn llvm_fixup_output<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    mut value: &'ll Value,
    reg: InlineAsmRegClass,
    layout: &TyAndLayout<'tcx>,
    instance: Instance<'_>,
) -> &'ll Value {
    use InlineAsmRegClass::*;
    match (reg, layout.backend_repr) {
        (AArch64(AArch64InlineAsmRegClass::vreg), BackendRepr::Scalar(s)) => {
            if let Primitive::Int(Integer::I8, _) = s.primitive() {
                bx.extract_element(value, bx.const_i32(0))
            } else {
                value
            }
        }
        (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Scalar(s))
            if s.primitive() != Primitive::Float(Float::F128) =>
        {
            value = bx.extract_element(value, bx.const_i32(0));
            if let Primitive::Pointer(_) = s.primitive() {
                value = bx.inttoptr(value, layout.llvm_type(bx.cx));
            }
            value
        }
        (
            AArch64(AArch64InlineAsmRegClass::vreg_low16),
            BackendRepr::SimdVector { element, count },
        ) if layout.size.bytes() == 8 => {
            let elem_ty = llvm_asm_scalar_type(bx.cx, element);
            let vec_ty = bx.cx.type_vector(elem_ty, count * 2);
            let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect();
            bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
        }
        (X86(X86InlineAsmRegClass::reg_abcd), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            bx.bitcast(value, bx.cx.type_f64())
        }
        (
            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
            BackendRepr::SimdVector { .. },
        ) if layout.size.bytes() == 64 => bx.bitcast(value, layout.llvm_type(bx.cx)),
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if bx.sess().asm_arch == Some(InlineAsmArch::X86)
            && s.primitive() == Primitive::Float(Float::F128) =>
        {
            bx.bitcast(value, bx.type_f128())
        }
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if s.primitive() == Primitive::Float(Float::F16) => {
            let value = bx.bitcast(value, bx.type_vector(bx.type_f16(), 8));
            bx.extract_element(value, bx.const_usize(0))
        }
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::SimdVector { element, count: count @ (8 | 16) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
        }
        (
            Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I32, _) = s.primitive() {
                bx.bitcast(value, bx.cx.type_i32())
            } else {
                value
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16,
            ),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I64, _) = s.primitive() {
                bx.bitcast(value, bx.cx.type_i64())
            } else {
                value
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16
                | ArmInlineAsmRegClass::qreg
                | ArmInlineAsmRegClass::qreg_low4
                | ArmInlineAsmRegClass::qreg_low8,
            ),
            BackendRepr::SimdVector { element, count: count @ (4 | 8) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
        }
        (LoongArch(LoongArchInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16) =>
        {
            let value = bx.bitcast(value, bx.type_i32());
            let value = bx.trunc(value, bx.type_i16());
            bx.bitcast(value, bx.type_f16())
        }
        (Mips(MipsInlineAsmRegClass::reg), BackendRepr::Scalar(s)) => {
            match s.primitive() {
                // MIPS only supports register-length arithmetics.
                Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
                Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
                Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_f32()),
                Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_f64()),
                _ => value,
            }
        }
        (RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16)
                && !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
        {
            let value = bx.bitcast(value, bx.type_i32());
            let value = bx.trunc(value, bx.type_i16());
            bx.bitcast(value, bx.type_f16())
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F32) =>
        {
            let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4));
            bx.extract_element(value, bx.const_usize(0))
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2));
            bx.extract_element(value, bx.const_usize(0))
        }
        _ => value,
    }
}

/// Output type to use for llvm_fixup_output.
fn llvm_fixup_output_type<'ll, 'tcx>(
    cx: &CodegenCx<'ll, 'tcx>,
    reg: InlineAsmRegClass,
    layout: &TyAndLayout<'tcx>,
    instance: Instance<'_>,
) -> &'ll Type {
    use InlineAsmRegClass::*;
    match (reg, layout.backend_repr) {
        (AArch64(AArch64InlineAsmRegClass::vreg), BackendRepr::Scalar(s)) => {
            if let Primitive::Int(Integer::I8, _) = s.primitive() {
                cx.type_vector(cx.type_i8(), 8)
            } else {
                layout.llvm_type(cx)
            }
        }
        (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Scalar(s))
            if s.primitive() != Primitive::Float(Float::F128) =>
        {
            let elem_ty = llvm_asm_scalar_type(cx, s);
            let count = 16 / layout.size.bytes();
            cx.type_vector(elem_ty, count)
        }
        (
            AArch64(AArch64InlineAsmRegClass::vreg_low16),
            BackendRepr::SimdVector { element, count },
        ) if layout.size.bytes() == 8 => {
            let elem_ty = llvm_asm_scalar_type(cx, element);
            cx.type_vector(elem_ty, count * 2)
        }
        (X86(X86InlineAsmRegClass::reg_abcd), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            cx.type_i64()
        }
        (
            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
            BackendRepr::SimdVector { .. },
        ) if layout.size.bytes() == 64 => cx.type_vector(cx.type_f64(), 8),
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if cx.sess().asm_arch == Some(InlineAsmArch::X86)
            && s.primitive() == Primitive::Float(Float::F128) =>
        {
            cx.type_vector(cx.type_i32(), 4)
        }
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::Scalar(s),
        ) if s.primitive() == Primitive::Float(Float::F16) => cx.type_vector(cx.type_i16(), 8),
        (
            X86(
                X86InlineAsmRegClass::xmm_reg
                | X86InlineAsmRegClass::ymm_reg
                | X86InlineAsmRegClass::zmm_reg,
            ),
            BackendRepr::SimdVector { element, count: count @ (8 | 16) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            cx.type_vector(cx.type_i16(), count)
        }
        (
            Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I32, _) = s.primitive() {
                cx.type_f32()
            } else {
                layout.llvm_type(cx)
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16,
            ),
            BackendRepr::Scalar(s),
        ) => {
            if let Primitive::Int(Integer::I64, _) = s.primitive() {
                cx.type_f64()
            } else {
                layout.llvm_type(cx)
            }
        }
        (
            Arm(
                ArmInlineAsmRegClass::dreg
                | ArmInlineAsmRegClass::dreg_low8
                | ArmInlineAsmRegClass::dreg_low16
                | ArmInlineAsmRegClass::qreg
                | ArmInlineAsmRegClass::qreg_low4
                | ArmInlineAsmRegClass::qreg_low8,
            ),
            BackendRepr::SimdVector { element, count: count @ (4 | 8) },
        ) if element.primitive() == Primitive::Float(Float::F16) => {
            cx.type_vector(cx.type_i16(), count)
        }
        (LoongArch(LoongArchInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16) =>
        {
            cx.type_f32()
        }
        (Mips(MipsInlineAsmRegClass::reg), BackendRepr::Scalar(s)) => {
            match s.primitive() {
                // MIPS only supports register-length arithmetics.
                Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
                Primitive::Float(Float::F32) => cx.type_i32(),
                Primitive::Float(Float::F64) => cx.type_i64(),
                _ => layout.llvm_type(cx),
            }
        }
        (RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F16)
                && !any_target_feature_enabled(cx, instance, &[sym::zfhmin, sym::zfh]) =>
        {
            cx.type_f32()
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F32) =>
        {
            cx.type_vector(cx.type_f32(), 4)
        }
        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
            if s.primitive() == Primitive::Float(Float::F64) =>
        {
            cx.type_vector(cx.type_f64(), 2)
        }
        _ => layout.llvm_type(cx),
    }
}
