IRTools.jl icon indicating copy to clipboard operation
IRTools.jl copied to clipboard

Calling `functional` with IR for `Dict` `getindex` raises `AssertionError`

Open rtjoa opened this issue 3 years ago • 2 comments

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)

rtjoa avatar Jun 16 '22 02:06 rtjoa

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.

MikeInnes avatar Jun 23 '22 14:06 MikeInnes

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

guyvdbroeck avatar Mar 22 '23 05:03 guyvdbroeck