EnzymeAD / Enzyme.jl

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

Sum of Int with floats fails #708

Closed jgreener64 closed 6 months ago

jgreener64 commented 1 year ago

I am on Julia 1.8.5 and Enzyme main (73285ce). The following works:

using Enzyme

f1(x) = sum([ifelse(i > 0, i, zero(i)) for i in x])

x = randn(5)
dx = zero(x)

autodiff(Reverse, f1, Active, Duplicated(x, dx))

However if I specify integer zero, it errors:

f2(x) = sum([ifelse(i > 0, i, 0) for i in x])

autodiff(Reverse, f2, Active, Duplicated(x, dx))

This is not ideal coding style since the intermediate vector is the non-concrete Vector{Real}, however the function does run fine without gradients. The error:

ERROR: Enzyme compilation failed due to illegal type analysis.
Current scope:
; Function Attrs: mustprogress willreturn
define nonnull {} addrspace(10)* @preprocess_julia_f2_5740_inner.1({} addrspace(10)* nonnull writeonly align 16 dereferenceable(40) %0) local_unnamed_addr #24 !dbg !741 {
entry:
  %1 = call {}*** @julia.get_pgcstack()
  %2 = bitcast {}*** %1 to {}**
  %3 = getelementptr inbounds {}*, {}** %2, i64 -12
  %4 = getelementptr inbounds {}*, {}** %3, i64 14
  %5 = bitcast {}** %4 to i8**
  %6 = load i8*, i8** %5, align 8
  %7 = call noalias nonnull dereferenceable(8) dereferenceable_or_null(8) {} addrspace(10)* @jl_gc_alloc_typed(i8* %6, i64 8, {} addrspace(10)* addrspacecast ({}* inttoptr (i64 1907595642928 to {}*) to {} addrspace(10)*)), !enzyme_fromstack !742
  %8 = bitcast {} addrspace(10)* %7 to { {} addrspace(10)* } addrspace(10)*, !enzyme_caststack !4
  %9 = bitcast { {} addrspace(10)* } addrspace(10)* %8 to i8 addrspace(10)*
  %10 = addrspacecast i8 addrspace(10)* %9 to i8*
  call void @llvm.lifetime.start.p0i8(i64 noundef 8, i8* noundef nonnull align 8 dereferenceable(8) %10) #25
  %11 = call {}*** @julia.get_pgcstack() #25
  %.fca.0.gep = getelementptr { {} addrspace(10)* }, { {} addrspace(10)* } addrspace(10)* %8, i64 0, i32 0, !dbg !743
  store {} addrspace(10)* %0, {} addrspace(10)* addrspace(10)* %.fca.0.gep, align 8, !dbg !743
  call void ({} addrspace(10)*, ...) @julia.write_barrier({} addrspace(10)* %7, {} addrspace(10)* %0), !dbg !743
  %12 = addrspacecast { {} addrspace(10)* } addrspace(10)* %8 to { {} addrspace(10)* } addrspace(11)*, !dbg !743
  %13 = call fastcc nonnull {} addrspace(10)* @julia_collect_5760({ {} addrspace(10)* } addrspace(11)* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) %12) #26, !dbg !743
  %14 = call {} addrspace(10)* @julia.typeof({} addrspace(10)* nonnull %13) #27, !dbg !743
  %.not = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 140708254088832 to {}*) to {} addrspace(10)*), !dbg !743
  br i1 %.not, label %L5.i, label %L52.i, !dbg !743

L5.i:                                             ; preds = %entry
  %15 = bitcast {} addrspace(10)* %13 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)*, !dbg !745
  %16 = addrspacecast { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)* %15 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*, !dbg !745
  %17 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %16, i64 0, i32 1, !dbg !745
  %18 = load i64, i64 addrspace(11)* %17, align 8, !dbg !745, !tbaa !230, !range !232
  switch i64 %18, label %L19.i [
    i64 0, label %L41.i
    i64 1, label %L17.i
  ], !dbg !759

L17.i:                                            ; preds = %L5.i
  %19 = bitcast {} addrspace(10)* %13 to double addrspace(13)* addrspace(10)*, !dbg !760
  %20 = addrspacecast double addrspace(13)* addrspace(10)* %19 to double addrspace(13)* addrspace(11)*, !dbg !760
  %21 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %20, align 8, !dbg !760, !tbaa !34, !nonnull !4  %22 = load double, double addrspace(13)* %21, align 8, !dbg !760, !tbaa !39
  br label %L41.i, !dbg !762

L19.i:                                            ; preds = %L5.i
  %23 = icmp ugt i64 %18, 15, !dbg !763
  br i1 %23, label %L36.i, label %L21.i, !dbg !765

L21.i:                                            ; preds = %L19.i
  %24 = bitcast {} addrspace(10)* %13 to double addrspace(13)* addrspace(10)*, !dbg !766
  %25 = addrspacecast double addrspace(13)* addrspace(10)* %24 to double addrspace(13)* addrspace(11)*, !dbg !766
  %26 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %25, align 8, !dbg !766, !tbaa !34, !nonnull !4  %27 = load double, double addrspace(13)* %26, align 8, !dbg !766, !tbaa !39
  %28 = getelementptr inbounds double, double addrspace(13)* %26, i64 1, !dbg !768
  %29 = load double, double addrspace(13)* %28, align 8, !dbg !768, !tbaa !39
  %30 = fadd double %27, %29, !dbg !770
  %.not511 = icmp ugt i64 %18, 2, !dbg !773
  br i1 %.not511, label %L31.i.preheader, label %L41.i, !dbg !775

L31.i.preheader:                                  ; preds = %L21.i
  br label %L31.i, !dbg !775

