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.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;
        // 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,
    );

    let fnc_tree =
        rustc_middle::ty::fnc_typetrees(tcx, fn_source.ty(tcx, TypingEnv::fully_monomorphized()));

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

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");
}
