use std::assert_matches::assert_matches;
use std::cmp::Ordering;

use rustc_abi::{Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size};
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
use rustc_codegen_ssa::codegen_attrs::autodiff_attrs;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::{self as hir};
use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym};
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
use rustc_target::callconv::PassMode;
use tracing::debug;

use crate::abi::FnAbiLlvmExt;
use crate::builder::Builder;
use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call};
use crate::context::CodegenCx;
use crate::errors::AutoDiffWithoutEnable;
use crate::llvm::{self, Metadata};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg;
use crate::value::Value;

fn call_simple_intrinsic<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    name: Symbol,
    args: &[OperandRef<'tcx, &'ll Value>],
) -> Option<&'ll Value> {
    let (base_name, type_params): (&'static str, &[&'ll Type]) = match name {
        sym::sqrtf16 => ("llvm.sqrt", &[bx.type_f16()]),
        sym::sqrtf32 => ("llvm.sqrt", &[bx.type_f32()]),
        sym::sqrtf64 => ("llvm.sqrt", &[bx.type_f64()]),
        sym::sqrtf128 => ("llvm.sqrt", &[bx.type_f128()]),

        sym::powif16 => ("llvm.powi", &[bx.type_f16(), bx.type_i32()]),
        sym::powif32 => ("llvm.powi", &[bx.type_f32(), bx.type_i32()]),
        sym::powif64 => ("llvm.powi", &[bx.type_f64(), bx.type_i32()]),
        sym::powif128 => ("llvm.powi", &[bx.type_f128(), bx.type_i32()]),

        sym::sinf16 => ("llvm.sin", &[bx.type_f16()]),
        sym::sinf32 => ("llvm.sin", &[bx.type_f32()]),
        sym::sinf64 => ("llvm.sin", &[bx.type_f64()]),
        sym::sinf128 => ("llvm.sin", &[bx.type_f128()]),

        sym::cosf16 => ("llvm.cos", &[bx.type_f16()]),
        sym::cosf32 => ("llvm.cos", &[bx.type_f32()]),
        sym::cosf64 => ("llvm.cos", &[bx.type_f64()]),
        sym::cosf128 => ("llvm.cos", &[bx.type_f128()]),

        sym::powf16 => ("llvm.pow", &[bx.type_f16()]),
        sym::powf32 => ("llvm.pow", &[bx.type_f32()]),
        sym::powf64 => ("llvm.pow", &[bx.type_f64()]),
        sym::powf128 => ("llvm.pow", &[bx.type_f128()]),

        sym::expf16 => ("llvm.exp", &[bx.type_f16()]),
        sym::expf32 => ("llvm.exp", &[bx.type_f32()]),
        sym::expf64 => ("llvm.exp", &[bx.type_f64()]),
        sym::expf128 => ("llvm.exp", &[bx.type_f128()]),

        sym::exp2f16 => ("llvm.exp2", &[bx.type_f16()]),
        sym::exp2f32 => ("llvm.exp2", &[bx.type_f32()]),
        sym::exp2f64 => ("llvm.exp2", &[bx.type_f64()]),
        sym::exp2f128 => ("llvm.exp2", &[bx.type_f128()]),

        sym::logf16 => ("llvm.log", &[bx.type_f16()]),
        sym::logf32 => ("llvm.log", &[bx.type_f32()]),
        sym::logf64 => ("llvm.log", &[bx.type_f64()]),
        sym::logf128 => ("llvm.log", &[bx.type_f128()]),

        sym::log10f16 => ("llvm.log10", &[bx.type_f16()]),
        sym::log10f32 => ("llvm.log10", &[bx.type_f32()]),
        sym::log10f64 => ("llvm.log10", &[bx.type_f64()]),
        sym::log10f128 => ("llvm.log10", &[bx.type_f128()]),

        sym::log2f16 => ("llvm.log2", &[bx.type_f16()]),
        sym::log2f32 => ("llvm.log2", &[bx.type_f32()]),
        sym::log2f64 => ("llvm.log2", &[bx.type_f64()]),
        sym::log2f128 => ("llvm.log2", &[bx.type_f128()]),

        sym::fmaf16 => ("llvm.fma", &[bx.type_f16()]),
        sym::fmaf32 => ("llvm.fma", &[bx.type_f32()]),
        sym::fmaf64 => ("llvm.fma", &[bx.type_f64()]),
        sym::fmaf128 => ("llvm.fma", &[bx.type_f128()]),

        sym::fmuladdf16 => ("llvm.fmuladd", &[bx.type_f16()]),
        sym::fmuladdf32 => ("llvm.fmuladd", &[bx.type_f32()]),
        sym::fmuladdf64 => ("llvm.fmuladd", &[bx.type_f64()]),
        sym::fmuladdf128 => ("llvm.fmuladd", &[bx.type_f128()]),

        sym::fabsf16 => ("llvm.fabs", &[bx.type_f16()]),
        sym::fabsf32 => ("llvm.fabs", &[bx.type_f32()]),
        sym::fabsf64 => ("llvm.fabs", &[bx.type_f64()]),
        sym::fabsf128 => ("llvm.fabs", &[bx.type_f128()]),

        sym::minnumf16 => ("llvm.minnum", &[bx.type_f16()]),
        sym::minnumf32 => ("llvm.minnum", &[bx.type_f32()]),
        sym::minnumf64 => ("llvm.minnum", &[bx.type_f64()]),
        sym::minnumf128 => ("llvm.minnum", &[bx.type_f128()]),

        // FIXME: LLVM currently mis-compile those intrinsics, re-enable them
        // when llvm/llvm-project#{139380,139381,140445} are fixed.
        //sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
        //sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
        //sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
        //sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
        //
        sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]),
        sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]),
        sym::maxnumf64 => ("llvm.maxnum", &[bx.type_f64()]),
        sym::maxnumf128 => ("llvm.maxnum", &[bx.type_f128()]),

        // FIXME: LLVM currently mis-compile those intrinsics, re-enable them
        // when llvm/llvm-project#{139380,139381,140445} are fixed.
        //sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
        //sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
        //sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
        //sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
        //
        sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]),
        sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]),
        sym::copysignf64 => ("llvm.copysign", &[bx.type_f64()]),
        sym::copysignf128 => ("llvm.copysign", &[bx.type_f128()]),

        sym::floorf16 => ("llvm.floor", &[bx.type_f16()]),
        sym::floorf32 => ("llvm.floor", &[bx.type_f32()]),
        sym::floorf64 => ("llvm.floor", &[bx.type_f64()]),
        sym::floorf128 => ("llvm.floor", &[bx.type_f128()]),

        sym::ceilf16 => ("llvm.ceil", &[bx.type_f16()]),
        sym::ceilf32 => ("llvm.ceil", &[bx.type_f32()]),
        sym::ceilf64 => ("llvm.ceil", &[bx.type_f64()]),
        sym::ceilf128 => ("llvm.ceil", &[bx.type_f128()]),

        sym::truncf16 => ("llvm.trunc", &[bx.type_f16()]),
        sym::truncf32 => ("llvm.trunc", &[bx.type_f32()]),
        sym::truncf64 => ("llvm.trunc", &[bx.type_f64()]),
        sym::truncf128 => ("llvm.trunc", &[bx.type_f128()]),

        // We could use any of `rint`, `nearbyint`, or `roundeven`
        // for this -- they are all identical in semantics when
        // assuming the default FP environment.
        // `rint` is what we used for $forever.
        sym::round_ties_even_f16 => ("llvm.rint", &[bx.type_f16()]),
        sym::round_ties_even_f32 => ("llvm.rint", &[bx.type_f32()]),
        sym::round_ties_even_f64 => ("llvm.rint", &[bx.type_f64()]),
        sym::round_ties_even_f128 => ("llvm.rint", &[bx.type_f128()]),

        sym::roundf16 => ("llvm.round", &[bx.type_f16()]),
        sym::roundf32 => ("llvm.round", &[bx.type_f32()]),
        sym::roundf64 => ("llvm.round", &[bx.type_f64()]),
        sym::roundf128 => ("llvm.round", &[bx.type_f128()]),

        _ => return None,
    };
    Some(bx.call_intrinsic(
        base_name,
        type_params,
        &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
    ))
}

impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
    fn codegen_intrinsic_call(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[OperandRef<'tcx, &'ll Value>],
        result: PlaceRef<'tcx, &'ll Value>,
        span: Span,
    ) -> Result<(), ty::Instance<'tcx>> {
        let tcx = self.tcx;

        let name = tcx.item_name(instance.def_id());
        let fn_args = instance.args;

        let simple = call_simple_intrinsic(self, name, args);
        let llval = match name {
            _ if simple.is_some() => simple.unwrap(),
            sym::ptr_mask => {
                let ptr = args[0].immediate();
                self.call_intrinsic(
                    "llvm.ptrmask",
                    &[self.val_ty(ptr), self.type_isize()],
                    &[ptr, args[1].immediate()],
                )
            }
            sym::autodiff => {
                codegen_autodiff(self, tcx, instance, args, result);
                return Ok(());
            }
            sym::is_val_statically_known => {
                if let OperandValue::Immediate(imm) = args[0].val {
                    self.call_intrinsic(
                        "llvm.is.constant",
                        &[args[0].layout.immediate_llvm_type(self.cx)],
                        &[imm],
                    )
                } else {
                    self.const_bool(false)
                }
            }
            sym::select_unpredictable => {
                let cond = args[0].immediate();
                assert_eq!(args[1].layout, args[2].layout);
                let select = |bx: &mut Self, true_val, false_val| {
                    let result = bx.select(cond, true_val, false_val);
                    bx.set_unpredictable(&result);
                    result
                };
                match (args[1].val, args[2].val) {
                    (OperandValue::Ref(true_val), OperandValue::Ref(false_val)) => {
                        assert!(true_val.llextra.is_none());
                        assert!(false_val.llextra.is_none());
                        assert_eq!(true_val.align, false_val.align);
                        let ptr = select(self, true_val.llval, false_val.llval);
                        let selected =
                            OperandValue::Ref(PlaceValue::new_sized(ptr, true_val.align));
                        selected.store(self, result);
                        return Ok(());
                    }
                    (OperandValue::Immediate(_), OperandValue::Immediate(_))
                    | (OperandValue::Pair(_, _), OperandValue::Pair(_, _)) => {
                        let true_val = args[1].immediate_or_packed_pair(self);
                        let false_val = args[2].immediate_or_packed_pair(self);
                        select(self, true_val, false_val)
                    }
                    (OperandValue::ZeroSized, OperandValue::ZeroSized) => return Ok(()),
                    _ => span_bug!(span, "Incompatible OperandValue for select_unpredictable"),
                }
            }
            sym::catch_unwind => {
                catch_unwind_intrinsic(
                    self,
                    args[0].immediate(),
                    args[1].immediate(),
                    args[2].immediate(),
                    result,
                );
                return Ok(());
            }
            sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]),
            sym::va_copy => {
                let dest = args[0].immediate();
                self.call_intrinsic(
                    "llvm.va_copy",
                    &[self.val_ty(dest)],
                    &[dest, args[1].immediate()],
                )
            }
            sym::va_arg => {
                match result.layout.backend_repr {
                    BackendRepr::Scalar(scalar) => {
                        match scalar.primitive() {
                            Primitive::Int(..) => {
                                if self.cx().size_of(result.layout.ty).bytes() < 4 {
                                    // `va_arg` should not be called on an integer type
                                    // less than 4 bytes in length. If it is, promote
                                    // the integer to an `i32` and truncate the result
                                    // back to the smaller type.
                                    let promoted_result = emit_va_arg(self, args[0], tcx.types.i32);
                                    self.trunc(promoted_result, result.layout.llvm_type(self))
                                } else {
                                    emit_va_arg(self, args[0], result.layout.ty)
                                }
                            }
                            Primitive::Float(Float::F16) => {
                                bug!("the va_arg intrinsic does not work with `f16`")
                            }
                            Primitive::Float(Float::F64) | Primitive::Pointer(_) => {
                                emit_va_arg(self, args[0], result.layout.ty)
                            }
                            // `va_arg` should never be used with the return type f32.
                            Primitive::Float(Float::F32) => {
                                bug!("the va_arg intrinsic does not work with `f32`")
                            }
                            Primitive::Float(Float::F128) => {
                                bug!("the va_arg intrinsic does not work with `f128`")
                            }
                        }
                    }
                    _ => bug!("the va_arg intrinsic does not work with non-scalar types"),
                }
            }

            sym::volatile_load | sym::unaligned_volatile_load => {
                let ptr = args[0].immediate();
                let load = self.volatile_load(result.layout.llvm_type(self), ptr);
                let align = if name == sym::unaligned_volatile_load {
                    1
                } else {
                    result.layout.align.abi.bytes() as u32
                };
                unsafe {
                    llvm::LLVMSetAlignment(load, align);
                }
                if !result.layout.is_zst() {
                    self.store_to_place(load, result.val);
                }
                return Ok(());
            }
            sym::volatile_store => {
                let dst = args[0].deref(self.cx());
                args[1].val.volatile_store(self, dst);
                return Ok(());
            }
            sym::unaligned_volatile_store => {
                let dst = args[0].deref(self.cx());
                args[1].val.unaligned_volatile_store(self, dst);
                return Ok(());
            }
            sym::prefetch_read_data
            | sym::prefetch_write_data
            | sym::prefetch_read_instruction
            | sym::prefetch_write_instruction => {
                let (rw, cache_type) = match name {
                    sym::prefetch_read_data => (0, 1),
                    sym::prefetch_write_data => (1, 1),
                    sym::prefetch_read_instruction => (0, 0),
                    sym::prefetch_write_instruction => (1, 0),
                    _ => bug!(),
                };
                let ptr = args[0].immediate();
                let locality = fn_args.const_at(1).to_value().valtree.unwrap_leaf().to_i32();
                self.call_intrinsic(
                    "llvm.prefetch",
                    &[self.val_ty(ptr)],
                    &[
                        ptr,
                        self.const_i32(rw),
                        self.const_i32(locality),
                        self.const_i32(cache_type),
                    ],
                )
            }
            sym::carrying_mul_add => {
                let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx);

                let wide_llty = self.type_ix(size.bits() * 2);
                let args = args.as_array().unwrap();
                let [a, b, c, d] = args.map(|a| self.intcast(a.immediate(), wide_llty, signed));

                let wide = if signed {
                    let prod = self.unchecked_smul(a, b);
                    let acc = self.unchecked_sadd(prod, c);
                    self.unchecked_sadd(acc, d)
                } else {
                    let prod = self.unchecked_umul(a, b);
                    let acc = self.unchecked_uadd(prod, c);
                    self.unchecked_uadd(acc, d)
                };

                let narrow_llty = self.type_ix(size.bits());
                let low = self.trunc(wide, narrow_llty);
                let bits_const = self.const_uint(wide_llty, size.bits());
                // No need for ashr when signed; LLVM changes it to lshr anyway.
                let high = self.lshr(wide, bits_const);
                // FIXME: could be `trunc nuw`, even for signed.
                let high = self.trunc(high, narrow_llty);

                let pair_llty = self.type_struct(&[narrow_llty, narrow_llty], false);
                let pair = self.const_poison(pair_llty);
                let pair = self.insert_value(pair, low, 0);
                let pair = self.insert_value(pair, high, 1);
                pair
            }
            sym::ctlz
            | sym::ctlz_nonzero
            | sym::cttz
            | sym::cttz_nonzero
            | sym::ctpop
            | sym::bswap
            | sym::bitreverse
            | sym::rotate_left
            | sym::rotate_right
            | sym::saturating_add
            | sym::saturating_sub
            | sym::unchecked_funnel_shl
            | sym::unchecked_funnel_shr => {
                let ty = args[0].layout.ty;
                if !ty.is_integral() {
                    tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
                        span,
                        name,
                        ty,
                    });
                    return Ok(());
                }
                let (size, signed) = ty.int_size_and_signed(self.tcx);
                let width = size.bits();
                let llty = self.type_ix(width);
                match name {
                    sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => {
                        let y =
                            self.const_bool(name == sym::ctlz_nonzero || name == sym::cttz_nonzero);
                        let llvm_name = if name == sym::ctlz || name == sym::ctlz_nonzero {
                            "llvm.ctlz"
                        } else {
                            "llvm.cttz"
                        };
                        let ret =
                            self.call_intrinsic(llvm_name, &[llty], &[args[0].immediate(), y]);
                        self.intcast(ret, result.layout.llvm_type(self), false)
                    }
                    sym::ctpop => {
                        let ret =
                            self.call_intrinsic("llvm.ctpop", &[llty], &[args[0].immediate()]);
                        self.intcast(ret, result.layout.llvm_type(self), false)
                    }
                    sym::bswap => {
                        if width == 8 {
                            args[0].immediate() // byte swap a u8/i8 is just a no-op
                        } else {
                            self.call_intrinsic("llvm.bswap", &[llty], &[args[0].immediate()])
                        }
                    }
                    sym::bitreverse => {
                        self.call_intrinsic("llvm.bitreverse", &[llty], &[args[0].immediate()])
                    }
                    sym::rotate_left
                    | sym::rotate_right
                    | sym::unchecked_funnel_shl
                    | sym::unchecked_funnel_shr => {
                        let is_left = name == sym::rotate_left || name == sym::unchecked_funnel_shl;
                        let lhs = args[0].immediate();
                        let (rhs, raw_shift) =
                            if name == sym::rotate_left || name == sym::rotate_right {
                                // rotate = funnel shift with first two args the same
                                (lhs, args[1].immediate())
                            } else {
                                (args[1].immediate(), args[2].immediate())
                            };
                        let llvm_name = format!("llvm.fsh{}", if is_left { 'l' } else { 'r' });

                        // 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(lhs), false);

                        self.call_intrinsic(llvm_name, &[llty], &[lhs, rhs, raw_shift])
                    }
                    sym::saturating_add | sym::saturating_sub => {
                        let is_add = name == sym::saturating_add;
                        let lhs = args[0].immediate();
                        let rhs = args[1].immediate();
                        let llvm_name = format!(
                            "llvm.{}{}.sat",
                            if signed { 's' } else { 'u' },
                            if is_add { "add" } else { "sub" },
                        );
                        self.call_intrinsic(llvm_name, &[llty], &[lhs, rhs])
                    }
                    _ => bug!(),
                }
            }

            sym::raw_eq => {
                use BackendRepr::*;
                let tp_ty = fn_args.type_at(0);
                let layout = self.layout_of(tp_ty).layout;
                let use_integer_compare = match layout.backend_repr() {
                    Scalar(_) | ScalarPair(_, _) => true,
                    SimdVector { .. } => false,
                    Memory { .. } => {
                        // For rusty ABIs, small aggregates are actually passed
                        // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
                        // so we re-use that same threshold here.
                        layout.size() <= self.data_layout().pointer_size() * 2
                    }
                };

                let a = args[0].immediate();
                let b = args[1].immediate();
                if layout.size().bytes() == 0 {
                    self.const_bool(true)
                } else if use_integer_compare {
                    let integer_ty = self.type_ix(layout.size().bits());
                    let a_val = self.load(integer_ty, a, layout.align().abi);
                    let b_val = self.load(integer_ty, b, layout.align().abi);
                    self.icmp(IntPredicate::IntEQ, a_val, b_val)
                } else {
                    let n = self.const_usize(layout.size().bytes());
                    let cmp = self.call_intrinsic("memcmp", &[], &[a, b, n]);
                    self.icmp(IntPredicate::IntEQ, cmp, self.const_int(self.type_int(), 0))
                }
            }

            sym::compare_bytes => {
                // Here we assume that the `memcmp` provided by the target is a NOP for size 0.
                let cmp = self.call_intrinsic(
                    "memcmp",
                    &[],
                    &[args[0].immediate(), args[1].immediate(), args[2].immediate()],
                );
                // Some targets have `memcmp` returning `i16`, but the intrinsic is always `i32`.
                self.sext(cmp, self.type_ix(32))
            }

            sym::black_box => {
                args[0].val.store(self, result);
                let result_val_span = [result.val.llval];
                // We need to "use" the argument in some way LLVM can't introspect, and on
                // targets that support it we can typically leverage inline assembly to do
                // this. LLVM's interpretation of inline assembly is that it's, well, a black
                // box. This isn't the greatest implementation since it probably deoptimizes
                // more than we want, but it's so far good enough.
                //
                // For zero-sized types, the location pointed to by the result may be
                // uninitialized. Do not "use" the result in this case; instead just clobber
                // the memory.
                let (constraint, inputs): (&str, &[_]) = if result.layout.is_zst() {
                    ("~{memory}", &[])
                } else {
                    ("r,~{memory}", &result_val_span)
                };
                crate::asm::inline_asm_call(
                    self,
                    "",
                    constraint,
                    inputs,
                    self.type_void(),
                    &[],
                    true,
                    false,
                    llvm::AsmDialect::Att,
                    &[span],
                    false,
                    None,
                    None,
                )
                .unwrap_or_else(|| bug!("failed to generate inline asm call for `black_box`"));

                // We have copied the value to `result` already.
                return Ok(());
            }

            _ if name.as_str().starts_with("simd_") => {
                // Unpack non-power-of-2 #[repr(packed, simd)] arguments.
                // This gives them the expected layout of a regular #[repr(simd)] vector.
                let mut loaded_args = Vec::new();
                for arg in args {
                    loaded_args.push(
                        // #[repr(packed, simd)] vectors are passed like arrays (as references,
                        // with reduced alignment and no padding) rather than as immediates.
                        // We can use a vector load to fix the layout and turn the argument
                        // into an immediate.
                        if arg.layout.ty.is_simd()
                            && let OperandValue::Ref(place) = arg.val
                        {
                            let (size, elem_ty) = arg.layout.ty.simd_size_and_type(self.tcx());
                            let elem_ll_ty = match elem_ty.kind() {
                                ty::Float(f) => self.type_float_from_ty(*f),
                                ty::Int(i) => self.type_int_from_ty(*i),
                                ty::Uint(u) => self.type_uint_from_ty(*u),
                                ty::RawPtr(_, _) => self.type_ptr(),
                                _ => unreachable!(),
                            };
                            let loaded =
                                self.load_from_place(self.type_vector(elem_ll_ty, size), place);
                            OperandRef::from_immediate_or_packed_pair(self, loaded, arg.layout)
                        } else {
                            *arg
                        },
                    );
                }

                let llret_ty = if result.layout.ty.is_simd()
                    && let BackendRepr::Memory { .. } = result.layout.backend_repr
                {
                    let (size, elem_ty) = result.layout.ty.simd_size_and_type(self.tcx());
                    let elem_ll_ty = match elem_ty.kind() {
                        ty::Float(f) => self.type_float_from_ty(*f),
                        ty::Int(i) => self.type_int_from_ty(*i),
                        ty::Uint(u) => self.type_uint_from_ty(*u),
                        ty::RawPtr(_, _) => self.type_ptr(),
                        _ => unreachable!(),
                    };
                    self.type_vector(elem_ll_ty, size)
                } else {
                    result.layout.llvm_type(self)
                };

                match generic_simd_intrinsic(
                    self,
                    name,
                    fn_args,
                    &loaded_args,
                    result.layout.ty,
                    llret_ty,
                    span,
                ) {
                    Ok(llval) => llval,
                    // If there was an error, just skip this invocation... we'll abort compilation
                    // anyway, but we can keep codegen'ing to find more errors.
                    Err(()) => return Ok(()),
                }
            }

            _ => {
                debug!("unknown intrinsic '{}' -- falling back to default body", name);
                // Call the fallback body instead of generating the intrinsic code
                return Err(ty::Instance::new_raw(instance.def_id(), instance.args));
            }
        };

        if result.layout.ty.is_bool() {
            let val = self.from_immediate(llval);
            self.store_to_place(val, result.val);
        } else if !result.layout.ty.is_unit() {
            self.store_to_place(llval, result.val);
        }
        Ok(())
    }

    fn abort(&mut self) {
        self.call_intrinsic("llvm.trap", &[], &[]);
    }

    fn assume(&mut self, val: Self::Value) {
        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
            self.call_intrinsic("llvm.assume", &[], &[val]);
        }
    }

    fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value {
        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
            self.call_intrinsic(
                "llvm.expect",
                &[self.type_i1()],
                &[cond, self.const_bool(expected)],
            )
        } else {
            cond
        }
    }

    fn type_checked_load(
        &mut self,
        llvtable: &'ll Value,
        vtable_byte_offset: u64,
        typeid: &'ll Metadata,
    ) -> Self::Value {
        let typeid = self.get_metadata_value(typeid);
        let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32);
        let type_checked_load = self.call_intrinsic(
            "llvm.type.checked.load",
            &[],
            &[llvtable, vtable_byte_offset, typeid],
        );
        self.extract_value(type_checked_load, 0)
    }

    fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value {
        self.call_intrinsic("llvm.va_start", &[self.val_ty(va_list)], &[va_list])
    }

    fn va_end(&mut self, va_list: &'ll Value) -> &'ll Value {
        self.call_intrinsic("llvm.va_end", &[self.val_ty(va_list)], &[va_list])
    }
}