L31.i:                                            ; preds = %L31.i.preheader, %L31.i
  %iv1 = phi i64 [ %iv.next2, %L31.i ], [ 0, %L31.i.preheader ]
  %value_phi2.i12 = phi double [ %35, %L31.i ], [ %30, %L31.i.preheader ]
  %31 = add i64 %iv1, 2, !dbg !776
  %iv.next2 = add nuw nsw i64 %iv1, 1, !dbg !776
  %32 = add nuw nsw i64 %31, 1, !dbg !776
  %33 = getelementptr inbounds double, double addrspace(13)* %26, i64 %31, !dbg !778
  %34 = load double, double addrspace(13)* %33, align 8, !dbg !778, !tbaa !39
  %35 = fadd double %value_phi2.i12, %34, !dbg !779
  %exitcond.not = icmp eq i64 %32, %18, !dbg !773
  br i1 %exitcond.not, label %L41.i.loopexit, label %L31.i, !dbg !775

L36.i:                                            ; preds = %L19.i
  %36 = call fastcc double @julia_mapreduce_impl_5757({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %13, i64 noundef signext 1, i64 signext %18) #28, !dbg !782
  br label %L41.i, !dbg !784

L41.i.loopexit:                                   ; preds = %L31.i
  br label %L41.i

L41.i:                                            ; preds = %L41.i.loopexit, %L36.i, %L21.i, %L17.i, %L5.i
  %value_phi.i = phi double [ %22, %L17.i ], [ %36, %L36.i ], [ 0.000000e+00, %L5.i ], [ %30, %L21.i ], [ %35, %L41.i.loopexit ]
  %current_task7.i3 = getelementptr inbounds {}**, {}*** %11, i64 -12
  %current_task7.i = bitcast {}*** %current_task7.i3 to {}**
  %37 = call noalias nonnull {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task7.i, i64 noundef 8, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 140708253266096 to {}*) to {} addrspace(10)*)) #29, !dbg !743
  %38 = bitcast {} addrspace(10)* %37 to double addrspace(10)*
  store double %value_phi.i, double addrspace(10)* %38, align 8, !tbaa !108
  br label %julia_f2_5740_inner.exit, !dbg !743

L52.i:                                            ; preds = %entry
  %.not6 = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 140708253032368 to {}*) to {} addrspace(10)*), !dbg !743
  br i1 %.not6, label %L54.i, label %L101.i, !dbg !743

L54.i:                                            ; preds = %L52.i
  %39 = bitcast {} addrspace(10)* %13 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)*, !dbg !745
  %40 = addrspacecast { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)* %39 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*, !dbg !745
  %41 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %40, i64 0, i32 1, !dbg !745
  %42 = load i64, i64 addrspace(11)* %41, align 8, !dbg !745, !tbaa !230, !range !232
  switch i64 %42, label %L68.i [
    i64 0, label %L90.i
    i64 1, label %L66.i
  ], !dbg !759

L66.i:                                            ; preds = %L54.i
  %43 = bitcast {} addrspace(10)* %13 to i64 addrspace(13)* addrspace(10)*, !dbg !760
  %44 = addrspacecast i64 addrspace(13)* addrspace(10)* %43 to i64 addrspace(13)* addrspace(11)*, !dbg !760
  %45 = load i64 addrspace(13)*, i64 addrspace(13)* addrspace(11)* %44, align 8, !dbg !760, !tbaa !34, !nonnull !4
  %46 = load i64, i64 addrspace(13)* %45, align 8, !dbg !760, !tbaa !39
  br label %L90.i, !dbg !762

L68.i:                                            ; preds = %L54.i
  %47 = icmp ugt i64 %42, 15, !dbg !763
  br i1 %47, label %L85.i, label %L70.i, !dbg !765

L70.i:                                            ; preds = %L68.i
  %48 = bitcast {} addrspace(10)* %13 to i64 addrspace(13)* addrspace(10)*, !dbg !766
  %49 = addrspacecast i64 addrspace(13)* addrspace(10)* %48 to i64 addrspace(13)* addrspace(11)*, !dbg !766
  %50 = load i64 addrspace(13)*, i64 addrspace(13)* addrspace(11)* %49, align 8, !dbg !766, !tbaa !34, !nonnull !4
  %51 = load i64, i64 addrspace(13)* %50, align 8, !dbg !766, !tbaa !39
  %52 = getelementptr inbounds i64, i64 addrspace(13)* %50, i64 1, !dbg !768
  %53 = load i64, i64 addrspace(13)* %52, align 8, !dbg !768, !tbaa !39
  %54 = add i64 %53, %51, !dbg !785
  %.not914 = icmp ugt i64 %42, 2, !dbg !773
  br i1 %.not914, label %L80.i.preheader, label %L90.i, !dbg !775

L80.i.preheader:                                  ; preds = %L70.i
  br label %L80.i, !dbg !775

L80.i:                                            ; preds = %L80.i.preheader, %L80.i
  %iv = phi i64 [ %iv.next, %L80.i ], [ 0, %L80.i.preheader ]
  %value_phi5.i15 = phi i64 [ %59, %L80.i ], [ %54, %L80.i.preheader ]
  %55 = add i64 %iv, 2, !dbg !776
  %iv.next = add nuw nsw i64 %iv, 1, !dbg !776
  %56 = add nuw nsw i64 %55, 1, !dbg !776
  %57 = getelementptr inbounds i64, i64 addrspace(13)* %50, i64 %55, !dbg !778
  %58 = load i64, i64 addrspace(13)* %57, align 8, !dbg !778, !tbaa !39
  %59 = add i64 %58, %value_phi5.i15, !dbg !786
  %exitcond19.not = icmp eq i64 %56, %42, !dbg !773
  br i1 %exitcond19.not, label %L90.i.loopexit, label %L80.i, !dbg !775

