@jameson has answered:
Probably not really, since the question is underspecified once you have an IRCode stripped of its MethodInstance. The MethodInstance is needed to provide context to inference
@aviatesk has answered:
It’s very hacky and not recommended, but you can do something like:
julia> function foo(x,y)
z = x * y
z + sin(x)
end;
julia> ir, = only(Base.code_ircode(foo, (Float64,Float64,)));
julia> ir.stmts.type .= Any;
julia> ir
2 1 ─ %1 = Base.mul_float(_2, _3)::Any │╻ *
3 │ %2 = invoke Main.sin(_2::Float64)::Any │
│ %3 = Base.add_float(%1, %2)::Any │╻ +
└── return %3 │
julia> interp = Core.Compiler.NativeInterpreter();
julia> world = Core.Compiler.get_world_counter(interp);
julia> mi = only(methods(foo)).specializations;
julia> argtypes = Any[Core.Const(foo), Float64, Float64];
julia> src = first(@code_typed foo(1.0, 2.0));
julia> method_info = Core.Compiler.MethodInfo(src);
julia> irsv = Core.Compiler.IRInterpretationState(interp, method_info, ir, mi, argtypes, world, src.min_world, src.max_world);
julia> irsv.argtypes_refined .|= true; # force reinference
julia> Core.Compiler.ir_abstract_constant_propagation(interp, irsv);
julia> irsv.ir
2 1 ─ %1 = Base.mul_float(_2, _3)::Float64 │╻ *
3 │ %2 = invoke Main.sin(_2::Float64)::Float64 │
│ %3 = Base.add_float(%1, %2)::Float64 │╻ +
└── return %3 │