fn catch_unwind_intrinsic<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    try_func: &'ll Value,
    data: &'ll Value,
    catch_func: &'ll Value,
    dest: PlaceRef<'tcx, &'ll Value>,
) {
    if !bx.sess().panic_strategy().unwinds() {
        let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
        bx.call(try_func_ty, None, None, try_func, &[data], None, None);
        // Return 0 unconditionally from the intrinsic call;
        // we can never unwind.
        OperandValue::Immediate(bx.const_i32(0)).store(bx, dest);
    } else if wants_msvc_seh(bx.sess()) {
        codegen_msvc_try(bx, try_func, data, catch_func, dest);
    } else if wants_wasm_eh(bx.sess()) {
        codegen_wasm_try(bx, try_func, data, catch_func, dest);
    } else if bx.sess().target.os == "emscripten" {
        codegen_emcc_try(bx, try_func, data, catch_func, dest);
    } else {
        codegen_gnu_try(bx, try_func, data, catch_func, dest);
    }
}

// MSVC's definition of the `rust_try` function.
//
// This implementation uses the new exception handling instructions in LLVM
// which have support in LLVM for SEH on MSVC targets. Although these
// instructions are meant to work for all targets, as of the time of this
// writing, however, LLVM does not recommend the usage of these new instructions
// as the old ones are still more optimized.
fn codegen_msvc_try<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    try_func: &'ll Value,
    data: &'ll Value,
    catch_func: &'ll Value,
    dest: PlaceRef<'tcx, &'ll Value>,
) {
    let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
        bx.set_personality_fn(bx.eh_personality());

        let normal = bx.append_sibling_block("normal");
        let catchswitch = bx.append_sibling_block("catchswitch");
        let catchpad_rust = bx.append_sibling_block("catchpad_rust");
        let catchpad_foreign = bx.append_sibling_block("catchpad_foreign");
        let caught = bx.append_sibling_block("caught");

        let try_func = llvm::get_param(bx.llfn(), 0);
        let data = llvm::get_param(bx.llfn(), 1);
        let catch_func = llvm::get_param(bx.llfn(), 2);

        // We're generating an IR snippet that looks like:
        //
        //   declare i32 @rust_try(%try_func, %data, %catch_func) {
        //      %slot = alloca i8*
        //      invoke %try_func(%data) to label %normal unwind label %catchswitch
        //
        //   normal:
        //      ret i32 0
        //
        //   catchswitch:
        //      %cs = catchswitch within none [%catchpad_rust, %catchpad_foreign] unwind to caller
        //
        //   catchpad_rust:
        //      %tok = catchpad within %cs [%type_descriptor, 8, %slot]
        //      %ptr = load %slot
        //      call %catch_func(%data, %ptr)
        //      catchret from %tok to label %caught
        //
        //   catchpad_foreign:
        //      %tok = catchpad within %cs [null, 64, null]
        //      call %catch_func(%data, null)
        //      catchret from %tok to label %caught
        //
        //   caught:
        //      ret i32 1
        //   }
        //
        // This structure follows the basic usage of throw/try/catch in LLVM.
        // For example, compile this C++ snippet to see what LLVM generates:
        //
        //      struct rust_panic {
        //          rust_panic(const rust_panic&);
        //          ~rust_panic();
        //
        //          void* x[2];
        //      };
        //
        //      int __rust_try(
        //          void (*try_func)(void*),
        //          void *data,
        //          void (*catch_func)(void*, void*) noexcept
        //      ) {
        //          try {
        //              try_func(data);
        //              return 0;
        //          } catch(rust_panic& a) {
        //              catch_func(data, &a);
        //              return 1;
        //          } catch(...) {
        //              catch_func(data, NULL);
        //              return 1;
        //          }
        //      }
        //
        // More information can be found in libstd's seh.rs implementation.
        let ptr_size = bx.tcx().data_layout.pointer_size();
        let ptr_align = bx.tcx().data_layout.pointer_align().abi;
        let slot = bx.alloca(ptr_size, ptr_align);
        let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);

        bx.switch_to_block(normal);
        bx.ret(bx.const_i32(0));

        bx.switch_to_block(catchswitch);
        let cs = bx.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]);

        // We can't use the TypeDescriptor defined in libpanic_unwind because it
        // might be in another DLL and the SEH encoding only supports specifying
        // a TypeDescriptor from the current module.
        //
        // However this isn't an issue since the MSVC runtime uses string
        // comparison on the type name to match TypeDescriptors rather than
        // pointer equality.
        //
        // So instead we generate a new TypeDescriptor in each module that uses
        // `try` and let the linker merge duplicate definitions in the same
        // module.
        //
        // When modifying, make sure that the type_name string exactly matches
        // the one used in library/panic_unwind/src/seh.rs.
        let type_info_vtable = bx.declare_global("??_7type_info@@6B@", bx.type_ptr());
        let type_name = bx.const_bytes(b"rust_panic\0");
        let type_info =
            bx.const_struct(&[type_info_vtable, bx.const_null(bx.type_ptr()), type_name], false);
        let tydesc = bx.declare_global(
            &mangle_internal_symbol(bx.tcx, "__rust_panic_type_info"),
            bx.val_ty(type_info),
        );

        llvm::set_linkage(tydesc, llvm::Linkage::LinkOnceODRLinkage);
        if bx.cx.tcx.sess.target.supports_comdat() {
            llvm::SetUniqueComdat(bx.llmod, tydesc);
        }
        llvm::set_initializer(tydesc, type_info);

        // The flag value of 8 indicates that we are catching the exception by
        // reference instead of by value. We can't use catch by value because
        // that requires copying the exception object, which we don't support
        // since our exception object effectively contains a Box.
        //
        // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
        bx.switch_to_block(catchpad_rust);
        let flags = bx.const_i32(8);
        let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
        let ptr = bx.load(bx.type_ptr(), slot, ptr_align);
        let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
        bx.catch_ret(&funclet, caught);

        // The flag value of 64 indicates a "catch-all".
        bx.switch_to_block(catchpad_foreign);
        let flags = bx.const_i32(64);
        let null = bx.const_null(bx.type_ptr());
        let funclet = bx.catch_pad(cs, &[null, flags, null]);
        bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet), None);
        bx.catch_ret(&funclet, caught);

        bx.switch_to_block(caught);
        bx.ret(bx.const_i32(1));
    });

    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
    OperandValue::Immediate(ret).store(bx, dest);
}