L85.i:                                            ; preds = %L68.i
  %60 = call fastcc i64 @julia_mapreduce_impl_5754({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %13, i64 noundef signext 1, i64 signext %42) #28, !dbg !782
  br label %L90.i, !dbg !784

L90.i.loopexit:                                   ; preds = %L80.i
  br label %L90.i, !dbg !743

L90.i:                                            ; preds = %L90.i.loopexit, %L85.i, %L70.i, %L66.i, %L54.i
  %value_phi4.i = phi i64 [ %46, %L66.i ], [ %60, %L85.i ], [ 0, %L54.i ], [ %54, %L70.i ], [ %59, %L90.i.loopexit ]
  %61 = call noalias nonnull {} addrspace(10)* @ijl_box_int64(i64 signext %value_phi4.i) #25, !dbg !743
  br label %julia_f2_5740_inner.exit, !dbg !743

L101.i:                                           ; preds = %L52.i
  %.not10 = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 1908471539968 to {}*) to {} addrspace(10)*), !dbg !743
  br i1 %.not10, label %L103.i, label %L108.i, !dbg !743

L103.i:                                           ; preds = %L101.i
  %62 = call fastcc nonnull {} addrspace(10)* @julia__mapreduce_5746({} addrspace(10)* nocapture nonnull readonly align 16 dereferenceable(40) %13) #26, !dbg !787
  br label %julia_f2_5740_inner.exit, !dbg !743

L108.i:                                           ; preds = %L101.i
  call void @ijl_throw({} addrspace(12)* noundef addrspacecast ({}* inttoptr (i64 140708254126288 to {}*) to {} addrspace(12)*)) #30, !dbg !743
  unreachable, !dbg !743

julia_f2_5740_inner.exit:                         ; preds = %L103.i, %L90.i, %L41.i
  %value_phi1.i = phi {} addrspace(10)* [ %37, %L41.i ], [ %61, %L90.i ], [ %62, %L103.i ]
  %63 = addrspacecast i8 addrspace(10)* %9 to i8*, !dbg !743
  call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %63) #25, !dbg !743
  ret {} addrspace(10)* %value_phi1.i, !dbg !788
}

 Type analysis state:
