Enzyme.jl
Enzyme.jl copied to clipboard
Alloc -> Malloc downgrade on sret
trafficstars
Suppose you have something like
%z = alloca { {} addr(10)*, {} addr(10)* }
call f(%z sret(...) )
load %z[0]
load %z[1]
This ends up deciding to upgrade %z to a malloc to preserve all at once for the reverse, rather than separately cache %z[0]/%z[1]. However, this means that the gc frame lowering fails since it assumes an alloca is what is used.
julia: /buildworker/worker/package_linux64/build/src/llvm-late-gc-lowering.cpp:1463: State LateLowerGCFrame::LocalScan(llvm::Function&): Assertion `SRet' failed.
signal (6): Aborted
in expression starting at /mnt/Data/git/Enzyme.jl/lux.jl:18
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7f2c0c2713f9)
__assert_fail at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
LocalScan at /buildworker/worker/package_linux64/build/src/llvm-late-gc-lowering.cpp:1463
runOnFunction at /buildworker/worker/package_linux64/build/src/llvm-late-gc-lowering.cpp:2675
_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE at /mnt/Data/git/Enzyme.jl/julia-1.7.2/bin/../lib/julia/libLLVM-12jl.so (unknown line)
_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE at /mnt/Data/git/Enzyme.jl/julia-1.7.2/bin/../lib/julia/libLLVM-12jl.so (unknown line)
_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE at /mnt/Data/git/Enzyme.jl/julia-1.7.2/bin/../lib/julia/libLLVM-12jl.so (unknown line)
LLVMRunPassManager at /mnt/Data/git/Enzyme.jl/julia-1.7.2/bin/../lib/julia/libLLVM-12jl.so (unknown line)
LLVMRunPassManager at /home/wmoses/.julia/packages/LLVM/gE6U9/lib/12/libLLVM_h.jl:4741 [inlined]
run! at /home/wmoses/.julia/packages/LLVM/gE6U9/src/passmanager.jl:39 [inlined]
#58 at /mnt/Data/git/Enzyme.jl/src/compiler/optimize.jl:230
#ModulePassManager#64 at /home/wmoses/.julia/packages/LLVM/gE6U9/src/passmanager.jl:33
unknown function (ip: 0x7f2b8c5cf10e)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
ModulePassManager at /home/wmoses/.julia/packages/LLVM/gE6U9/src/passmanager.jl:31
post_optimze! at /mnt/Data/git/Enzyme.jl/src/compiler/optimize.jl:227 [inlined]
post_optimze! at /mnt/Data/git/Enzyme.jl/src/compiler/optimize.jl:221 [inlined]
_thunk at /mnt/Data/git/Enzyme.jl/src/compiler.jl:4442
unknown function (ip: 0x7f2b8c5f0a2d)
Example:
; Function Attrs: willreturn mustprogress
define private { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } @preprocess_julia_apply_3569_.8([1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, {} addrspace(10)* nonnull align 16 dereferenceable(40) %1, [5 x [2 x {} addrspace(10)*]] %2, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } %3) local_unnamed_addr #34 !dbg !5658 {
entry:
%malloccall = tail call noalias nonnull dereferenceable(40) dereferenceable_or_null(40) i8* inttoptr (i64 140737344004128 to i8* (i64)*)(i64 40), !enzyme_fromstack !5665
%4 = bitcast i8* %malloccall to { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } }*
%malloccall1 = tail call noalias nonnull dereferenceable(80) dereferenceable_or_null(80) i8* inttoptr (i64 140737344004128 to i8* (i64)*)(i64 80), !enzyme_fromstack !5665
%.fca.0.0.0.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 0, 0, !dbg !5666
%.fca.0.0.0.gep = bitcast i8* %malloccall1 to float*, !dbg !5666
store float %.fca.0.0.0.extract, float* %.fca.0.0.0.gep, align 8, !dbg !5666
%.fca.0.0.1.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 0, 1, !dbg !5666
%.fca.0.0.1.gep = getelementptr inbounds i8, i8* %malloccall1, i64 4, !dbg !5666
%5 = bitcast i8* %.fca.0.0.1.gep to float*, !dbg !5666
store float %.fca.0.0.1.extract, float* %5, align 4, !dbg !5666
%.fca.0.0.2.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 0, 2, !dbg !5666
%.fca.0.0.2.gep = getelementptr inbounds i8, i8* %malloccall1, i64 8, !dbg !5666
%6 = bitcast i8* %.fca.0.0.2.gep to i64*, !dbg !5666
store i64 %.fca.0.0.2.extract, i64* %6, align 8, !dbg !5666
%.fca.0.1.0.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 1, 0, !dbg !5666
%.fca.0.1.0.gep = getelementptr inbounds i8, i8* %malloccall1, i64 16, !dbg !5666
%7 = bitcast i8* %.fca.0.1.0.gep to i64*, !dbg !5666
store i64 %.fca.0.1.0.extract, i64* %7, align 8, !dbg !5666
%.fca.0.1.1.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 1, 1, !dbg !5666
%.fca.0.1.1.gep = getelementptr inbounds i8, i8* %malloccall1, i64 24, !dbg !5666
%8 = bitcast i8* %.fca.0.1.1.gep to i64*, !dbg !5666
store i64 %.fca.0.1.1.extract, i64* %8, align 8, !dbg !5666
%.fca.0.2.0.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 2, 0, !dbg !5666
%.fca.0.2.0.gep = getelementptr inbounds i8, i8* %malloccall1, i64 32, !dbg !5666
%9 = bitcast i8* %.fca.0.2.0.gep to float*, !dbg !5666
store float %.fca.0.2.0.extract, float* %9, align 8, !dbg !5666
%.fca.0.2.1.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 2, 1, !dbg !5666
%.fca.0.2.1.gep = getelementptr inbounds i8, i8* %malloccall1, i64 36, !dbg !5666
%10 = bitcast i8* %.fca.0.2.1.gep to float*, !dbg !5666
store float %.fca.0.2.1.extract, float* %10, align 4, !dbg !5666
%.fca.0.2.2.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 2, 2, !dbg !5666
%.fca.0.2.2.gep = getelementptr inbounds i8, i8* %malloccall1, i64 40, !dbg !5666
%11 = bitcast i8* %.fca.0.2.2.gep to i64*, !dbg !5666
store i64 %.fca.0.2.2.extract, i64* %11, align 8, !dbg !5666
%.fca.0.3.0.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 3, 0, !dbg !5666
%.fca.0.3.0.gep = getelementptr inbounds i8, i8* %malloccall1, i64 48, !dbg !5666
%12 = bitcast i8* %.fca.0.3.0.gep to i64*, !dbg !5666
store i64 %.fca.0.3.0.extract, i64* %12, align 8, !dbg !5666
%.fca.0.3.1.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 3, 1, !dbg !5666
%.fca.0.3.1.gep = getelementptr inbounds i8, i8* %malloccall1, i64 56, !dbg !5666
%13 = bitcast i8* %.fca.0.3.1.gep to i64*, !dbg !5666
store i64 %.fca.0.3.1.extract, i64* %13, align 8, !dbg !5666
%.fca.0.4.0.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 4, 0, !dbg !5666
%.fca.0.4.0.gep = getelementptr inbounds i8, i8* %malloccall1, i64 64, !dbg !5666
%14 = bitcast i8* %.fca.0.4.0.gep to i64*, !dbg !5666
store i64 %.fca.0.4.0.extract, i64* %14, align 8, !dbg !5666
%.fca.0.4.1.extract = extractvalue [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] %0, 0, 4, 1, !dbg !5666
%.fca.0.4.1.gep = getelementptr inbounds i8, i8* %malloccall1, i64 72, !dbg !5666
%15 = bitcast i8* %.fca.0.4.1.gep to i64*, !dbg !5666
store i64 %.fca.0.4.1.extract, i64* %15, align 8, !dbg !5666
%malloccall2 = tail call noalias nonnull dereferenceable(80) dereferenceable_or_null(80) i8* inttoptr (i64 140737344004128 to i8* (i64)*)(i64 80), !enzyme_fromstack !5665
%16 = bitcast i8* %malloccall2 to [5 x [2 x {} addrspace(10)*]]*
%17 = addrspacecast [5 x [2 x {} addrspace(10)*]]* %16 to [5 x [2 x {} addrspace(10)*]] addrspace(11)*, !dbg !5666
%.fca.0.0.extract1 = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 0, 0, !dbg !5666
%.fca.0.0.gep2 = bitcast i8* %malloccall2 to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.0.0.extract1, {} addrspace(10)** %.fca.0.0.gep2, align 8, !dbg !5666
%.fca.0.1.extract3 = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 0, 1, !dbg !5666
%.fca.0.1.gep4 = getelementptr inbounds i8, i8* %malloccall2, i64 8, !dbg !5666
%18 = bitcast i8* %.fca.0.1.gep4 to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.0.1.extract3, {} addrspace(10)** %18, align 8, !dbg !5666
%.fca.1.0.extract5 = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 1, 0, !dbg !5666
%.fca.1.0.gep6 = getelementptr inbounds i8, i8* %malloccall2, i64 16, !dbg !5666
%19 = bitcast i8* %.fca.1.0.gep6 to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.1.0.extract5, {} addrspace(10)** %19, align 8, !dbg !5666
%.fca.1.1.extract7 = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 1, 1, !dbg !5666
%.fca.1.1.gep8 = getelementptr inbounds i8, i8* %malloccall2, i64 24, !dbg !5666
%20 = bitcast i8* %.fca.1.1.gep8 to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.1.1.extract7, {} addrspace(10)** %20, align 8, !dbg !5666
%.fca.2.0.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 2, 0, !dbg !5666
%.fca.2.0.gep = getelementptr inbounds i8, i8* %malloccall2, i64 32, !dbg !5666
%21 = bitcast i8* %.fca.2.0.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.2.0.extract, {} addrspace(10)** %21, align 8, !dbg !5666
%.fca.2.1.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 2, 1, !dbg !5666
%.fca.2.1.gep = getelementptr inbounds i8, i8* %malloccall2, i64 40, !dbg !5666
%22 = bitcast i8* %.fca.2.1.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.2.1.extract, {} addrspace(10)** %22, align 8, !dbg !5666
%.fca.3.0.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 3, 0, !dbg !5666
%.fca.3.0.gep = getelementptr inbounds i8, i8* %malloccall2, i64 48, !dbg !5666
%23 = bitcast i8* %.fca.3.0.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.3.0.extract, {} addrspace(10)** %23, align 8, !dbg !5666
%.fca.3.1.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 3, 1, !dbg !5666
%.fca.3.1.gep = getelementptr inbounds i8, i8* %malloccall2, i64 56, !dbg !5666
%24 = bitcast i8* %.fca.3.1.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.3.1.extract, {} addrspace(10)** %24, align 8, !dbg !5666
%.fca.4.0.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 4, 0, !dbg !5666
%.fca.4.0.gep = getelementptr inbounds i8, i8* %malloccall2, i64 64, !dbg !5666
%25 = bitcast i8* %.fca.4.0.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.4.0.extract, {} addrspace(10)** %25, align 8, !dbg !5666
%.fca.4.1.extract = extractvalue [5 x [2 x {} addrspace(10)*]] %2, 4, 1, !dbg !5666
%.fca.4.1.gep = getelementptr inbounds i8, i8* %malloccall2, i64 72, !dbg !5666
%26 = bitcast i8* %.fca.4.1.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.4.1.extract, {} addrspace(10)** %26, align 8, !dbg !5666
%malloccall3 = tail call noalias nonnull dereferenceable(32) dereferenceable_or_null(32) i8* inttoptr (i64 140737344004128 to i8* (i64)*)(i64 32), !enzyme_fromstack !5665
%27 = bitcast i8* %malloccall3 to { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } }*
%28 = addrspacecast { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } }* %27 to { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } addrspace(11)*, !dbg !5666
%.fca.0.0.extract = extractvalue { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } %3, 0, 0, !dbg !5666
%.fca.0.0.gep = bitcast i8* %malloccall3 to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.0.0.extract, {} addrspace(10)** %.fca.0.0.gep, align 8, !dbg !5666
%.fca.0.1.extract = extractvalue { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } %3, 0, 1, !dbg !5666
%.fca.0.1.gep = getelementptr inbounds i8, i8* %malloccall3, i64 8, !dbg !5666
%29 = bitcast i8* %.fca.0.1.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.0.1.extract, {} addrspace(10)** %29, align 8, !dbg !5666
%.fca.1.0.extract = extractvalue { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } %3, 1, 0, !dbg !5666
%.fca.1.0.gep = getelementptr inbounds i8, i8* %malloccall3, i64 16, !dbg !5666
%30 = bitcast i8* %.fca.1.0.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.1.0.extract, {} addrspace(10)** %30, align 8, !dbg !5666
%.fca.1.1.extract = extractvalue { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } %3, 1, 1, !dbg !5666
%.fca.1.1.gep = getelementptr inbounds i8, i8* %malloccall3, i64 24, !dbg !5666
%31 = bitcast i8* %.fca.1.1.gep to {} addrspace(10)**, !dbg !5666
store {} addrspace(10)* %.fca.1.1.extract, {} addrspace(10)** %31, align 8, !dbg !5666
call void @llvm.lifetime.start.p0i8(i64 noundef 40, i8* noundef nonnull align 8 dereferenceable(40) %malloccall) #41
%32 = call {}*** @julia.get_pgcstack() #41, !noalias !5667
call void @llvm.dbg.value(metadata {} addrspace(10)* null, metadata !5662, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5670
call void @llvm.dbg.declare(metadata [1 x { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }] addrspace(11)* undef, metadata !5661, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5672
call void @llvm.dbg.value(metadata {} addrspace(10)* %1, metadata !5662, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5670
call void @llvm.dbg.declare(metadata [5 x [2 x {} addrspace(10)*]] addrspace(11)* %17, metadata !5663, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5672
call void @llvm.dbg.declare(metadata { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } addrspace(11)* %28, metadata !5664, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5672
%33 = bitcast i8* %malloccall1 to { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }*, !dbg !5673
%34 = addrspacecast { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } }* %33 to { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } } addrspace(11)*, !dbg !5673
call void @llvm.dbg.value(metadata {} addrspace(10)* %1, metadata !5662, metadata !DIExpression(DW_OP_deref)) #41, !dbg !5670
call fastcc void @julia_applychain_3572({ {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } }* noalias nocapture noundef nonnull sret({ {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } }) align 8 dereferenceable(40) %4, { { float, float, i64 }, { i64, i64 }, { float, float, i64 }, { i64, i64 }, { i64, i64 } } addrspace(11)* nocapture noundef nonnull readonly align 8 dereferenceable(80) %34, {} addrspace(10)* nonnull align 16 dereferenceable(40) %1, [5 x [2 x {} addrspace(10)*]] addrspace(11)* nocapture noundef nonnull readonly align 8 dereferenceable(80) %17, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } addrspace(11)* nocapture noundef nonnull readonly align 8 dereferenceable(32) %28) #34, !dbg !5676, !noalias !5667
%.sroa.0.0..sroa_idx = bitcast i8* %malloccall to {} addrspace(10)**, !dbg !5677
%.sroa.0.0.copyload = load {} addrspace(10)*, {} addrspace(10)** %.sroa.0.0..sroa_idx, align 8, !dbg !5677
%.sroa.2.0..sroa_idx9 = getelementptr inbounds i8, i8* %malloccall, i64 8, !dbg !5677
%35 = bitcast i8* %.sroa.2.0..sroa_idx9 to {} addrspace(10)**, !dbg !5677
%.sroa.2.0.copyload = load {} addrspace(10)*, {} addrspace(10)** %35, align 8, !dbg !5677
%.sroa.3.0..sroa_idx10 = getelementptr inbounds i8, i8* %malloccall, i64 16, !dbg !5677
%36 = bitcast i8* %.sroa.3.0..sroa_idx10 to {} addrspace(10)**, !dbg !5677
%.sroa.3.0.copyload = load {} addrspace(10)*, {} addrspace(10)** %36, align 8, !dbg !5677
%.sroa.4.0..sroa_idx11 = getelementptr inbounds i8, i8* %malloccall, i64 24, !dbg !5677
%37 = bitcast i8* %.sroa.4.0..sroa_idx11 to {} addrspace(10)**, !dbg !5677
%.sroa.4.0.copyload = load {} addrspace(10)*, {} addrspace(10)** %37, align 8, !dbg !5677
%.sroa.5.0..sroa_idx12 = getelementptr inbounds i8, i8* %malloccall, i64 32, !dbg !5677
%38 = bitcast i8* %.sroa.5.0..sroa_idx12 to {} addrspace(10)**, !dbg !5677
%.sroa.5.0.copyload = load {} addrspace(10)*, {} addrspace(10)** %38, align 8, !dbg !5677
call void @llvm.lifetime.end.p0i8(i64 40, i8* nonnull %malloccall) #41, !dbg !5677
%.fca.0.insert = insertvalue { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } undef, {} addrspace(10)* %.sroa.0.0.copyload, 0, !dbg !5666
%.fca.1.0.0.insert = insertvalue { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } %.fca.0.insert, {} addrspace(10)* %.sroa.2.0.copyload, 1, 0, 0, !dbg !5666
%.fca.1.0.1.insert = insertvalue { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } %.fca.1.0.0.insert, {} addrspace(10)* %.sroa.3.0.copyload, 1, 0, 1, !dbg !5666
%.fca.1.1.0.insert = insertvalue { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } %.fca.1.0.1.insert, {} addrspace(10)* %.sroa.4.0.copyload, 1, 1, 0, !dbg !5666
%.fca.1.1.1.insert = insertvalue { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } %.fca.1.1.0.insert, {} addrspace(10)* %.sroa.5.0.copyload, 1, 1, 1, !dbg !5666
ret { {} addrspace(10)*, { { {} addrspace(10)*, {} addrspace(10)* }, { {} addrspace(10)*, {} addrspace(10)* } } } %.fca.1.1.1.insert, !dbg !5666
}
@vchuravy alternatively, would using the GC functions you mentioned earlier remedy.
@vtjnash is it possible to have this function extended to also handle (newtype*)malloc(...) somehow
This is a tape allocation? Yes I think what I mentioned would work here