// WASM's definition of the `rust_try` function.
fn codegen_wasm_try<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    try_func: &'ll Value,
    data: &'ll Value,
    catch_func: &'ll Value,
    dest: PlaceRef<'tcx, &'ll Value>,
) {
    let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
        bx.set_personality_fn(bx.eh_personality());

        let normal = bx.append_sibling_block("normal");
        let catchswitch = bx.append_sibling_block("catchswitch");
        let catchpad = bx.append_sibling_block("catchpad");
        let caught = bx.append_sibling_block("caught");

        let try_func = llvm::get_param(bx.llfn(), 0);
        let data = llvm::get_param(bx.llfn(), 1);
        let catch_func = llvm::get_param(bx.llfn(), 2);

        // We're generating an IR snippet that looks like:
        //
        //   declare i32 @rust_try(%try_func, %data, %catch_func) {
        //      %slot = alloca i8*
        //      invoke %try_func(%data) to label %normal unwind label %catchswitch
        //
        //   normal:
        //      ret i32 0
        //
        //   catchswitch:
        //      %cs = catchswitch within none [%catchpad] unwind to caller
        //
        //   catchpad:
        //      %tok = catchpad within %cs [null]
        //      %ptr = call @llvm.wasm.get.exception(token %tok)
        //      %sel = call @llvm.wasm.get.ehselector(token %tok)
        //      call %catch_func(%data, %ptr)
        //      catchret from %tok to label %caught
        //
        //   caught:
        //      ret i32 1
        //   }
        //
        let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);

        bx.switch_to_block(normal);
        bx.ret(bx.const_i32(0));

        bx.switch_to_block(catchswitch);
        let cs = bx.catch_switch(None, None, &[catchpad]);

        bx.switch_to_block(catchpad);
        let null = bx.const_null(bx.type_ptr());
        let funclet = bx.catch_pad(cs, &[null]);

        let ptr = bx.call_intrinsic("llvm.wasm.get.exception", &[], &[funclet.cleanuppad()]);
        let _sel = bx.call_intrinsic("llvm.wasm.get.ehselector", &[], &[funclet.cleanuppad()]);

        let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
        bx.catch_ret(&funclet, caught);

        bx.switch_to_block(caught);
        bx.ret(bx.const_i32(1));
    });

    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
    OperandValue::Immediate(ret).store(bx, dest);
}

// Definition of the standard `try` function for Rust using the GNU-like model
// of exceptions (e.g., the normal semantics of LLVM's `landingpad` and `invoke`
// instructions).
//
// This codegen is a little surprising because we always call a shim
// function instead of inlining the call to `invoke` manually here. This is done
// because in LLVM we're only allowed to have one personality per function
// definition. The call to the `try` intrinsic is being inlined into the
// function calling it, and that function may already have other personality
// functions in play. By calling a shim we're guaranteed that our shim will have
// the right personality function.
fn codegen_gnu_try<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    try_func: &'ll Value,
    data: &'ll Value,
    catch_func: &'ll Value,
    dest: PlaceRef<'tcx, &'ll Value>,
) {
    let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
        // Codegens the shims described above:
        //
        //   bx:
        //      invoke %try_func(%data) normal %normal unwind %catch
        //
        //   normal:
        //      ret 0
        //
        //   catch:
        //      (%ptr, _) = landingpad
        //      call %catch_func(%data, %ptr)
        //      ret 1
        let then = bx.append_sibling_block("then");
        let catch = bx.append_sibling_block("catch");

        let try_func = llvm::get_param(bx.llfn(), 0);
        let data = llvm::get_param(bx.llfn(), 1);
        let catch_func = llvm::get_param(bx.llfn(), 2);
        let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);

        bx.switch_to_block(then);
        bx.ret(bx.const_i32(0));

        // Type indicator for the exception being thrown.
        //
        // The first value in this tuple is a pointer to the exception object
        // being thrown. The second value is a "selector" indicating which of
        // the landing pad clauses the exception's type had been matched to.
        // rust_try ignores the selector.
        bx.switch_to_block(catch);
        let lpad_ty = bx.type_struct(&[bx.type_ptr(), bx.type_i32()], false);
        let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 1);
        let tydesc = bx.const_null(bx.type_ptr());
        bx.add_clause(vals, tydesc);
        let ptr = bx.extract_value(vals, 0);
        let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
        bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
        bx.ret(bx.const_i32(1));
    });

    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
    OperandValue::Immediate(ret).store(bx, dest);
}

// Variant of codegen_gnu_try used for emscripten where Rust panics are
// implemented using C++ exceptions. Here we use exceptions of a specific type
// (`struct rust_panic`) to represent Rust panics.
fn codegen_emcc_try<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    try_func: &'ll Value,
    data: &'ll Value,
    catch_func: &'ll Value,
    dest: PlaceRef<'tcx, &'ll Value>,
) {
    let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
        // Codegens the shims described above:
        //
        //   bx:
        //      invoke %try_func(%data) normal %normal unwind %catch
        //
        //   normal:
        //      ret 0
        //
        //   catch:
        //      (%ptr, %selector) = landingpad
        //      %rust_typeid = @llvm.eh.typeid.for(@_ZTI10rust_panic)
        //      %is_rust_panic = %selector == %rust_typeid
        //      %catch_data = alloca { i8*, i8 }
        //      %catch_data[0] = %ptr
        //      %catch_data[1] = %is_rust_panic
        //      call %catch_func(%data, %catch_data)
        //      ret 1
        let then = bx.append_sibling_block("then");
        let catch = bx.append_sibling_block("catch");

        let try_func = llvm::get_param(bx.llfn(), 0);
        let data = llvm::get_param(bx.llfn(), 1);
        let catch_func = llvm::get_param(bx.llfn(), 2);
        let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);

        bx.switch_to_block(then);
        bx.ret(bx.const_i32(0));

        // Type indicator for the exception being thrown.
        //
        // The first value in this tuple is a pointer to the exception object
        // being thrown. The second value is a "selector" indicating which of
        // the landing pad clauses the exception's type had been matched to.
        bx.switch_to_block(catch);
        let tydesc = bx.eh_catch_typeinfo();
        let lpad_ty = bx.type_struct(&[bx.type_ptr(), bx.type_i32()], false);
        let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 2);
        bx.add_clause(vals, tydesc);
        bx.add_clause(vals, bx.const_null(bx.type_ptr()));
        let ptr = bx.extract_value(vals, 0);
        let selector = bx.extract_value(vals, 1);

        // Check if the typeid we got is the one for a Rust panic.
        let rust_typeid = bx.call_intrinsic("llvm.eh.typeid.for", &[bx.val_ty(tydesc)], &[tydesc]);
        let is_rust_panic = bx.icmp(IntPredicate::IntEQ, selector, rust_typeid);
        let is_rust_panic = bx.zext(is_rust_panic, bx.type_bool());

        // We need to pass two values to catch_func (ptr and is_rust_panic), so
        // create an alloca and pass a pointer to that.
        let ptr_size = bx.tcx().data_layout.pointer_size();
        let ptr_align = bx.tcx().data_layout.pointer_align().abi;
        let i8_align = bx.tcx().data_layout.i8_align.abi;
        // Required in order for there to be no padding between the fields.
        assert!(i8_align <= ptr_align);
        let catch_data = bx.alloca(2 * ptr_size, ptr_align);
        bx.store(ptr, catch_data, ptr_align);
        let catch_data_1 = bx.inbounds_ptradd(catch_data, bx.const_usize(ptr_size.bytes()));
        bx.store(is_rust_panic, catch_data_1, i8_align);

        let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
        bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None, None);
        bx.ret(bx.const_i32(1));
    });

    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
    OperandValue::Immediate(ret).store(bx, dest);
}

// Helper function to give a Block to a closure to codegen a shim function.
// This is currently primarily used for the `try` intrinsic functions above.
fn gen_fn<'a, 'll, 'tcx>(
    cx: &'a CodegenCx<'ll, 'tcx>,
    name: &str,
    rust_fn_sig: ty::PolyFnSig<'tcx>,
    codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
) -> (&'ll Type, &'ll Value) {
    let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty());
    let llty = fn_abi.llvm_type(cx);
    let llfn = cx.declare_fn(name, fn_abi, None);
    cx.set_frame_pointer_type(llfn);
    cx.apply_target_cpu_attr(llfn);
    // FIXME(eddyb) find a nicer way to do this.
    llvm::set_linkage(llfn, llvm::Linkage::InternalLinkage);
    let llbb = Builder::append_block(cx, llfn, "entry-block");
    let bx = Builder::build(cx, llbb);
    codegen(bx);
    (llty, llfn)
}

// Helper function used to get a handle to the `__rust_try` function used to
// catch exceptions.
//
// This function is only generated once and is then cached.
fn get_rust_try_fn<'a, 'll, 'tcx>(
    cx: &'a CodegenCx<'ll, 'tcx>,
    codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
) -> (&'ll Type, &'ll Value) {
    if let Some(llfn) = cx.rust_try_fn.get() {
        return llfn;
    }

    // Define the type up front for the signature of the rust_try function.
    let tcx = cx.tcx;
    let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8);
    // `unsafe fn(*mut i8) -> ()`
    let try_fn_ty = Ty::new_fn_ptr(
        tcx,
        ty::Binder::dummy(tcx.mk_fn_sig(
            [i8p],
            tcx.types.unit,
            false,
            hir::Safety::Unsafe,
            ExternAbi::Rust,
        )),
    );
    // `unsafe fn(*mut i8, *mut i8) -> ()`
    let catch_fn_ty = Ty::new_fn_ptr(
        tcx,
        ty::Binder::dummy(tcx.mk_fn_sig(
            [i8p, i8p],
            tcx.types.unit,
            false,
            hir::Safety::Unsafe,
            ExternAbi::Rust,
        )),
    );
    // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
    let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
        [try_fn_ty, i8p, catch_fn_ty],
        tcx.types.i32,
        false,
        hir::Safety::Unsafe,
        ExternAbi::Rust,
    ));
    let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
    cx.rust_try_fn.set(Some(rust_try));
    rust_try
}