<analysis>
i64 0: {[-1]:Anything}, intvals: {0,}
i64 1: {[-1]:Integer}, intvals: {1,}
i32 0: {[-1]:Anything}, intvals: {0,}
i64 2: {[-1]:Integer}, intvals: {2,}
i64 8: {[-1]:Integer}, intvals: {8,}
i64 15: {[-1]:Integer}, intvals: {15,}
{} addrspace(12)* addrspacecast ({}* inttoptr (i64 140708254126288 to {}*) to {} addrspace(12)*): {[-1]:Anything}, intvals: {}
{}* inttoptr (i64 140708254126288 to {}*): {[-1]:Anything}, intvals: {}
{} addrspace(10)* addrspacecast ({}* inttoptr (i64 140708253266096 to {}*) to {} addrspace(10)*): {[-1]:Anything}, intvals: {}
{}* inttoptr (i64 140708253266096 to {}*): {[-1]:Anything}, intvals: {}
  %22 = load double, double addrspace(13)* %21, align 8, !dbg !64, !tbaa !69: {[-1]:Float@double}, intvals: {}
  %26 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %25, align 8, !dbg !78, !tbaa !67, !nonnull !4: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double}, intvals: {}
  %24 = bitcast {} addrspace(10)* %13 to double addrspace(13)* addrspace(10)*, !dbg !78: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %25 = addrspacecast double addrspace(13)* addrspace(10)* %24 to double addrspace(13)* addrspace(11)*, !dbg !78: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,8]:Float@double, [-1,0,16]: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, [-1,40]:Integer}, intvals: {}
  %27 = load double, double addrspace(13)* %26, align 8, !dbg !78, !tbaa !69: {[-1]:Float@double}, intvals: {}
  %12 = addrspacecast { {} addrspace(10)* } addrspace(10)* %8 to { {} addrspace(10)* } addrspace(11)*, !dbg !27: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Float@double, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,0,40]:Integer}, intvals: {}
  %29 = load double, double addrspace(13)* %28, align 8, !dbg !80, !tbaa !69: {[-1]:Float@double}, intvals: {}
  %20 = addrspacecast double addrspace(13)* addrspace(10)* %19 to double addrspace(13)* addrspace(11)*, !dbg !64: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %34 = load double, double addrspace(13)* %33, align 8, !dbg !94, !tbaa !69: {[-1]:Float@double}, intvals: {}
  %16 = addrspacecast { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)* %15 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*, !dbg !29: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %current_task7.i = bitcast {}*** %current_task7.i3 to {}**: {}, intvals: {}
  %38 = bitcast {} addrspace(10)* %37 to double addrspace(10)*: {[-1]:Pointer, [-1,-1]:Float@double}, intvals: {}
  %39 = bitcast {} addrspace(10)* %13 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)*, !dbg !29: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %40 = addrspacecast { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)* %39 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)*, !dbg !29: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %42 = load i64, i64 addrspace(11)* %41, align 8, !dbg !29, !tbaa !57, !range !62: {[-1]:Integer}, intvals: {}
  %18 = load i64, i64 addrspace(11)* %17, align 8, !dbg !29, !tbaa !57, !range !62: {[-1]:Integer}, intvals: {}
  %19 = bitcast {} addrspace(10)* %13 to double addrspace(13)* addrspace(10)*, !dbg !64: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %15 = bitcast {} addrspace(10)* %13 to { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(10)*, !dbg !29: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %21 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %20, align 8, !dbg !64, !tbaa !67, !nonnull !4: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %2 = bitcast {}*** %1 to {}**: {[-1]:Pointer}, intvals: {}
  %63 = addrspacecast i8 addrspace(10)* %9 to i8*, !dbg !27: {[-1]:Pointer}, intvals: {}
  %10 = addrspacecast i8 addrspace(10)* %9 to i8*: {[-1]:Pointer}, intvals: {}
  %6 = load i8*, i8** %5, align 8: {}, intvals: {}
  %44 = addrspacecast i64 addrspace(13)* addrspace(10)* %43 to i64 addrspace(13)* addrspace(11)*, !dbg !64: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
  %58 = load i64, i64 addrspace(13)* %57, align 8, !dbg !94, !tbaa !69: {}, intvals: {}
  %49 = addrspacecast i64 addrspace(13)* addrspace(10)* %48 to i64 addrspace(13)* addrspace(11)*, !dbg !78: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
  %48 = bitcast {} addrspace(10)* %13 to i64 addrspace(13)* addrspace(10)*, !dbg !78: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %46 = load i64, i64 addrspace(13)* %45, align 8, !dbg !64, !tbaa !69: {}, intvals: {}
  %50 = load i64 addrspace(13)*, i64 addrspace(13)* addrspace(11)* %49, align 8, !dbg !78, !tbaa !67, !nonnull !4: {[-1]:Pointer}, intvals: {}
  %51 = load i64, i64 addrspace(13)* %50, align 8, !dbg !78, !tbaa !69: {}, intvals: {}
  %5 = bitcast {}** %4 to i8**: {[-1]:Pointer}, intvals: {}
  %8 = bitcast {} addrspace(10)* %7 to { {} addrspace(10)* } addrspace(10)*, !enzyme_caststack !4: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Float@double, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,0,40]:Integer}, intvals: {}
  %9 = bitcast { {} addrspace(10)* } addrspace(10)* %8 to i8 addrspace(10)*: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Float@double, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,0,40]:Integer}, intvals: {}
  %43 = bitcast {} addrspace(10)* %13 to i64 addrspace(13)* addrspace(10)*, !dbg !64: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %45 = load i64 addrspace(13)*, i64 addrspace(13)* addrspace(11)* %44, align 8, !dbg !64, !tbaa !67, !nonnull !4: {[-1]:Pointer}, intvals: {}
  %53 = load i64, i64 addrspace(13)* %52, align 8, !dbg !80, !tbaa !69: {}, intvals: {}
{} addrspace(10)* addrspacecast ({}* inttoptr (i64 140708254088832 to {}*) to {} addrspace(10)*): {[-1]:Anything}, intvals: {}
{}* inttoptr (i64 140708254088832 to {}*): {[-1]:Anything}, intvals: {}
{}* inttoptr (i64 140708253032368 to {}*): {[-1]:Anything}, intvals: {}
{} addrspace(10)* addrspacecast ({}* inttoptr (i64 140708253032368 to {}*) to {} addrspace(10)*): {[-1]:Anything}, intvals: {}
double 0.000000e+00: {[-1]:Anything}, intvals: {}
  %17 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %16, i64 0, i32 1, !dbg !29: {[-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}, intvals: {}
  %.fca.0.gep = getelementptr { {} addrspace(10)* }, { {} addrspace(10)* } addrspace(10)* %8, i64 0, i32 0, !dbg !27: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,0,-1]:Float@double, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,0,40]:Integer}, intvals: {}
  %41 = getelementptr inbounds { i8 addrspace(13)*, i64, i16, i16, i32 }, { i8 addrspace(13)*, i64, i16, i16, i32 } addrspace(11)* %40, i64 0, i32 1, !dbg !29: {[-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}, intvals: {}
  %52 = getelementptr inbounds i64, i64 addrspace(13)* %50, i64 1, !dbg !80: {[-1]:Pointer}, intvals: {}
  %62 = call fastcc nonnull {} addrspace(10)* @julia__mapreduce_5746({} addrspace(10)* nocapture nonnull readonly align 16 dereferenceable(40) %13) #26, !dbg !107: {[-1]:Pointer}, intvals: {}
  %28 = getelementptr inbounds double, double addrspace(13)* %26, i64 1, !dbg !80: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double}, intvals: {}
  %61 = call noalias nonnull {} addrspace(10)* @ijl_box_int64(i64 signext %value_phi4.i) #25, !dbg !27: {[-1]:Pointer}, intvals: {}
  %current_task7.i3 = getelementptr inbounds {}**, {}*** %11, i64 -12: {}, intvals: {}
  %57 = getelementptr inbounds i64, i64 addrspace(13)* %50, i64 %55, !dbg !94: {[-1]:Pointer}, intvals: {}
  %33 = getelementptr inbounds double, double addrspace(13)* %26, i64 %31, !dbg !94: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %3 = getelementptr inbounds {}*, {}** %2, i64 -12: {[-1]:Pointer}, intvals: {}
  %14 = call {} addrspace(10)* @julia.typeof({} addrspace(10)* nonnull %13) #27, !dbg !27: {}, intvals: {}
  %13 = call fastcc nonnull {} addrspace(10)* @julia_collect_5760({ {} addrspace(10)* } addrspace(11)* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) %12) #26, !dbg !27: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer}, intvals: {}
  %4 = getelementptr inbounds {}*, {}** %3, i64 14: {[-1]:Pointer}, intvals: {}
  %value_phi2.i12 = phi double [ %35, %L31.i ], [ %30, %L31.i.preheader ]: {[-1]:Float@double}, intvals: {}
  %value_phi.i = phi double [ %22, %L17.i ], [ %36, %L36.i ], [ 0.000000e+00, %L5.i ], [ %30, %L21.i ], [ %35, %L41.i.loopexit ]: {[-1]:Float@double}, intvals: {}
  %value_phi5.i15 = phi i64 [ %59, %L80.i ], [ %54, %L80.i.preheader ]: {}, intvals: {}
  %iv1 = phi i64 [ %iv.next2, %L31.i ], [ 0, %L31.i.preheader ]: {[-1]:Integer}, intvals: {0,}
  %iv = phi i64 [ %iv.next, %L80.i ], [ 0, %L80.i.preheader ]: {[-1]:Integer}, intvals: {0,}
  %value_phi4.i = phi i64 [ %46, %L66.i ], [ %60, %L85.i ], [ 0, %L54.i ], [ %54, %L70.i ], [ %59, %L90.i.loopexit ]: {}, intvals: {0,}
  %value_phi1.i = phi {} addrspace(10)* [ %37, %L41.i ], [ %61, %L90.i ], [ %62, %L103.i ]: {[-1]:Pointer}, intvals: {}
  %.not = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 140708254088832 to {}*) to {} addrspace(10)*), !dbg !27: {[-1]:Integer}, intvals: {}
  %23 = icmp ugt i64 %18, 15, !dbg !73: {[-1]:Integer}, intvals: {}
  %32 = add nuw nsw i64 %31, 1, !dbg !91: {[-1]:Integer}, intvals: {3,}
  %54 = add i64 %53, %51, !dbg !105: {}, intvals: {}
  %exitcond.not = icmp eq i64 %32, %18, !dbg !88: {[-1]:Integer}, intvals: {}
  %.not914 = icmp ugt i64 %42, 2, !dbg !88: {[-1]:Integer}, intvals: {}
  %56 = add nuw nsw i64 %55, 1, !dbg !91: {[-1]:Integer}, intvals: {3,}
  %.not6 = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 140708253032368 to {}*) to {} addrspace(10)*), !dbg !27: {[-1]:Integer}, intvals: {}
  %exitcond19.not = icmp eq i64 %56, %42, !dbg !88: {[-1]:Integer}, intvals: {}
  %47 = icmp ugt i64 %42, 15, !dbg !73: {[-1]:Integer}, intvals: {}
  %30 = fadd double %27, %29, !dbg !82: {[-1]:Float@double}, intvals: {}
  %.not511 = icmp ugt i64 %18, 2, !dbg !88: {[-1]:Integer}, intvals: {}
  %35 = fadd double %value_phi2.i12, %34, !dbg !95: {[-1]:Float@double}, intvals: {}
  %59 = add i64 %58, %value_phi5.i15, !dbg !106: {}, intvals: {}
  %.not10 = icmp eq {} addrspace(10)* %14, addrspacecast ({}* inttoptr (i64 1908471539968 to {}*) to {} addrspace(10)*), !dbg !27: {[-1]:Integer}, intvals: {}
  %55 = add i64 %iv, 2, !dbg !91: {[-1]:Integer}, intvals: {2,}
  %iv.next2 = add nuw nsw i64 %iv1, 1, !dbg !91: {[-1]:Integer}, intvals: {1,}
  %31 = add i64 %iv1, 2, !dbg !91: {[-1]:Integer}, intvals: {2,}
  %iv.next = add nuw nsw i64 %iv, 1, !dbg !91: {[-1]:Integer}, intvals: {1,}
{}* inttoptr (i64 1908471539968 to {}*): {[-1]:Anything}, intvals: {}
{} addrspace(10)* addrspacecast ({}* inttoptr (i64 1908471539968 to {}*) to {} addrspace(10)*): {[-1]:Anything}, intvals: {}
{}* inttoptr (i64 1907595642928 to {}*): {[-1]:Anything}, intvals: {}
{} addrspace(10)* addrspacecast ({}* inttoptr (i64 1907595642928 to {}*) to {} addrspace(10)*): {[-1]:Anything}, intvals: {}
  %60 = call fastcc i64 @julia_mapreduce_impl_5754({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %13, i64 noundef signext 1, i64 signext %42) #28, !dbg !98: {}, intvals: {}
  %36 = call fastcc double @julia_mapreduce_impl_5757({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %13, i64 noundef signext 1, i64 signext %18) #28, !dbg !98: {[-1]:Float@double}, intvals: {}
  %37 = call noalias nonnull {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task7.i, i64 noundef 8, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 140708253266096 to {}*) to {} addrspace(10)*)) #29, !dbg !27: {[-1]:Pointer, [-1,-1]:Float@double}, intvals: {}
  %7 = call noalias nonnull dereferenceable(8) dereferenceable_or_null(8) {} addrspace(10)* @jl_gc_alloc_typed(i8* %6, i64 8, {} addrspace(10)* addrspacecast ({}* inttoptr (i64 1907595642928 to {}*) to {} addrspace(10)*)), !enzyme_fromstack !26: {[-1]:Pointer, [-1,-1]:Pointer, [-1,-1,0]:Pointer, [-1,-1,0,-1]:Float@double, [-1,-1,8]:Integer, [-1,-1,9]:Integer, [-1,-1,10]:Integer, [-1,-1,11]:Integer, [-1,-1,12]:Integer, [-1,-1,13]:Integer, [-1,-1,14]:Integer, [-1,-1,15]:Integer, [-1,-1,16]:Integer, [-1,-1,17]:Integer, [-1,-1,18]:Integer, [-1,-1,19]:Integer, [-1,-1,20]:Integer, [-1,-1,21]:Integer, [-1,-1,22]:Integer, [-1,-1,23]:Integer, [-1,-1,24]:Integer, [-1,-1,25]:Integer, [-1,-1,26]:Integer, [-1,-1,27]:Integer, [-1,-1,28]:Integer, [-1,-1,29]:Integer, [-1,-1,30]:Integer, [-1,-1,31]:Integer, [-1,-1,32]:Integer, [-1,-1,33]:Integer, [-1,-1,34]:Integer, [-1,-1,35]:Integer, [-1,-1,36]:Integer, [-1,-1,37]:Integer, [-1,-1,38]:Integer, [-1,-1,39]:Integer, [-1,-1,40]:Integer, [-1,0,0]:Pointer, [-1,0,0,-1]:Float@double, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,0,40]:Integer}, intvals: {}
{} addrspace(10)* %0: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]: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, [-1,40]:Integer}, intvals: {}
  %1 = call {}*** @julia.get_pgcstack(): {[-1]:Pointer}, intvals: {}
  %11 = call {}*** @julia.get_pgcstack() #25: {}, intvals: {}
