EnzymeAD / Enzyme.jl

Julia bindings for the Enzyme automatic differentiator
https://enzyme.mit.edu
MIT License
438 stars 62 forks source link

Compilation Error: Unsafe copyto! #1681

Closed jlk9 closed 1 month ago

jlk9 commented 1 month ago

This code produces a compilation error:

using Enzyme
using EnzymeCore
# Required presently
Enzyme.API.runtimeActivity!(true)
Enzyme.API.looseTypeAnalysis!(true)
Enzyme.API.maxtypeoffset!(2032)

mutable struct OuterStruct{S, T}
    a:: S
    b:: T
end

struct InnerStruct{F}
    func :: F

    function InnerStruct(func::F) where {F}
        return new{F}(func)
    end
end

for dir in (:a, :b)
    extract_side = Symbol(:extract_, dir)
    @eval begin
        @inline $extract_side(bc) = bc.$dir
        @inline $extract_side(bc::Tuple) = map($extract_side, bc)
    end
end

@inline extract(bc, ::Val{:a_and_a}) = (extract_a(bc), extract_a(bc))
@inline extract(bc, ::Val{:a_and_b})  = (extract_a(bc), extract_b(bc))

"Fill halo regions in ``x``, ``y``, and ``z`` for a given field's data."
function tuple_things!(inner, args...; kwargs...)

    sides = [:a_and_a, :a_and_b]
    perm  = [2,1]
    sides = sides[perm]

    inner = Tuple(extract(inner, Val(side)) for side in sides)
    number_of_tasks = length(sides)

    return nothing
end

@testset "Enzyme on advection and diffusion WITH flux boundary condition" begin

    b = InnerStruct(1.0)
    thing  = OuterStruct((1,), tuple(b))
    dthing = Enzyme.make_zero(thing)

    dc²_dκ = autodiff(Enzyme.Reverse,
                      tuple_things!,
                      Duplicated(thing, dthing),
                      Duplicated((1,2), (0,0)),
                      Duplicated((3,4), (0,0)))
end

@wsmoses

wsmoses commented 1 month ago
using Enzyme

function f!(out, inp)
    Base._unsafe_copyto!(out, 1, inp, 1, 1)
    return nothing
end

out = Tuple{Tuple{Int64}, Tuple{Any}}[]

inp = Tuple{Tuple{Int64}, Tuple{Float64}}[]

autodiff(Enzyme.Reverse,
                  f!,
                  Duplicated(out, out),
                  Duplicated(inp, inp)
                  )
Current scope: 
; Function Attrs: mustprogress willreturn
define internal fastcc void @preprocess_julia__unsafe_copyto__1914({} addrspace(10)* noundef nonnull align 16 dereferenceable(40) "enzyme_type"="{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}" "enzymejl_parmtype"="4504960848" "enzymejl_parmtype_ref"="2" %0, {} addrspace(10)* noundef nonnull align 16 dereferenceable(40) "enzyme_type"="{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}" "enzymejl_parmtype"="4503151760" "enzymejl_parmtype_ref"="2" %1) unnamed_addr #11 !dbg !97 {
top:
  %2 = call {}*** @julia.get_pgcstack() #12
  %current_task181 = getelementptr inbounds {}**, {}*** %2, i64 -14
  %current_task1 = bitcast {}*** %current_task181 to {}**
  %ptls_field82 = getelementptr inbounds {}**, {}*** %2, i64 2
  %3 = bitcast {}*** %ptls_field82 to i64***
  %ptls_load8384 = load i64**, i64*** %3, align 8, !tbaa !12
  %4 = getelementptr inbounds i64*, i64** %ptls_load8384, i64 2
  %safepoint = load i64*, i64** %4, align 8, !tbaa !16
  fence syncscope("singlethread") seq_cst
  call void @julia.safepoint(i64* %safepoint) #12, !dbg !98
  fence syncscope("singlethread") seq_cst
  %5 = addrspacecast {} addrspace(10)* %0 to {} addrspace(11)*, !dbg !99
  %6 = call nonnull {}* @julia.pointer_from_objref({} addrspace(11)* noundef %5) #13, !dbg !99
  %7 = bitcast {}* %6 to i8**, !dbg !99
  %arrayptr = load i8*, i8** %7, align 8, !dbg !99, !tbaa !31, !alias.scope !34, !noalias !37, !nonnull !11
  %8 = addrspacecast {} addrspace(10)* %1 to {} addrspace(11)*, !dbg !102
  %9 = call nonnull {}* @julia.pointer_from_objref({} addrspace(11)* noundef %8) #13, !dbg !102
  %10 = bitcast {}* %9 to i8**, !dbg !102
  %arrayptr3 = load i8*, i8** %10, align 8, !dbg !102, !tbaa !31, !alias.scope !34, !noalias !37, !nonnull !11
  %11 = icmp uge i8* %arrayptr, %arrayptr3, !dbg !105
  %12 = getelementptr i8, i8* %arrayptr3, i64 1
  %13 = icmp uge i8* %12, %arrayptr
  %or.cond = and i1 %11, %13, !dbg !107
  br i1 %or.cond, label %L85.preheader, label %L175.preheader, !dbg !107