fn codegen_autodiff<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    tcx: TyCtxt<'tcx>,
    instance: ty::Instance<'tcx>,
    args: &[OperandRef<'tcx, &'ll Value>],
    result: PlaceRef<'tcx, &'ll Value>,
) {
    if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
        let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
    }

    let fn_args = instance.args;
    let callee_ty = instance.ty(tcx, bx.typing_env());

    let sig = callee_ty.fn_sig(tcx).skip_binder();

    let ret_ty = sig.output();
    let llret_ty = bx.layout_of(ret_ty).llvm_type(bx);

    // Get source, diff, and attrs
    let (source_id, source_args) = match fn_args.into_type_list(tcx)[0].kind() {
        ty::FnDef(def_id, source_params) => (def_id, source_params),
        _ => bug!("invalid autodiff intrinsic args"),
    };

    let fn_source = match Instance::try_resolve(tcx, bx.cx.typing_env(), *source_id, source_args) {
        Ok(Some(instance)) => instance,
        Ok(None) => bug!(
            "could not resolve ({:?}, {:?}) to a specific autodiff instance",
            source_id,
            source_args
        ),
        Err(_) => {
            // An error has already been emitted
            return;
        }
    };

    let source_symbol = symbol_name_for_instance_in_crate(tcx, fn_source.clone(), LOCAL_CRATE);
    let Some(fn_to_diff) = bx.cx.get_function(&source_symbol) else {
        bug!("could not find source function")
    };

    let (diff_id, diff_args) = match fn_args.into_type_list(tcx)[1].kind() {
        ty::FnDef(def_id, diff_args) => (def_id, diff_args),
        _ => bug!("invalid args"),
    };

    let fn_diff = match Instance::try_resolve(tcx, bx.cx.typing_env(), *diff_id, diff_args) {
        Ok(Some(instance)) => instance,
        Ok(None) => bug!(
            "could not resolve ({:?}, {:?}) to a specific autodiff instance",
            diff_id,
            diff_args
        ),
        Err(_) => {
            // An error has already been emitted
            return;
        }
    };

    let val_arr = get_args_from_tuple(bx, args[2], fn_diff);
    let diff_symbol = symbol_name_for_instance_in_crate(tcx, fn_diff.clone(), LOCAL_CRATE);

    let Some(mut diff_attrs) = autodiff_attrs(tcx, fn_diff.def_id()) else {
        bug!("could not find autodiff attrs")
    };

    adjust_activity_to_abi(
        tcx,
        fn_source,
        TypingEnv::fully_monomorphized(),
        &mut diff_attrs.input_activity,
    );

    // Build body
    generate_enzyme_call(
        bx,
        bx.cx,
        fn_to_diff,
        &diff_symbol,
        llret_ty,
        &val_arr,
        diff_attrs.clone(),
        result,
    );
}

fn get_args_from_tuple<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    tuple_op: OperandRef<'tcx, &'ll Value>,
    fn_instance: Instance<'tcx>,
) -> Vec<&'ll Value> {
    let cx = bx.cx;
    let fn_abi = cx.fn_abi_of_instance(fn_instance, ty::List::empty());

    match tuple_op.val {
        OperandValue::Immediate(val) => vec![val],
        OperandValue::Pair(v1, v2) => vec![v1, v2],
        OperandValue::Ref(ptr) => {
            let tuple_place = PlaceRef { val: ptr, layout: tuple_op.layout };

            let mut result = Vec::with_capacity(fn_abi.args.len());
            let mut tuple_index = 0;

            for arg in &fn_abi.args {
                match arg.mode {
                    PassMode::Ignore => {}
                    PassMode::Direct(_) | PassMode::Cast { .. } => {
                        let field = tuple_place.project_field(bx, tuple_index);
                        let llvm_ty = field.layout.llvm_type(bx.cx);
                        let val = bx.load(llvm_ty, field.val.llval, field.val.align);
                        result.push(val);
                        tuple_index += 1;
                    }
                    PassMode::Pair(_, _) => {
                        let field = tuple_place.project_field(bx, tuple_index);
                        let llvm_ty = field.layout.llvm_type(bx.cx);
                        let pair_val = bx.load(llvm_ty, field.val.llval, field.val.align);
                        result.push(bx.extract_value(pair_val, 0));
                        result.push(bx.extract_value(pair_val, 1));
                        tuple_index += 1;
                    }
                    PassMode::Indirect { .. } => {
                        let field = tuple_place.project_field(bx, tuple_index);
                        result.push(field.val.llval);
                        tuple_index += 1;
                    }
                }
            }

            result
        }

        OperandValue::ZeroSized => vec![],
    }
}

