IRTools.jl
IRTools.jl copied to clipboard
Calling `functional` with IR for `Dict` `getindex` raises `AssertionError`
The following example fails this assert on Julia v1.7.2, IRTools v0.4.6:
using IRTools: IR, functional
ir = IR(typeof(getindex), Dict{String, String}, String)
functional(ir)
The use of @inbounds return ... here leads to a redundant trailing block in the IR:
1: (%1, %2, %3)
%4 = Base.ht_keyindex(%2, %3)
%5 = $(Expr(:inbounds, true))
%6 = %4 < 0
br 3 unless %6
2:
%7 = Base.KeyError(%3)
%8 = Base.throw(%7)
return %8
3:
%9 = Base.getproperty(%2, :vals)
%10 = Base.getindex(%9, %4)
%11 = Core.typeassert(%10, $(QuoteNode(String)))
return %11
4:
%12 = $(Expr(:inbounds, :pop))
ie block 4 isn't reachable here, and violates our assumptions by not branching anywhere. I guess the Julia compiler has some way to handle this case. I know little about how the :inbounds expression works so I'm not sure if it's safe to simply drop the :pop; for functional we could just remove all :inbounds expressions.
I've been meaning to build some tools for stripping unreachable code, so when I do I'll try to fix this issue as well.
There appear to be more general issues with functional, for example the following code also errors while every block is reachable:
using IRTools: IR, functional
f(x,y) = x && y && error()
ir = IR(typeof(f), Bool, Bool)
functional(ir)
The issue is with the 3 branches in the generated IR:
ir = 1: (%1, %2, %3)
br 4 unless %2
br 3 unless %3
br 2
2:
%4 = Main.error()
return %4
3:
return false
4:
return false