From 723fada571b80b3cacaedfd7e140301fe70a14c2 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 8 Jul 2026 01:10:51 -0400 Subject: [PATCH] Fix conditional wrappers for vararg runtime calls Co-Authored-By: Chris Rackauckas --- src/gradientutils.jl | 18 ++++++++++++++---- test/typeunstable.jl | 27 ++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/gradientutils.jl b/src/gradientutils.jl index 6844495308..daf8cd4dbf 100644 --- a/src/gradientutils.jl +++ b/src/gradientutils.jl @@ -106,9 +106,13 @@ function set_reverse_block!(gutils::GradientUtils, block::LLVM.BasicBlock) return API.EnzymeGradientUtilsSetReverseBlock(gutils, block) end -function get_or_insert_conditional_execute!(fn::LLVM.Function; force_run=false, need_result=true, preprocess=nothing, postprocess=nothing, postprocess_const=nothing, cmpidx::Int = 1) +function get_or_insert_conditional_execute!(fn::LLVM.Function; force_run=false, need_result=true, preprocess=nothing, postprocess=nothing, postprocess_const=nothing, cmpidx::Int = 1, arg_tys=nothing) FT0 = LLVM.function_type(fn) ptys = LLVM.parameters(FT0) + if length(ptys) < cmpidx + @assert arg_tys !== nothing + ptys = collect(LLVM.LLVMType, arg_tys) + end insert!(ptys, 1, ptys[cmpidx]) void_rt = LLVM.return_type(FT0) == LLVM.VoidType() || !need_result @@ -134,6 +138,9 @@ function get_or_insert_conditional_execute!(fn::LLVM.Function; force_run=false, if postprocess_const !== nothing newname = newname * ".poc_$(postprocess_const)" end + if arg_tys !== nothing + newname = newname * ".argtys$(hash(string.(arg_tys)))" + end newname = newname * LLVM.name(fn) cfn, _ = get_function!(mod, newname, FT) if isempty(blocks(cfn)) @@ -151,7 +158,7 @@ function get_or_insert_conditional_execute!(fn::LLVM.Function; force_run=false, if force_run if preprocess !== nothing - ppr = preprocess(builder, args) + ppr = preprocess(builder, rparms) end res = call!(builder, FT0, fn, rparms) callconv!(res, callconv(fn)) @@ -275,14 +282,17 @@ function call_same_with_inverted_arg_if_active!( valTys[cmpidx] = API.VT_Both end args = collect(LLVM.Value, args) + prefn = LLVM.called_operand(orig)::LLVM.Function + arg_tys = if length(LLVM.parameters(LLVM.function_type(prefn))) < cmpidx + LLVM.LLVMType[value_type(arg) for arg in args] + end insert!(args, 1, new_from_original(gutils, origops[cmpidx])) newval = nothing if value_type(orig) != LLVM.VoidType() && postprocess_const === nothing && need_result newval = new_from_original(gutils, orig) insert!(args, 1, newval) end - prefn = LLVM.called_operand(orig)::LLVM.Function - condfn = get_or_insert_conditional_execute!(prefn; force_run, preprocess, postprocess, postprocess_const, need_result, cmpidx) + condfn = get_or_insert_conditional_execute!(prefn; force_run, preprocess, postprocess, postprocess_const, need_result, cmpidx, arg_tys) res = LLVM.Value( API.EnzymeGradientUtilsCallWithInvertedBundles( diff --git a/test/typeunstable.jl b/test/typeunstable.jl index b1a69d08a1..c256c61e49 100644 --- a/test/typeunstable.jl +++ b/test/typeunstable.jl @@ -285,4 +285,29 @@ end Enzyme.autodiff(set_runtime_activity(Reverse), Enzyme.Const(loss_3280), Enzyme.Active, Enzyme.Duplicated(p, dp)) @test dp ≈ [1.0] -end \ No newline at end of file +end + +mutable struct TypeUnstableSetpropertyBox + x::Any +end + +@noinline function setproperty_unstable!(box, name, x)::Any + setproperty!(box, name, x) + return box +end + +function setproperty_unstable_fn(x) + box = TypeUnstableSetpropertyBox(nothing) + name = Base.inferencebarrier(:x) + setproperty_unstable!(box, name, x[1]) + return box.x +end + +@testset "Forward type-unstable setproperty!" begin + res = Enzyme.autodiff( + set_runtime_activity(Forward), + setproperty_unstable_fn, + Duplicated([2.0], [3.0]), + ) + @test res[1] ≈ 3.0 +end