</analysis>

Illegal updateAnalysis prev:{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]: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, [-1,40]:Integer} new: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@double}
val:   %20 = addrspacecast double addrspace(13)* addrspace(10)* %19 to double addrspace(13)* addrspace(11)*, !dbg !64 origin=  %21 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %20, align 8, !dbg !64, !tbaa !67, !nonnull !4

Caused by:
Stacktrace:
  [1] getindex
    @ .\array.jl:924
  [2] _mapreduce
    @ .\reduce.jl:429
  [3] _mapreduce_dim
    @ .\reducedim.jl:365
  [4] #mapreduce#765
    @ .\reducedim.jl:357
  [5] mapreduce
    @ .\reducedim.jl:357
  [6] #_sum#775
    @ .\reducedim.jl:999
  [7] _sum
    @ .\reducedim.jl:999
  [8] #_sum#774
    @ .\reducedim.jl:998
  [9] _sum
    @ .\reducedim.jl:998
 [10] #sum#772
    @ .\reducedim.jl:994
 [11] sum
    @ .\reducedim.jl:994
 [12] f2
    @ .\REPL[11]:1
 [13] f2
    @ .\REPL[11]:0

Stacktrace:
  [1] julia_error(cstr::Cstring, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing})
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:5092
  [2] EnzymeCreateAugmentedPrimal(logic::Enzyme.Logic, todiff::LLVM.Function, retType::Enzyme.API.CDIFFE_TYPE, constant_args::Vector{Enzyme.API.CDIFFE_TYPE}, TA::Enzyme.TypeAnalysis, returnUsed::Bool, shadowReturnUsed::Bool, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{Bool}, forceAnonymousTape::Bool, width::Int64, atomicAdd::Bool)
    @ Enzyme.API C:\Users\Joe\.julia\dev\Enzyme\src\api.jl:159
  [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}, returnPrimal::Bool, jlrules::Vector{String}, expectedTapeType::Type)
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:6522
  [4] codegen(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}; libraries::Bool, deferred_codegen::Bool, optimize::Bool, ctx::LLVM.Context, strip::Bool, validate::Bool, only_entry::Bool, parent_job::Nothing)
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:7817
  [5] _thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8329 [inlined]
  [6] _thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8326 [inlined]
  [7] cached_compilation
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8362 [inlined]
  [8] #s260#178
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8424 [inlined]
  [9] var"#s260#178"(FA::Any, A::Any, TT::Any, Mode::Any, ModifiedBetween::Any, width::Any, ReturnPrimal::Any, ShadowInit::Any, parent_job::Any, World::Any, ::Any, ::Any, ::Any, ::Any, tt::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
    @ Enzyme.Compiler .\none:0
 [10] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
    @ Core .\boot.jl:582
 [11] thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8379 [inlined]
 [12] autodiff(#unused#::EnzymeCore.ReverseMode{false}, f::Const{typeof(f2)}, #unused#::Type{Active}, args::Duplicated{Vector{Float64}})
    @ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:187
 [13] autodiff(::EnzymeCore.ReverseMode{false}, ::typeof(f2), ::Type, ::Duplicated{Vector{Float64}})
    @ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:214
 [14] top-level scope
    @ REPL[12]:1
wsmoses commented 1 year ago

Add a Enzyme.API.strictAliasing!(false) and see if it succeeds?

jgreener64 commented 1 year ago

With Enzyme.API.strictAliasing!(false) the error changes slightly:

ERROR: Enzyme cannot deduce type
Current scope:
; Function Attrs: mustprogress nofree noinline nosync readonly uwtable willreturn
define internal fastcc double @preprocess_julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %2) unnamed_addr #33 !dbg !1466 {
top:
  %3 = call {}*** @julia.get_pgcstack() #43
  %.not = icmp eq i64 %2, %1, !dbg !1467
  br i1 %.not, label %L3, label %L5, !dbg !1468

common.ret.loopexit:                              ; preds = %L32
  br label %common.ret, !dbg !1469

common.ret:                                       ; preds = %common.ret.loopexit, %L59, %L8, %L3
  %common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]
  ret double %common.ret.op, !dbg !1469