fn generic_simd_intrinsic<'ll, 'tcx>(
    bx: &mut Builder<'_, 'll, 'tcx>,
    name: Symbol,
    fn_args: GenericArgsRef<'tcx>,
    args: &[OperandRef<'tcx, &'ll Value>],
    ret_ty: Ty<'tcx>,
    llret_ty: &'ll Type,
    span: Span,
) -> Result<&'ll Value, ()> {
    macro_rules! return_error {
        ($diag: expr) => {{
            bx.sess().dcx().emit_err($diag);
            return Err(());
        }};
    }

    macro_rules! require {
        ($cond: expr, $diag: expr) => {
            if !$cond {
                return_error!($diag);
            }
        };
    }

    macro_rules! require_simd {
        ($ty: expr, $variant:ident) => {{
            require!($ty.is_simd(), InvalidMonomorphization::$variant { span, name, ty: $ty });
            $ty.simd_size_and_type(bx.tcx())
        }};
    }

    /// Returns the bitwidth of the `$ty` argument if it is an `Int` or `Uint` type.
    macro_rules! require_int_or_uint_ty {
        ($ty: expr, $diag: expr) => {
            match $ty {
                ty::Int(i) => {
                    i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size().bits())
                }
                ty::Uint(i) => {
                    i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size().bits())
                }
                _ => {
                    return_error!($diag);
                }
            }
        };
    }

    /// Converts a vector mask, where each element has a bit width equal to the data elements it is used with,
    /// down to an i1 based mask that can be used by llvm intrinsics.
    ///
    /// The rust simd semantics are that each element should either consist of all ones or all zeroes,
    /// but this information is not available to llvm. Truncating the vector effectively uses the lowest bit,
    /// but codegen for several targets is better if we consider the highest bit by shifting.
    ///
    /// For x86 SSE/AVX targets this is beneficial since most instructions with mask parameters only consider the highest bit.
    /// So even though on llvm level we have an additional shift, in the final assembly there is no shift or truncate and
    /// instead the mask can be used as is.
    ///
    /// For aarch64 and other targets there is a benefit because a mask from the sign bit can be more
    /// efficiently converted to an all ones / all zeroes mask by comparing whether each element is negative.
    fn vector_mask_to_bitmask<'a, 'll, 'tcx>(
        bx: &mut Builder<'a, 'll, 'tcx>,
        i_xn: &'ll Value,
        in_elem_bitwidth: u64,
        in_len: u64,
    ) -> &'ll Value {
        // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
        let shift_idx = bx.cx.const_int(bx.type_ix(in_elem_bitwidth), (in_elem_bitwidth - 1) as _);
        let shift_indices = vec![shift_idx; in_len as _];
        let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice()));
        // Truncate vector to an <i1 x N>
        bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len))
    }

    // Sanity-check: all vector arguments must be immediates.
    if cfg!(debug_assertions) {
        for arg in args {
            if arg.layout.ty.is_simd() {
                assert_matches!(arg.val, OperandValue::Immediate(_));
            }
        }
    }

    if name == sym::simd_select_bitmask {
        let (len, _) = require_simd!(args[1].layout.ty, SimdArgument);

        let expected_int_bits = len.max(8).next_power_of_two();
        let expected_bytes = len.div_ceil(8);

        let mask_ty = args[0].layout.ty;
        let mask = match mask_ty.kind() {
            ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
            ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
            ty::Array(elem, len)
                if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
                    && len
                        .try_to_target_usize(bx.tcx)
                        .expect("expected monomorphic const in codegen")
                        == expected_bytes =>
            {
                let place = PlaceRef::alloca(bx, args[0].layout);
                args[0].val.store(bx, place);
                let int_ty = bx.type_ix(expected_bytes * 8);
                bx.load(int_ty, place.val.llval, Align::ONE)
            }
            _ => return_error!(InvalidMonomorphization::InvalidBitmask {
                span,
                name,
                mask_ty,
                expected_int_bits,
                expected_bytes
            }),
        };

        let i1 = bx.type_i1();
        let im = bx.type_ix(len);
        let i1xn = bx.type_vector(i1, len);
        let m_im = bx.trunc(mask, im);
        let m_i1s = bx.bitcast(m_im, i1xn);
        return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
    }

    // every intrinsic below takes a SIMD vector as its first argument
    let (in_len, in_elem) = require_simd!(args[0].layout.ty, SimdInput);
    let in_ty = args[0].layout.ty;

    let comparison = match name {
        sym::simd_eq => Some(BinOp::Eq),
        sym::simd_ne => Some(BinOp::Ne),
        sym::simd_lt => Some(BinOp::Lt),
        sym::simd_le => Some(BinOp::Le),
        sym::simd_gt => Some(BinOp::Gt),
        sym::simd_ge => Some(BinOp::Ge),
        _ => None,
    };

    if let Some(cmp_op) = comparison {
        let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);

        require!(
            in_len == out_len,
            InvalidMonomorphization::ReturnLengthInputType {
                span,
                name,
                in_len,
                in_ty,
                ret_ty,
                out_len
            }
        );
        require!(
            bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
            InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
        );

        return Ok(compare_simd_types(
            bx,
            args[0].immediate(),
            args[1].immediate(),
            in_elem,
            llret_ty,
            cmp_op,
        ));
    }

    if name == sym::simd_shuffle_const_generic {
        let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch();
        let n = idx.len() as u64;

        let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
        require!(
            out_len == n,
            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
        );
        require!(
            in_elem == out_ty,
            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
        );

        let total_len = in_len * 2;

        let indices: Option<Vec<_>> = idx
            .iter()
            .enumerate()
            .map(|(arg_idx, val)| {
                let idx = val.unwrap_leaf().to_i32();
                if idx >= i32::try_from(total_len).unwrap() {
                    bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
                        span,
                        name,
                        arg_idx: arg_idx as u64,
                        total_len: total_len.into(),
                    });
                    None
                } else {
                    Some(bx.const_i32(idx))
                }
            })
            .collect();
        let Some(indices) = indices else {
            return Ok(bx.const_null(llret_ty));
        };

        return Ok(bx.shuffle_vector(
            args[0].immediate(),
            args[1].immediate(),
            bx.const_vector(&indices),
        ));
    }

    if name == sym::simd_shuffle {
        // Make sure this is actually a SIMD vector.
        let idx_ty = args[2].layout.ty;
        let n: u64 = if idx_ty.is_simd()
            && matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
        {
            idx_ty.simd_size_and_type(bx.cx.tcx).0
        } else {
            return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
        };

        let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
        require!(
            out_len == n,
            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
        );
        require!(
            in_elem == out_ty,
            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
        );

        let total_len = u128::from(in_len) * 2;

        // Check that the indices are in-bounds.
        let indices = args[2].immediate();
        for i in 0..n {
            let val = bx.const_get_elt(indices, i as u64);
            let idx = bx
                .const_to_opt_u128(val, true)
                .unwrap_or_else(|| bug!("typeck should have already ensured that these are const"));
            if idx >= total_len {
                return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
                    span,
                    name,
                    arg_idx: i,
                    total_len,
                });
            }
        }

        return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
    }

    if name == sym::simd_insert || name == sym::simd_insert_dyn {
        require!(
            in_elem == args[2].layout.ty,
            InvalidMonomorphization::InsertedType {
                span,
                name,
                in_elem,
                in_ty,
                out_ty: args[2].layout.ty
            }
        );

        let index_imm = if name == sym::simd_insert {
            let idx = bx
                .const_to_opt_u128(args[1].immediate(), false)
                .expect("typeck should have ensure that this is a const");
            if idx >= in_len.into() {
                return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
                    span,
                    name,
                    arg_idx: 1,
                    total_len: in_len.into(),
                });
            }
            bx.const_i32(idx as i32)
        } else {
            args[1].immediate()
        };

        return Ok(bx.insert_element(args[0].immediate(), args[2].immediate(), index_imm));
    }
    if name == sym::simd_extract || name == sym::simd_extract_dyn {
        require!(
            ret_ty == in_elem,
            InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
        );
        let index_imm = if name == sym::simd_extract {
            let idx = bx
                .const_to_opt_u128(args[1].immediate(), false)
                .expect("typeck should have ensure that this is a const");
            if idx >= in_len.into() {
                return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
                    span,
                    name,
                    arg_idx: 1,
                    total_len: in_len.into(),
                });
            }
            bx.const_i32(idx as i32)
        } else {
            args[1].immediate()
        };

        return Ok(bx.extract_element(args[0].immediate(), index_imm));
    }

    if name == sym::simd_select {
        let m_elem_ty = in_elem;
        let m_len = in_len;
        let (v_len, _) = require_simd!(args[1].layout.ty, SimdArgument);
        require!(
            m_len == v_len,
            InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
        );
        let in_elem_bitwidth = require_int_or_uint_ty!(
            m_elem_ty.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: m_elem_ty }
        );
        let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len);
        return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
    }

    if name == sym::simd_bitmask {
        // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a vector mask and
        // returns one bit for each lane (which must all be `0` or `!0`) in the form of either:
        // * an unsigned integer
        // * an array of `u8`
        // If the vector has less than 8 lanes, a u8 is returned with zeroed trailing bits.
        //
        // The bit order of the result depends on the byte endianness, LSB-first for little
        // endian and MSB-first for big endian.
        let expected_int_bits = in_len.max(8).next_power_of_two();
        let expected_bytes = in_len.div_ceil(8);

        // Integer vector <i{in_bitwidth} x in_len>:
        let in_elem_bitwidth = require_int_or_uint_ty!(
            in_elem.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: in_elem }
        );

        let i1xn = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, in_len);
        // Bitcast <i1 x N> to iN:
        let i_ = bx.bitcast(i1xn, bx.type_ix(in_len));

        match ret_ty.kind() {
            ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {
                // Zero-extend iN to the bitmask type:
                return Ok(bx.zext(i_, bx.type_ix(expected_int_bits)));
            }
            ty::Array(elem, len)
                if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
                    && len
                        .try_to_target_usize(bx.tcx)
                        .expect("expected monomorphic const in codegen")
                        == expected_bytes =>
            {
                // Zero-extend iN to the array length:
                let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8));

                // Convert the integer to a byte array
                let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE);
                bx.store(ze, ptr, Align::ONE);
                let array_ty = bx.type_array(bx.type_i8(), expected_bytes);
                return Ok(bx.load(array_ty, ptr, Align::ONE));
            }
            _ => return_error!(InvalidMonomorphization::CannotReturn {
                span,
                name,
                ret_ty,
                expected_int_bits,
                expected_bytes
            }),
        }
    }

    fn simd_simple_float_intrinsic<'ll, 'tcx>(
        name: Symbol,
        in_elem: Ty<'_>,
        in_ty: Ty<'_>,
        in_len: u64,
        bx: &mut Builder<'_, 'll, 'tcx>,
        span: Span,
        args: &[OperandRef<'tcx, &'ll Value>],
    ) -> Result<&'ll Value, ()> {
        macro_rules! return_error {
            ($diag: expr) => {{
                bx.sess().dcx().emit_err($diag);
                return Err(());
            }};
        }

        let elem_ty = if let ty::Float(f) = in_elem.kind() {
            bx.cx.type_float_from_ty(*f)
        } else {
            return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty });
        };

        let vec_ty = bx.type_vector(elem_ty, in_len);

        let intr_name = match name {
            sym::simd_ceil => "llvm.ceil",
            sym::simd_fabs => "llvm.fabs",
            sym::simd_fcos => "llvm.cos",
            sym::simd_fexp2 => "llvm.exp2",
            sym::simd_fexp => "llvm.exp",
            sym::simd_flog10 => "llvm.log10",
            sym::simd_flog2 => "llvm.log2",
            sym::simd_flog => "llvm.log",
            sym::simd_floor => "llvm.floor",
            sym::simd_fma => "llvm.fma",
            sym::simd_relaxed_fma => "llvm.fmuladd",
            sym::simd_fsin => "llvm.sin",
            sym::simd_fsqrt => "llvm.sqrt",
            sym::simd_round => "llvm.round",
            sym::simd_round_ties_even => "llvm.rint",
            sym::simd_trunc => "llvm.trunc",
            _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
        };
        Ok(bx.call_intrinsic(
            intr_name,
            &[vec_ty],
            &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
        ))
    }

    if std::matches!(
        name,
        sym::simd_ceil
            | sym::simd_fabs
            | sym::simd_fcos
            | sym::simd_fexp2
            | sym::simd_fexp
            | sym::simd_flog10
            | sym::simd_flog2
            | sym::simd_flog
            | sym::simd_floor
            | sym::simd_fma
            | sym::simd_fsin
            | sym::simd_fsqrt
            | sym::simd_relaxed_fma
            | sym::simd_round
            | sym::simd_round_ties_even
            | sym::simd_trunc
    ) {
        return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
    }

    fn llvm_vector_ty<'ll>(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: u64) -> &'ll Type {
        let elem_ty = match *elem_ty.kind() {
            ty::Int(v) => cx.type_int_from_ty(v),
            ty::Uint(v) => cx.type_uint_from_ty(v),
            ty::Float(v) => cx.type_float_from_ty(v),
            ty::RawPtr(_, _) => cx.type_ptr(),
            _ => unreachable!(),
        };
        cx.type_vector(elem_ty, vec_len)
    }

    if name == sym::simd_gather {
        // simd_gather(values: <N x T>, pointers: <N x *_ T>,
        //             mask: <N x i{M}>) -> <N x T>
        // * N: number of elements in the input vectors
        // * T: type of the element to load
        // * M: any integer width is supported, will be truncated to i1

        // All types must be simd vector types

        // The second argument must be a simd vector with an element type that's a pointer
        // to the element type of the first argument
        let (_, element_ty0) = require_simd!(in_ty, SimdFirst);
        let (out_len, element_ty1) = require_simd!(args[1].layout.ty, SimdSecond);
        // The element type of the third argument must be a signed integer type of any width:
        let (out_len2, element_ty2) = require_simd!(args[2].layout.ty, SimdThird);
        require_simd!(ret_ty, SimdReturn);

        // Of the same length:
        require!(
            in_len == out_len,
            InvalidMonomorphization::SecondArgumentLength {
                span,
                name,
                in_len,
                in_ty,
                arg_ty: args[1].layout.ty,
                out_len
            }
        );
        require!(
            in_len == out_len2,
            InvalidMonomorphization::ThirdArgumentLength {
                span,
                name,
                in_len,
                in_ty,
                arg_ty: args[2].layout.ty,
                out_len: out_len2
            }
        );

        // The return type must match the first argument type
        require!(
            ret_ty == in_ty,
            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
        );

        require!(
            matches!(
                *element_ty1.kind(),
                ty::RawPtr(p_ty, _) if p_ty == in_elem && p_ty.kind() == element_ty0.kind()
            ),
            InvalidMonomorphization::ExpectedElementType {
                span,
                name,
                expected_element: element_ty1,
                second_arg: args[1].layout.ty,
                in_elem,
                in_ty,
                mutability: ExpectedPointerMutability::Not,
            }
        );

        let mask_elem_bitwidth = require_int_or_uint_ty!(
            element_ty2.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: element_ty2 }
        );

        // Alignment of T, must be a constant integer value:
        let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32);

        // Truncate the mask vector to a vector of i1s:
        let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len);

        // Type of the vector of pointers:
        let llvm_pointer_vec_ty = llvm_vector_ty(bx, element_ty1, in_len);

        // Type of the vector of elements:
        let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len);

        return Ok(bx.call_intrinsic(
            "llvm.masked.gather",
            &[llvm_elem_vec_ty, llvm_pointer_vec_ty],
            &[args[1].immediate(), alignment, mask, args[0].immediate()],
        ));
    }

    if name == sym::simd_masked_load {
        // simd_masked_load(mask: <N x i{M}>, pointer: *_ T, values: <N x T>) -> <N x T>
        // * N: number of elements in the input vectors
        // * T: type of the element to load
        // * M: any integer width is supported, will be truncated to i1
        // Loads contiguous elements from memory behind `pointer`, but only for
        // those lanes whose `mask` bit is enabled.
        // The memory addresses corresponding to the “off” lanes are not accessed.

        // The element type of the "mask" argument must be a signed integer type of any width
        let mask_ty = in_ty;
        let (mask_len, mask_elem) = (in_len, in_elem);

        // The second argument must be a pointer matching the element type
        let pointer_ty = args[1].layout.ty;

        // The last argument is a passthrough vector providing values for disabled lanes
        let values_ty = args[2].layout.ty;
        let (values_len, values_elem) = require_simd!(values_ty, SimdThird);

        require_simd!(ret_ty, SimdReturn);

        // Of the same length:
        require!(
            values_len == mask_len,
            InvalidMonomorphization::ThirdArgumentLength {
                span,
                name,
                in_len: mask_len,
                in_ty: mask_ty,
                arg_ty: values_ty,
                out_len: values_len
            }
        );

        // The return type must match the last argument type
        require!(
            ret_ty == values_ty,
            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty: values_ty, ret_ty }
        );

        require!(
            matches!(
                *pointer_ty.kind(),
                ty::RawPtr(p_ty, _) if p_ty == values_elem && p_ty.kind() == values_elem.kind()
            ),
            InvalidMonomorphization::ExpectedElementType {
                span,
                name,
                expected_element: values_elem,
                second_arg: pointer_ty,
                in_elem: values_elem,
                in_ty: values_ty,
                mutability: ExpectedPointerMutability::Not,
            }
        );

        let m_elem_bitwidth = require_int_or_uint_ty!(
            mask_elem.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: mask_elem }
        );

        let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);

        // Alignment of T, must be a constant integer value:
        let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);

        let llvm_pointer = bx.type_ptr();

        // Type of the vector of elements:
        let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len);

        return Ok(bx.call_intrinsic(
            "llvm.masked.load",
            &[llvm_elem_vec_ty, llvm_pointer],
            &[args[1].immediate(), alignment, mask, args[2].immediate()],
        ));
    }

    if name == sym::simd_masked_store {
        // simd_masked_store(mask: <N x i{M}>, pointer: *mut T, values: <N x T>) -> ()
        // * N: number of elements in the input vectors
        // * T: type of the element to load
        // * M: any integer width is supported, will be truncated to i1
        // Stores contiguous elements to memory behind `pointer`, but only for
        // those lanes whose `mask` bit is enabled.
        // The memory addresses corresponding to the “off” lanes are not accessed.

        // The element type of the "mask" argument must be a signed integer type of any width
        let mask_ty = in_ty;
        let (mask_len, mask_elem) = (in_len, in_elem);

        // The second argument must be a pointer matching the element type
        let pointer_ty = args[1].layout.ty;

        // The last argument specifies the values to store to memory
        let values_ty = args[2].layout.ty;
        let (values_len, values_elem) = require_simd!(values_ty, SimdThird);

        // Of the same length:
        require!(
            values_len == mask_len,
            InvalidMonomorphization::ThirdArgumentLength {
                span,
                name,
                in_len: mask_len,
                in_ty: mask_ty,
                arg_ty: values_ty,
                out_len: values_len
            }
        );

        // The second argument must be a mutable pointer type matching the element type
        require!(
            matches!(
                *pointer_ty.kind(),
                ty::RawPtr(p_ty, p_mutbl)
                    if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
            ),
            InvalidMonomorphization::ExpectedElementType {
                span,
                name,
                expected_element: values_elem,
                second_arg: pointer_ty,
                in_elem: values_elem,
                in_ty: values_ty,
                mutability: ExpectedPointerMutability::Mut,
            }
        );

        let m_elem_bitwidth = require_int_or_uint_ty!(
            mask_elem.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: mask_elem }
        );

        let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);

        // Alignment of T, must be a constant integer value:
        let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);

        let llvm_pointer = bx.type_ptr();

        // Type of the vector of elements:
        let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len);

        return Ok(bx.call_intrinsic(
            "llvm.masked.store",
            &[llvm_elem_vec_ty, llvm_pointer],
            &[args[2].immediate(), args[1].immediate(), alignment, mask],
        ));
    }

    if name == sym::simd_scatter {
        // simd_scatter(values: <N x T>, pointers: <N x *mut T>,
        //             mask: <N x i{M}>) -> ()
        // * N: number of elements in the input vectors
        // * T: type of the element to load
        // * M: any integer width is supported, will be truncated to i1

        // All types must be simd vector types
        // The second argument must be a simd vector with an element type that's a pointer
        // to the element type of the first argument
        let (_, element_ty0) = require_simd!(in_ty, SimdFirst);
        let (element_len1, element_ty1) = require_simd!(args[1].layout.ty, SimdSecond);
        let (element_len2, element_ty2) = require_simd!(args[2].layout.ty, SimdThird);

        // Of the same length:
        require!(
            in_len == element_len1,
            InvalidMonomorphization::SecondArgumentLength {
                span,
                name,
                in_len,
                in_ty,
                arg_ty: args[1].layout.ty,
                out_len: element_len1
            }
        );
        require!(
            in_len == element_len2,
            InvalidMonomorphization::ThirdArgumentLength {
                span,
                name,
                in_len,
                in_ty,
                arg_ty: args[2].layout.ty,
                out_len: element_len2
            }
        );

        require!(
            matches!(
                *element_ty1.kind(),
                ty::RawPtr(p_ty, p_mutbl)
                    if p_ty == in_elem && p_mutbl.is_mut() && p_ty.kind() == element_ty0.kind()
            ),
            InvalidMonomorphization::ExpectedElementType {
                span,
                name,
                expected_element: element_ty1,
                second_arg: args[1].layout.ty,
                in_elem,
                in_ty,
                mutability: ExpectedPointerMutability::Mut,
            }
        );

        // The element type of the third argument must be an integer type of any width:
        let mask_elem_bitwidth = require_int_or_uint_ty!(
            element_ty2.kind(),
            InvalidMonomorphization::MaskWrongElementType { span, name, ty: element_ty2 }
        );

        // Alignment of T, must be a constant integer value:
        let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32);

        // Truncate the mask vector to a vector of i1s:
        let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len);

        // Type of the vector of pointers:
        let llvm_pointer_vec_ty = llvm_vector_ty(bx, element_ty1, in_len);

        // Type of the vector of elements:
        let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len);

        return Ok(bx.call_intrinsic(
            "llvm.masked.scatter",
            &[llvm_elem_vec_ty, llvm_pointer_vec_ty],
            &[args[0].immediate(), args[1].immediate(), alignment, mask],
        ));
    }

    macro_rules! arith_red {
        ($name:ident : $integer_reduce:ident, $float_reduce:ident, $ordered:expr, $op:ident,
         $identity:expr) => {
            if name == sym::$name {
                require!(
                    ret_ty == in_elem,
                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
                );
                return match in_elem.kind() {
                    ty::Int(_) | ty::Uint(_) => {
                        let r = bx.$integer_reduce(args[0].immediate());
                        if $ordered {
                            // if overflow occurs, the result is the
                            // mathematical result modulo 2^n:
                            Ok(bx.$op(args[1].immediate(), r))
                        } else {
                            Ok(bx.$integer_reduce(args[0].immediate()))
                        }
                    }
                    ty::Float(f) => {
                        let acc = if $ordered {
                            // ordered arithmetic reductions take an accumulator
                            args[1].immediate()
                        } else {
                            // unordered arithmetic reductions use the identity accumulator
                            match f.bit_width() {
                                32 => bx.const_real(bx.type_f32(), $identity),
                                64 => bx.const_real(bx.type_f64(), $identity),
                                v => return_error!(
                                    InvalidMonomorphization::UnsupportedSymbolOfSize {
                                        span,
                                        name,
                                        symbol: sym::$name,
                                        in_ty,
                                        in_elem,
                                        size: v,
                                        ret_ty
                                    }
                                ),
                            }
                        };
                        Ok(bx.$float_reduce(acc, args[0].immediate()))
                    }
                    _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
                        span,
                        name,
                        symbol: sym::$name,
                        in_ty,
                        in_elem,
                        ret_ty
                    }),
                };
            }
        };
    }

    arith_red!(simd_reduce_add_ordered: vector_reduce_add, vector_reduce_fadd, true, add, -0.0);
    arith_red!(simd_reduce_mul_ordered: vector_reduce_mul, vector_reduce_fmul, true, mul, 1.0);
    arith_red!(
        simd_reduce_add_unordered: vector_reduce_add,
        vector_reduce_fadd_reassoc,
        false,
        add,
        -0.0
    );
    arith_red!(
        simd_reduce_mul_unordered: vector_reduce_mul,
        vector_reduce_fmul_reassoc,
        false,
        mul,
        1.0
    );

    macro_rules! minmax_red {
        ($name:ident: $int_red:ident, $float_red:ident) => {
            if name == sym::$name {
                require!(
                    ret_ty == in_elem,
                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
                );
                return match in_elem.kind() {
                    ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)),
                    ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)),
                    ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())),
                    _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
                        span,
                        name,
                        symbol: sym::$name,
                        in_ty,
                        in_elem,
                        ret_ty
                    }),
                };
            }
        };
    }

    minmax_red!(simd_reduce_min: vector_reduce_min, vector_reduce_fmin);
    minmax_red!(simd_reduce_max: vector_reduce_max, vector_reduce_fmax);

    macro_rules! bitwise_red {
        ($name:ident : $red:ident, $boolean:expr) => {
            if name == sym::$name {
                let input = if !$boolean {
                    require!(
                        ret_ty == in_elem,
                        InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
                    );
                    args[0].immediate()
                } else {
                    let bitwidth = match in_elem.kind() {
                        ty::Int(i) => {
                            i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size().bits())
                        }
                        ty::Uint(i) => {
                            i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size().bits())
                        }
                        _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
                            span,
                            name,
                            symbol: sym::$name,
                            in_ty,
                            in_elem,
                            ret_ty
                        }),
                    };

                    vector_mask_to_bitmask(bx, args[0].immediate(), bitwidth, in_len as _)
                };
                return match in_elem.kind() {
                    ty::Int(_) | ty::Uint(_) => {
                        let r = bx.$red(input);
                        Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) })
                    }
                    _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
                        span,
                        name,
                        symbol: sym::$name,
                        in_ty,
                        in_elem,
                        ret_ty
                    }),
                };
            }
        };
    }

    bitwise_red!(simd_reduce_and: vector_reduce_and, false);
    bitwise_red!(simd_reduce_or: vector_reduce_or, false);
    bitwise_red!(simd_reduce_xor: vector_reduce_xor, false);
    bitwise_red!(simd_reduce_all: vector_reduce_and, true);
    bitwise_red!(simd_reduce_any: vector_reduce_or, true);

    if name == sym::simd_cast_ptr {
        let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
        require!(
            in_len == out_len,
            InvalidMonomorphization::ReturnLengthInputType {
                span,
                name,
                in_len,
                in_ty,
                ret_ty,
                out_len
            }
        );

        match in_elem.kind() {
            ty::RawPtr(p_ty, _) => {
                let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                    bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
                });
                require!(
                    metadata.is_unit(),
                    InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
                );
            }
            _ => {
                return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
            }
        }
        match out_elem.kind() {
            ty::RawPtr(p_ty, _) => {
                let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                    bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
                });
                require!(
                    metadata.is_unit(),
                    InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
                );
            }
            _ => {
                return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
            }
        }

        return Ok(args[0].immediate());
    }

    if name == sym::simd_expose_provenance {
        let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
        require!(
            in_len == out_len,
            InvalidMonomorphization::ReturnLengthInputType {
                span,
                name,
                in_len,
                in_ty,
                ret_ty,
                out_len
            }
        );

        match in_elem.kind() {
            ty::RawPtr(_, _) => {}
            _ => {
                return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
            }
        }
        match out_elem.kind() {
            ty::Uint(ty::UintTy::Usize) => {}
            _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }),
        }

        return Ok(bx.ptrtoint(args[0].immediate(), llret_ty));
    }

    if name == sym::simd_with_exposed_provenance {
        let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
        require!(
            in_len == out_len,
            InvalidMonomorphization::ReturnLengthInputType {
                span,
                name,
                in_len,
                in_ty,
                ret_ty,
                out_len
            }
        );

        match in_elem.kind() {
            ty::Uint(ty::UintTy::Usize) => {}
            _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }),
        }
        match out_elem.kind() {
            ty::RawPtr(_, _) => {}
            _ => {
                return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
            }
        }

        return Ok(bx.inttoptr(args[0].immediate(), llret_ty));
    }

    if name == sym::simd_cast || name == sym::simd_as {
        let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
        require!(
            in_len == out_len,
            InvalidMonomorphization::ReturnLengthInputType {
                span,
                name,
                in_len,
                in_ty,
                ret_ty,
                out_len
            }
        );
        // casting cares about nominal type, not just structural type
        if in_elem == out_elem {
            return Ok(args[0].immediate());
        }

        #[derive(Copy, Clone)]
        enum Sign {
            Unsigned,
            Signed,
        }
        use Sign::*;

        enum Style {
            Float,
            Int(Sign),
            Unsupported,
        }

        let (in_style, in_width) = match in_elem.kind() {
            // vectors of pointer-sized integers should've been
            // disallowed before here, so this unwrap is safe.
            ty::Int(i) => (
                Style::Int(Signed),
                i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
            ),
            ty::Uint(u) => (
                Style::Int(Unsigned),
                u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
            ),
            ty::Float(f) => (Style::Float, f.bit_width()),
            _ => (Style::Unsupported, 0),
        };
        let (out_style, out_width) = match out_elem.kind() {
            ty::Int(i) => (
                Style::Int(Signed),
                i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
            ),
            ty::Uint(u) => (
                Style::Int(Unsigned),
                u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
            ),
            ty::Float(f) => (Style::Float, f.bit_width()),
            _ => (Style::Unsupported, 0),
        };

        match (in_style, out_style) {
            (Style::Int(sign), Style::Int(_)) => {
                return Ok(match in_width.cmp(&out_width) {
                    Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty),
                    Ordering::Equal => args[0].immediate(),
                    Ordering::Less => match sign {
                        Sign::Signed => bx.sext(args[0].immediate(), llret_ty),
                        Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty),
                    },
                });
            }
            (Style::Int(Sign::Signed), Style::Float) => {
                return Ok(bx.sitofp(args[0].immediate(), llret_ty));
            }
            (Style::Int(Sign::Unsigned), Style::Float) => {
                return Ok(bx.uitofp(args[0].immediate(), llret_ty));
            }
            (Style::Float, Style::Int(sign)) => {
                return Ok(match (sign, name == sym::simd_as) {
                    (Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty),
                    (Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty),
                    (_, true) => bx.cast_float_to_int(
                        matches!(sign, Sign::Signed),
                        args[0].immediate(),
                        llret_ty,
                    ),
                });
            }
            (Style::Float, Style::Float) => {
                return Ok(match in_width.cmp(&out_width) {
                    Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty),
                    Ordering::Equal => args[0].immediate(),
                    Ordering::Less => bx.fpext(args[0].immediate(), llret_ty),
                });
            }
            _ => { /* Unsupported. Fallthrough. */ }
        }
        return_error!(InvalidMonomorphization::UnsupportedCast {
            span,
            name,
            in_ty,
            in_elem,
            ret_ty,
            out_elem
        });
    }
    macro_rules! arith_binary {
        ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => {
            $(if name == sym::$name {
                match in_elem.kind() {
                    $($(ty::$p(_))|* => {
                        return Ok(bx.$call(args[0].immediate(), args[1].immediate()))
                    })*
                    _ => {},
                }
                return_error!(
                    InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem }
                );
            })*
        }
    }
    arith_binary! {
        simd_add: Uint, Int => add, Float => fadd;
        simd_sub: Uint, Int => sub, Float => fsub;
        simd_mul: Uint, Int => mul, Float => fmul;
        simd_div: Uint => udiv, Int => sdiv, Float => fdiv;
        simd_rem: Uint => urem, Int => srem, Float => frem;
        simd_shl: Uint, Int => shl;
        simd_shr: Uint => lshr, Int => ashr;
        simd_and: Uint, Int => and;
        simd_or: Uint, Int => or;
        simd_xor: Uint, Int => xor;
        simd_fmax: Float => maxnum;
        simd_fmin: Float => minnum;

    }
    macro_rules! arith_unary {
        ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => {
            $(if name == sym::$name {
                match in_elem.kind() {
                    $($(ty::$p(_))|* => {
                        return Ok(bx.$call(args[0].immediate()))
                    })*
                    _ => {},
                }
                return_error!(
                    InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem }
                );
            })*
        }
    }
    arith_unary! {
        simd_neg: Int => neg, Float => fneg;
    }

    // Unary integer intrinsics
    if matches!(
        name,
        sym::simd_bswap
            | sym::simd_bitreverse
            | sym::simd_ctlz
            | sym::simd_ctpop
            | sym::simd_cttz
            | sym::simd_funnel_shl
            | sym::simd_funnel_shr
    ) {
        let vec_ty = bx.cx.type_vector(
            match *in_elem.kind() {
                ty::Int(i) => bx.cx.type_int_from_ty(i),
                ty::Uint(i) => bx.cx.type_uint_from_ty(i),
                _ => return_error!(InvalidMonomorphization::UnsupportedOperation {
                    span,
                    name,
                    in_ty,
                    in_elem
                }),
            },
            in_len as u64,
        );
        let llvm_intrinsic = match name {
            sym::simd_bswap => "llvm.bswap",
            sym::simd_bitreverse => "llvm.bitreverse",
            sym::simd_ctlz => "llvm.ctlz",
            sym::simd_ctpop => "llvm.ctpop",
            sym::simd_cttz => "llvm.cttz",
            sym::simd_funnel_shl => "llvm.fshl",
            sym::simd_funnel_shr => "llvm.fshr",
            _ => unreachable!(),
        };
        let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();

        return match name {
            // byte swap is no-op for i8/u8
            sym::simd_bswap if int_size == 8 => Ok(args[0].immediate()),
            sym::simd_ctlz | sym::simd_cttz => {
                // for the (int, i1 immediate) pair, the second arg adds `(0, true) => poison`
                let dont_poison_on_zero = bx.const_int(bx.type_i1(), 0);
                Ok(bx.call_intrinsic(
                    llvm_intrinsic,
                    &[vec_ty],
                    &[args[0].immediate(), dont_poison_on_zero],
                ))
            }
            sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctpop => {
                // simple unary argument cases
                Ok(bx.call_intrinsic(llvm_intrinsic, &[vec_ty], &[args[0].immediate()]))
            }
            sym::simd_funnel_shl | sym::simd_funnel_shr => Ok(bx.call_intrinsic(
                llvm_intrinsic,
                &[vec_ty],
                &[args[0].immediate(), args[1].immediate(), args[2].immediate()],
            )),
            _ => unreachable!(),
        };
    }

    if name == sym::simd_arith_offset {
        // This also checks that the first operand is a ptr type.
        let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| {
            span_bug!(span, "must be called with a vector of pointer types as first argument")
        });
        let layout = bx.layout_of(pointee);
        let ptrs = args[0].immediate();
        // The second argument must be a ptr-sized integer.
        // (We don't care about the signedness, this is wrapping anyway.)
        let (_offsets_len, offsets_elem) = args[1].layout.ty.simd_size_and_type(bx.tcx());
        if !matches!(offsets_elem.kind(), ty::Int(ty::IntTy::Isize) | ty::Uint(ty::UintTy::Usize)) {
            span_bug!(
                span,
                "must be called with a vector of pointer-sized integers as second argument"
            );
        }
        let offsets = args[1].immediate();

        return Ok(bx.gep(bx.backend_type(layout), ptrs, &[offsets]));
    }

    if name == sym::simd_saturating_add || name == sym::simd_saturating_sub {
        let lhs = args[0].immediate();
        let rhs = args[1].immediate();
        let is_add = name == sym::simd_saturating_add;
        let (signed, elem_ty) = match *in_elem.kind() {
            ty::Int(i) => (true, bx.cx.type_int_from_ty(i)),
            ty::Uint(i) => (false, bx.cx.type_uint_from_ty(i)),
            _ => {
                return_error!(InvalidMonomorphization::ExpectedVectorElementType {
                    span,
                    name,
                    expected_element: args[0].layout.ty.simd_size_and_type(bx.tcx()).1,
                    vector_type: args[0].layout.ty
                });
            }
        };
        let llvm_intrinsic = format!(
            "llvm.{}{}.sat",
            if signed { 's' } else { 'u' },
            if is_add { "add" } else { "sub" },
        );
        let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);

        return Ok(bx.call_intrinsic(llvm_intrinsic, &[vec_ty], &[lhs, rhs]));
    }

    span_bug!(span, "unknown SIMD intrinsic");
}