L85.preheader:                                    ; preds = %top
  %14 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(11)*
  %15 = getelementptr inbounds {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %14, i64 5
  %16 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(13)* addrspace(11)*
  %17 = addrspacecast {} addrspace(10)* %0 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*
  %arrayflags_ptr36 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %17, i64 0, i32 2
  %arrayflags37.pre = load i16, i16 addrspace(11)* %arrayflags_ptr36, align 16, !dbg !108, !tbaa !65, !alias.scope !34, !noalias !37
  %18 = and i16 %arrayflags37.pre, 3
  %has_owner38 = icmp eq i16 %18, 3
  %19 = addrspacecast {} addrspace(10)* %1 to i8 addrspace(13)* addrspace(11)*, !dbg !110
  %arrayptr3488.pre2 = load i8 addrspace(13)*, i8 addrspace(13)* addrspace(11)* %19, align 16, !dbg !110, !tbaa !31, !alias.scope !111, !noalias !37
  br i1 %has_owner38, label %array_owned39, label %merge_own40, !dbg !108

L175.preheader:                                   ; preds = %top
  %20 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(11)*
  %21 = getelementptr inbounds {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %20, i64 5
  %22 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(13)* addrspace(11)*
  %23 = addrspacecast {} addrspace(10)* %0 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*
  %arrayflags_ptr = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %23, i64 0, i32 2
  %arrayflags.pre = load i16, i16 addrspace(11)* %arrayflags_ptr, align 16, !dbg !114, !tbaa !65, !alias.scope !34, !noalias !37
  %24 = and i16 %arrayflags.pre, 3
  %has_owner = icmp eq i16 %24, 3
  %25 = addrspacecast {} addrspace(10)* %1 to i8 addrspace(13)* addrspace(11)*, !dbg !116
  %arrayptr1185.pre1 = load i8 addrspace(13)*, i8 addrspace(13)* addrspace(11)* %25, align 16, !dbg !116, !tbaa !31, !alias.scope !111, !noalias !37
  br i1 %has_owner, label %array_owned, label %merge_own, !dbg !114

L249:                                             ; preds = %merge_own40, %merge_own
  ret void, !dbg !117

array_owned:                                      ; preds = %L175.preheader
  %external_owner = load {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %21, align 8, !dbg !114, !tbaa !16, !alias.scope !78, !noalias !79, !nonnull !11, !dereferenceable !80, !align !81
  br label %merge_own, !dbg !114

merge_own:                                        ; preds = %array_owned, %L175.preheader
  %data_owner = phi {} addrspace(10)* [ %0, %L175.preheader ], [ %external_owner, %array_owned ], !dbg !114
  %arrayptr13 = load {} addrspace(10)* addrspace(13)*, {} addrspace(10)* addrspace(13)* addrspace(11)* %22, align 16, !dbg !114, !tbaa !31, !alias.scope !111, !noalias !37, !nonnull !11
  %box = call noalias nonnull dereferenceable(16) "enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 16, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4503149456 to {}*) to {} addrspace(10)*)) #14, !dbg !114
  %26 = bitcast {} addrspace(10)* %box to i8 addrspace(10)*, !dbg !114
  call void @llvm.memmove.p10i8.p13i8.i64(i8 addrspace(10)* nocapture nofree noundef nonnull align 8 dereferenceable(16) %26, i8 addrspace(13)* noundef align 1 dereferenceable(16) %arrayptr1185.pre1, i64 noundef 16, i1 noundef false) #12, !dbg !114
  store atomic {} addrspace(10)* %box, {} addrspace(10)* addrspace(13)* %arrayptr13 release, align 8, !dbg !114, !tbaa !82, !alias.scope !85, !noalias !118
  call void ({} addrspace(10)*, ...) @julia.write_barrier({} addrspace(10)* noundef nonnull %data_owner, {} addrspace(10)* nofree nonnull %box) #15, !dbg !114
  br label %L249, !dbg !119

array_owned39:                                    ; preds = %L85.preheader
  %external_owner41 = load {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %15, align 8, !dbg !108, !tbaa !16, !alias.scope !78, !noalias !79, !nonnull !11, !dereferenceable !80, !align !81
  br label %merge_own40, !dbg !108

merge_own40:                                      ; preds = %array_owned39, %L85.preheader
  %data_owner42 = phi {} addrspace(10)* [ %0, %L85.preheader ], [ %external_owner41, %array_owned39 ], !dbg !108
  %arrayptr44 = load {} addrspace(10)* addrspace(13)*, {} addrspace(10)* addrspace(13)* addrspace(11)* %16, align 16, !dbg !108, !tbaa !31, !alias.scope !111, !noalias !37, !nonnull !11
  %box46 = call noalias nonnull dereferenceable(16) "enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 16, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4503149456 to {}*) to {} addrspace(10)*)) #14, !dbg !108
  %27 = bitcast {} addrspace(10)* %box46 to i8 addrspace(10)*, !dbg !108
  call void @llvm.memmove.p10i8.p13i8.i64(i8 addrspace(10)* nocapture nofree noundef nonnull align 8 dereferenceable(16) %27, i8 addrspace(13)* noundef align 1 dereferenceable(16) %arrayptr3488.pre2, i64 noundef 16, i1 noundef false) #12, !dbg !108
  store atomic {} addrspace(10)* %box46, {} addrspace(10)* addrspace(13)* %arrayptr44 release, align 8, !dbg !108, !tbaa !82, !alias.scope !85, !noalias !118
  call void ({} addrspace(10)*, ...) @julia.write_barrier({} addrspace(10)* noundef nonnull %data_owner42, {} addrspace(10)* nofree nonnull %box46) #15, !dbg !108
  br label %L249, !dbg !120
}

 Type analysis state: 
<analysis>
  %ptls_field82 = getelementptr inbounds {}**, {}*** %2, i64 2: {}, intvals: {}
  %9 = call nonnull {}* @julia.pointer_from_objref({} addrspace(11)* noundef %8) #13, !dbg !37: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %12 = getelementptr i8, i8* %arrayptr3, i64 1: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Float@double}, intvals: {}
  %6 = call nonnull {}* @julia.pointer_from_objref({} addrspace(11)* noundef %5) #13, !dbg !19: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %15 = getelementptr inbounds {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %14, i64 5: {[-1]:Pointer}, intvals: {}
  %current_task181 = getelementptr inbounds {}**, {}*** %2, i64 -14: {}, intvals: {}
  %4 = getelementptr inbounds i64*, i64** %ptls_load8384, i64 2: {[-1]:Pointer}, intvals: {}
  %21 = getelementptr inbounds {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %20, i64 5: {[-1]:Pointer}, intvals: {}
  %arrayflags_ptr = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %23, i64 0, i32 2: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}, intvals: {}
  %arrayflags_ptr36 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %17, i64 0, i32 2: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}, intvals: {}
  %box = call noalias nonnull dereferenceable(16) "enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 16, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4503149456 to {}*) to {} addrspace(10)*)) #14, !dbg !57: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
  %box46 = call noalias nonnull dereferenceable(16) "enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 16, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4503149456 to {}*) to {} addrspace(10)*)) #14, !dbg !46: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
{} addrspace(10)* %0: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
{} addrspace(10)* %1: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %data_owner = phi {} addrspace(10)* [ %0, %L175.preheader ], [ %external_owner, %array_owned ], !dbg !57: {}, intvals: {}
  %2 = call {}*** @julia.get_pgcstack() #12: {}, intvals: {}
  %18 = and i16 %arrayflags37.pre, 3: {[-1]:Integer}, intvals: {}
  %or.cond = and i1 %11, %13, !dbg !45: {[-1]:Integer}, intvals: {}
  %has_owner = icmp eq i16 %24, 3: {[-1]:Integer}, intvals: {}
  %24 = and i16 %arrayflags.pre, 3: {[-1]:Integer}, intvals: {}
  %13 = icmp uge i8* %12, %arrayptr: {[-1]:Integer}, intvals: {}
  %11 = icmp uge i8* %arrayptr, %arrayptr3, !dbg !40: {[-1]:Integer}, intvals: {}
  %has_owner38 = icmp eq i16 %18, 3: {[-1]:Integer}, intvals: {}
i64 1: {[-1]:Integer}, intvals: {1,}
i16 3: {[-1]:Integer}, intvals: {3,}
  %arrayptr13 = load {} addrspace(10)* addrspace(13)*, {} addrspace(10)* addrspace(13)* addrspace(11)* %22, align 16, !dbg !57, !tbaa !26, !alias.scope !54, !noalias !32, !nonnull !11: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]:Pointer}, intvals: {}
  %14 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayflags.pre = load i16, i16 addrspace(11)* %arrayflags_ptr, align 16, !dbg !57, !tbaa !49, !alias.scope !29, !noalias !32: {[-1]:Integer}, intvals: {}
  %7 = bitcast {}* %6 to i8**, !dbg !19: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayptr = load i8*, i8** %7, align 8, !dbg !19, !tbaa !26, !alias.scope !29, !noalias !32, !nonnull !11: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]:Pointer}, intvals: {}
  %19 = addrspacecast {} addrspace(10)* %1 to i8 addrspace(13)* addrspace(11)*, !dbg !51: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayflags37.pre = load i16, i16 addrspace(11)* %arrayflags_ptr36, align 16, !dbg !46, !tbaa !49, !alias.scope !29, !noalias !32: {[-1]:Integer}, intvals: {}
  %10 = bitcast {}* %9 to i8**, !dbg !37: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayptr44 = load {} addrspace(10)* addrspace(13)*, {} addrspace(10)* addrspace(13)* addrspace(11)* %16, align 16, !dbg !46, !tbaa !26, !alias.scope !54, !noalias !32, !nonnull !11: {[-1]:Pointer}, intvals: {}
  %8 = addrspacecast {} addrspace(10)* %1 to {} addrspace(11)*, !dbg !37: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %5 = addrspacecast {} addrspace(10)* %0 to {} addrspace(11)*, !dbg !19: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %external_owner = load {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %21, align 8, !dbg !57, !tbaa !16, !alias.scope !61, !noalias !62, !nonnull !11, !dereferenceable !63, !align !64: {}, intvals: {}
  %17 = addrspacecast {} addrspace(10)* %0 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %3 = bitcast {}*** %ptls_field82 to i64***: {[-1]:Pointer}, intvals: {}
  %arrayptr3488.pre2 = load i8 addrspace(13)*, i8 addrspace(13)* addrspace(11)* %19, align 16, !dbg !51, !tbaa !26, !alias.scope !54, !noalias !32: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
  %current_task1 = bitcast {}*** %current_task181 to {}**: {}, intvals: {}
  %ptls_load8384 = load i64**, i64*** %3, align 8, !tbaa !12: {}, intvals: {}
  %16 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(13)* addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %26 = bitcast {} addrspace(10)* %box to i8 addrspace(10)*, !dbg !57: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
  %23 = addrspacecast {} addrspace(10)* %0 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayptr1185.pre1 = load i8 addrspace(13)*, i8 addrspace(13)* addrspace(11)* %25, align 16, !dbg !59, !tbaa !26, !alias.scope !54, !noalias !32: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
  %safepoint = load i64*, i64** %4, align 8, !tbaa !16: {}, intvals: {}
  %22 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(13)* addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %arrayptr3 = load i8*, i8** %10, align 8, !dbg !37, !tbaa !26, !alias.scope !29, !noalias !32, !nonnull !11: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Float@double}, intvals: {}
  %25 = addrspacecast {} addrspace(10)* %1 to i8 addrspace(13)* addrspace(11)*, !dbg !59: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
  %20 = addrspacecast {} addrspace(10)* %0 to {} addrspace(10)* addrspace(11)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Pointer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}, intvals: {}