L3:                                               ; preds = %top
  %4 = add i64 %2, -1, !dbg !1470
  %5 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !1470
  %6 = addrspacecast double addrspace(13)* addrspace(10)* %5 to double addrspace(13)* addrspace(11)*, !dbg !1470
  %7 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %6, align 16, !dbg !1470, !tbaa !82, !nonnull !4  %8 = getelementptr inbounds double, double addrspace(13)* %7, i64 %4, !dbg !1470
  %9 = load double, double addrspace(13)* %8, align 8, !dbg !1470, !tbaa !124
  br label %common.ret

L5:                                               ; preds = %top
  %10 = sub i64 %2, %1, !dbg !1472
  %.not11 = icmp slt i64 %10, 1024, !dbg !1474
  br i1 %.not11, label %L8, label %L59, !dbg !1473

L8:                                               ; preds = %L5
  %11 = add i64 %1, -1, !dbg !1475
  %12 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !1475
  %13 = addrspacecast double addrspace(13)* addrspace(10)* %12 to double addrspace(13)* addrspace(11)*, !dbg !1475
  %14 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %13, align 16, !dbg !1475, !tbaa !82, !nonnull !4
  %15 = getelementptr inbounds double, double addrspace(13)* %14, i64 %11, !dbg !1475
  %16 = load double, double addrspace(13)* %15, align 8, !dbg !1475, !tbaa !124
  %17 = getelementptr inbounds double, double addrspace(13)* %14, i64 %1, !dbg !1477
  %18 = load double, double addrspace(13)* %17, align 8, !dbg !1477, !tbaa !124
  %19 = fadd double %16, %18, !dbg !1479
  %20 = add i64 %1, 2, !dbg !1482
  %.not12 = icmp sgt i64 %20, %2, !dbg !1485
  %21 = add i64 %1, 1, !dbg !1487
  %value_phi = select i1 %.not12, i64 %21, i64 %2, !dbg !1487
  %22 = sub i64 %value_phi, %20, !dbg !1490
  %23 = icmp ugt i64 %22, 9223372036854775806, !dbg !1494
  br i1 %23, label %common.ret, label %L32.preheader, !dbg !1495