</analysis>

Illegal updateAnalysis prev:{[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]:Pointer} new: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Integer, [-1,0,1]:Integer, [-1,0,2]:Integer, [-1,0,3]:Integer, [-1,0,4]:Integer, [-1,0,5]:Integer, [-1,0,6]:Integer, [-1,0,7]:Integer, [-1,0,8]:Float@double}
val:   %arrayptr13 = load {} addrspace(10)* addrspace(13)*, {} addrspace(10)* addrspace(13)* addrspace(11)* %22, align 16, !dbg !57, !tbaa !26, !alias.scope !54, !noalias !32, !nonnull !11 origin=  store atomic {} addrspace(10)* %box, {} addrspace(10)* addrspace(13)* %arrayptr13 release, align 8, !dbg !57, !tbaa !65, !alias.scope !68, !noalias !69
MethodInstance for Base._unsafe_copyto!(::Vector{Tuple{Tuple{Int64}, Tuple{Any}}}, ::Int64, ::Vector{Tuple{Tuple{Int64}, Tuple{Float64}}}, ::Int64, ::Int64)

Caused by:
Stacktrace:
 [1] setindex!
   @ ./array.jl:1021
 [2] _unsafe_copyto!
   @ ./array.jl:299

Stacktrace:
  [1] julia_error(cstr::Cstring, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing}, data2::Ptr{LLVM.API.LLVMOpaqueValue}, B::Ptr{LLVM.API.LLVMOpaqueBuilder})
    @ Enzyme.Compiler ~/git/Enzyme.jl/src/compiler.jl:2161
  [2] EnzymeCreatePrimalAndGradient(logic::Enzyme.Logic, todiff::LLVM.Function, retType::Enzyme.API.CDIFFE_TYPE, constant_args::Vector{Enzyme.API.CDIFFE_TYPE}, TA::Enzyme.TypeAnalysis, returnValue::Bool, dretUsed::Bool, mode::Enzyme.API.CDerivativeMode, width::Int64, additionalArg::Ptr{Nothing}, forceAnonymousTape::Bool, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{Bool}, augmented::Ptr{Nothing}, atomicAdd::Bool)
    @ Enzyme.API ~/git/Enzyme.jl/src/api.jl:156
  [3] enzyme!(job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}, mod::LLVM.Module, primalf::LLVM.Function, TT::Type, mode::Enzyme.API.CDerivativeMode, width::Int64, parallel::Bool, actualRetType::Type, wrap::Bool, modifiedBetween::Tuple{Bool, Bool, Bool}, returnPrimal::Bool, expectedTapeType::Type, loweredArgs::Set{Int64}, boxedArgs::Set{Int64})
    @ Enzyme.Compiler ~/git/Enzyme.jl/src/compiler.jl:3922
  [4] codegen(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}; libraries::Bool, deferred_codegen::Bool, optimize::Bool, toplevel::Bool, strip::Bool, validate::Bool, only_entry::Bool, parent_job::Nothing)
    @ Enzyme.Compiler ~/git/Enzyme.jl/src/compiler.jl:6047
  [5] codegen
    @ ~/git/Enzyme.jl/src/compiler.jl:5355 [inlined]
  [6] _thunk(job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}, postopt::Bool)
    @ Enzyme.Compiler ~/git/Enzyme.jl/src/compiler.jl:6855
  [7] _thunk
    @ ~/git/Enzyme.jl/src/compiler.jl:6855 [inlined]
  [8] cached_compilation
    @ ~/git/Enzyme.jl/src/compiler.jl:6893 [inlined]
  [9] thunkbase(ctx::LLVM.Context, mi::Core.MethodInstance, ::Val{0x0000000000007aef}, ::Type{Const{typeof(f!)}}, ::Type{Const{Nothing}}, tt::Type{Tuple{Duplicated{Vector{Tuple{Tuple{Int64}, Tuple{Any}}}}, Duplicated{Vector{Tuple{Tuple{Int64}, Tuple{Float64}}}}}}, ::Val{Enzyme.API.DEM_ReverseModeCombined}, ::Val{1}, ::Val{(false, false, false)}, ::Val{false}, ::Val{false}, ::Type{FFIABI})
    @ Enzyme.Compiler ~/git/Enzyme.jl/src/compiler.jl:6966
 [10] #s2043#28379
    @ ~/git/Enzyme.jl/src/compiler.jl:7018 [inlined]
 [11] var"#s2043#28379"(FA::Any, A::Any, TT::Any, Mode::Any, ModifiedBetween::Any, width::Any, ReturnPrimal::Any, ShadowInit::Any, World::Any, ABI::Any, ::Any, ::Type, ::Type, ::Type, tt::Any, ::Type, ::Type, ::Type, ::Type, ::Type, ::Any)
    @ Enzyme.Compiler ./none:0
 [12] (::Core.GeneratedFunctionStub)(::UInt64, ::LineNumberNode, ::Any, ::Vararg{Any})
    @ Core ./boot.jl:602
 [13] autodiff
    @ ~/git/Enzyme.jl/src/Enzyme.jl:309 [inlined]
 [14] autodiff
    @ ~/git/Enzyme.jl/src/Enzyme.jl:338 [inlined]
 [15] autodiff(::ReverseMode{false, FFIABI, false}, ::typeof(f!), ::Duplicated{Vector{Tuple{Tuple{Int64}, Tuple{Any}}}}, ::Duplicated{Vector{Tuple{Tuple{Int64}, Tuple{Float64}}}})
    @ Enzyme ~/git/Enzyme.jl/src/Enzyme.jl:323
 [16] top-level scope
    @ ~/git/Enzyme.jl/cop.jl:12
in expression starting at /Users/wmoses/git/Enzyme.jl/cop.jl:12