L32.preheader:                                    ; preds = %L8
  br label %L32, !dbg !1496

L32:                                              ; preds = %L32.preheader, %L32
  %iv = phi i64 [ 0, %L32.preheader ], [ %iv.next, %L32 ]
  %value_phi115 = phi double [ %27, %L32 ], [ %19, %L32.preheader ]
  %iv.next = add nuw nsw i64 %iv, 1, !dbg !1497
  %24 = add i64 %21, %iv, !dbg !1497
  %25 = getelementptr inbounds double, double addrspace(13)* %14, i64 %24, !dbg !1497
  %26 = load double, double addrspace(13)* %25, align 8, !dbg !1497, !tbaa !124
  %27 = fadd fast double %value_phi115, %26, !dbg !1500
  %exitcond.not = icmp eq i64 %iv, %22, !dbg !1503
  br i1 %exitcond.not, label %common.ret.loopexit, label %L32, !dbg !1496, !llvm.loop !1504

L59:                                              ; preds = %L5
  %28 = ashr i64 %10, 1, !dbg !1505
  %29 = add i64 %28, %1, !dbg !1508
  %30 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %29) #44, !dbg !1509
  %31 = add i64 %29, 1, !dbg !1510
  %32 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %31, i64 signext %2) #44, !dbg !1511
  %33 = fadd double %30, %32, !dbg !1512
  br label %common.ret
}

 Type analysis state:
<analysis>
  %22 = sub i64 %value_phi, %20, !dbg !78: {[-1]:Integer}, intvals: {}
  %31 = add i64 %29, 1, !dbg !102: {[-1]:Integer}, intvals: {}
  %iv.next = add nuw nsw i64 %iv, 1, !dbg !87: {[-1]:Integer}, intvals: {1,}
  %23 = icmp ugt i64 %22, 9223372036854775806, !dbg !84: {[-1]:Integer}, intvals: {}
  %33 = fadd double %30, %32, !dbg !104: {[-1]:Float@double}, intvals: {}
  %19 = fadd double %16, %18, !dbg !55: {[-1]:Float@double}, intvals: {}
  %28 = ashr i64 %10, 1, !dbg !96: {[-1]:Integer}, intvals: {}
  %20 = add i64 %1, 2, !dbg !61: {[-1]:Integer}, intvals: {3,}
  %21 = add i64 %1, 1, !dbg !72: {[-1]:Integer}, intvals: {2,}
  %27 = fadd fast double %value_phi115, %26, !dbg !91: {[-1]:Float@double}, intvals: {}
  %11 = add i64 %1, -1, !dbg !51: {[-1]:Integer}, intvals: {0,}
  %.not = icmp eq i64 %2, %1, !dbg !29: {[-1]:Integer}, intvals: {}
  %.not11 = icmp slt i64 %10, 1024, !dbg !49: {[-1]:Integer}, intvals: {}
  %4 = add i64 %2, -1, !dbg !34: {[-1]:Integer}, intvals: {}
  %24 = add i64 %21, %iv, !dbg !87: {[-1]:Integer}, intvals: {2,}
  %exitcond.not = icmp eq i64 %iv, %22, !dbg !94: {[-1]:Integer}, intvals: {}
  %10 = sub i64 %2, %1, !dbg !45: {[-1]:Integer}, intvals: {}
  %29 = add i64 %28, %1, !dbg !100: {[-1]:Integer}, intvals: {}
  %.not12 = icmp sgt i64 %20, %2, !dbg !67: {[-1]:Integer}, intvals: {}
  %15 = getelementptr inbounds double, double addrspace(13)* %14, i64 %11, !dbg !51: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %25 = getelementptr inbounds double, double addrspace(13)* %14, i64 %24, !dbg !87: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %17 = getelementptr inbounds double, double addrspace(13)* %14, i64 %1, !dbg !53: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %8 = getelementptr inbounds double, double addrspace(13)* %7, i64 %4, !dbg !34: {[-1]:Pointer}, intvals: {}
  %26 = load double, double addrspace(13)* %25, align 8, !dbg !87, !tbaa !42: {[-1]:Float@double}, intvals: {}
  %14 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %13, align 16, !dbg !51, !tbaa !37, !nonnull !4: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double}, intvals: {}
  %13 = addrspacecast double addrspace(13)* addrspace(10)* %12 to double addrspace(13)* addrspace(11)*, !dbg !51: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@double, [-1,0,8]:Float@double}, intvals: {}
  %5 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !34: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
  %16 = load double, double addrspace(13)* %15, align 8, !dbg !51, !tbaa !42: {[-1]:Float@double}, intvals: {}
  %12 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !51: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@double, [-1,0,8]:Float@double}, intvals: {}
  %9 = load double, double addrspace(13)* %8, align 8, !dbg !34, !tbaa !42: {}, intvals: {}
  %18 = load double, double addrspace(13)* %17, align 8, !dbg !53, !tbaa !42: {[-1]:Float@double}, intvals: {}
  %6 = addrspacecast double addrspace(13)* addrspace(10)* %5 to double addrspace(13)* addrspace(11)*, !dbg !34: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
  %7 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %6, align 16, !dbg !34, !tbaa !37, !nonnull !4: {[-1]:Pointer}, intvals: {}
  %30 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %29) #44, !dbg !101: {[-1]:Float@double}, intvals: {}
  %32 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %31, i64 signext %2) #44, !dbg !103: {[-1]:Float@double}, intvals: {}
i64 1024: {[-1]:Integer}, intvals: {1024,}
  %value_phi = select i1 %.not12, i64 %21, i64 %2, !dbg !72: {[-1]:Integer}, intvals: {}
  %3 = call {}*** @julia.get_pgcstack() #43: {}, intvals: {}
{} addrspace(10)* %0: {[-1]:Pointer}, intvals: {}
i64 %1: {[-1]:Integer}, intvals: {1,}
i64 %2: {[-1]:Integer}, intvals: {}
  %common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]: {}, intvals: {}
  %value_phi115 = phi double [ %27, %L32 ], [ %19, %L32.preheader ]: {[-1]:Float@double}, intvals: {}
  %iv = phi i64 [ 0, %L32.preheader ], [ %iv.next, %L32 ]: {[-1]:Integer}, intvals: {0,}
i64 2: {[-1]:Integer}, intvals: {2,}
i64 -1: {[-1]:Anything}, intvals: {-1,}
i64 0: {[-1]:Anything}, intvals: {0,}
i64 1: {[-1]:Integer}, intvals: {1,}
i64 9223372036854775806: {[-1]:Anything}, intvals: {9223372036854775806,}
</analysis>

Cannot deduce type of phi   %common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]

Caused by:

Stacktrace:
  [1] julia_error(cstr::Cstring, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing})
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:5098
  [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{LLVM.API.LLVMOpaqueType}, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{Bool}, augmented::Ptr{Nothing}, atomicAdd::Bool)
    @ Enzyme.API C:\Users\Joe\.julia\dev\Enzyme\src\api.jl:123
  [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}, returnPrimal::Bool, jlrules::Vector{String}, expectedTapeType::Type)
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:6551
  [4] codegen(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}; libraries::Bool, deferred_codegen::Bool, optimize::Bool, ctx::LLVM.Context, strip::Bool, validate::Bool, only_entry::Bool, parent_job::Nothing)
    @ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:7817
  [5] _thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8329 [inlined]
  [6] _thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8326 [inlined]
  [7] cached_compilation
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8362 [inlined]
  [8] #s260#178
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8424 [inlined]
  [9] var"#s260#178"(FA::Any, A::Any, TT::Any, Mode::Any, ModifiedBetween::Any, width::Any, ReturnPrimal::Any, ShadowInit::Any, parent_job::Any, World::Any, ::Any, ::Any, ::Any, ::Any, tt::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
    @ Enzyme.Compiler .\none:0
 [10] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
    @ Core .\boot.jl:582
 [11] thunk
    @ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8379 [inlined]
 [12] autodiff(#unused#::EnzymeCore.ReverseMode{false}, f::Const{typeof(f2)}, #unused#::Type{Active}, args::Duplicated{Vector{Float64}})
    @ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:187
 [13] autodiff(::EnzymeCore.ReverseMode{false}, ::typeof(f2), ::Type, ::Duplicated{Vector{Float64}})
    @ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:214
 [14] top-level scope
    @ REPL[9]:1
wsmoses commented 6 months ago

This now works on main with strictaliasing!(false)

julia> using Enzyme

julia> Enzyme.API.strictAliasing!(false)

julia> f1(x) = sum([ifelse(i > 0, i, zero(i)) for i in x])
f1 (generic function with 1 method)

julia> x = randn(5)
5-element Vector{Float64}:
  1.4054496275614226
 -0.8542107477656112
  1.2424602513442708
 -1.1937151100828347
  1.188920661214303

julia> dx = zero(x)
5-element Vector{Float64}:
 0.0
 0.0
 0.0
 0.0
 0.0

julia> autodiff(Reverse, f1, Active, Duplicated(x, dx))
((nothing,),)

julia> f2(x) = sum([ifelse(i > 0, i, 0) for i in x])
f2 (generic function with 1 method)

julia> autodiff(Reverse, f2, Active, Duplicated(x, dx))
((nothing,),)
wsmoses commented 6 months ago

With strictaliasing and type analysis getting documentation here: https://github.com/EnzymeAD/Enzyme.jl/pull/1435, closing