Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[erlc] internal consistency check failed: "illegal_branch, try_handler" #6599

Closed
RobinMorisset opened this issue Dec 29, 2022 · 12 comments · Fixed by #7330
Closed

[erlc] internal consistency check failed: "illegal_branch, try_handler" #6599

RobinMorisset opened this issue Dec 29, 2022 · 12 comments · Fixed by #7330
Assignees
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM

Comments

@RobinMorisset
Copy link
Contributor

RobinMorisset commented Dec 29, 2022

On master,

f(X, #{0 := X, 0 := Y}) ->
    try #{ok => ok} of
        Y ->
            bnot (Y = X)
    after
        ok
    end.

crashes erlc with the message:

consistency_try:1: function f/2+13:
  Internal consistency check failed - please report this bug.
  Instruction: {jump,{f,8}}
  Error:       {illegal_branch,try_handler,8}:
@RobinMorisset RobinMorisset added the bug Issue is reported as a bug label Dec 29, 2022
@RobinMorisset
Copy link
Contributor Author

A couple of other testcases with the same error message:

f(X, Y) ->
    try Y of
        X ->
            (?MODULE:f1(
                try ([_ | _] = Y) of
                    X ->
                        ok
                after
                    ok
                end
            ) orelse X) bsl 0
    after
        ok
    end.

f1(_) ->
    ok.

and

f(X) ->
    {
        X ++ (X = get()),
        <<
            (ok):(catch (0 +
                try
                    [ok || _ <- []]
                catch
                    _ ->
                        X
                end))
        >>
    }.

@RobinMorisset RobinMorisset changed the title [erlc] internal consistency check failed on try_handler [erlc] internal consistency check failed: "illegal_branch, try_handler" Dec 30, 2022
@jhogberg jhogberg self-assigned this Jan 2, 2023
@jhogberg jhogberg added the team:VM Assigned to OTP team VM label Jan 2, 2023
@jhogberg
Copy link
Contributor

jhogberg commented Jan 9, 2023

Another variant:

f(X) when true; X ->
    - maybe
        <<>> ?= X,
        f(maybe
            0 ?= ([] =< ok)
        end),
        <<>> ?= ok
    else
        false  ->
            X;
        0  ->
            X
    end.

@jhogberg
Copy link
Contributor

Another variant:

f(X) ->
    Y =
        try
            false = X
        catch
            _ ->
                ok
        end /= ok,
    X = Y,
    false = Y,
    0 = ok.

@bjorng
Copy link
Contributor

bjorng commented Jan 13, 2023

Another variant:

f(X, #{0 := X, 0 := Y}, Y = [_ | _]) ->
    try
        Y = ok
    catch
        _ ->
            [_ | []] = Y = X
    end.

@RobinMorisset
Copy link
Contributor Author

Another infinite loop in the compiler (same as #6599 (comment) above), this time without using maybe:

f(_, []) ->
    0;
f(X, _) ->
    ?MODULE:foo(
        <<>> =
            try f(ok, X) + 0 of
                X ->
                    X
            catch
                _ ->
                    X
            end
    );
f(_, _) ->
    ok.

I believe that it is a duplicate of this bug because it is fixed by #6619

@jhogberg
Copy link
Contributor

Another variant:

f(X, _, X, X) ->
    ok;
f(X, (X = -0.0), (X = Y), _) ->
    -Y.

@RobinMorisset
Copy link
Contributor Author

Another probable variant:

f(X, X) when is_integer(X) ->
    ok;
f(Y, Y = #{}) ->
    Y#{ok := ok}.

results in

test7150:1: function f/2+12:
  Internal consistency check failed - please report this bug.
  Instruction: {put_map_exact,{f,0},
                              {x,0},
                              {x,0},
                              1,
                              {list,[{atom,ok},{atom,ok}]}}
  Error:       {bad_type,{needed,{t_map,any,any}},{actual,any}}:

@jhogberg
Copy link
Contributor

jhogberg commented Apr 26, 2023

Another probable variant:

Thanks, I can confirm it's the same issue. :-)

@RobinMorisset
Copy link
Contributor Author

Another likely variant, but this time with bad_typed_register (new I think):

f(_V0) ->
    case
        trunc(
            try
                trunc(<<>> = _V0)
            catch
                _ ->
                    0.0
            end
        )
    of
        _V0 -> ok;
        _ -> 42
    end.

resulting in

test70284:1: function f/1+14:
  Internal consistency check failed - please report this bug.
  Instruction: {test,is_eq_exact,
                     {f,4},
                     [{tr,{y,0},{t_integer,any}},{integer,0}]}
  Error:       {bad_typed_register,{t_bitstring,256,true},{t_integer,any}}:

@RobinMorisset
Copy link
Contributor Author

Yet another likely variant, with yet another symptom:

f(_V0, _V1 = _V0) when _V1; _V0 ->
    _V0#{ok := ok},
    try _V0 of
        _V1 ->
            _V1
    after
        ok
    end#{
        ok := ok
    }.

results in

Function: f/2
/home/rmorisset/minimized/test168208.erl: internal error in pass beam_ssa_codegen:
exception error: no function clause matching beam_ssa_codegen:cg_instr(put_map,[{atom,exact},{atom,true},{atom,ok},{atom,ok}],{x,0}) 
  in function  beam_ssa_codegen:cg_block/3 (beam_ssa_codegen.erl, line 1381)
  in call from beam_ssa_codegen:cg_linear/2 (beam_ssa_codegen.erl, line 986)
  in call from beam_ssa_codegen:cg_linear/2 (beam_ssa_codegen.erl, line 987)
  in call from beam_ssa_codegen:cg_fun/3 (beam_ssa_codegen.erl, line 177)
  in call from beam_ssa_codegen:function/4 (beam_ssa_codegen.erl, line 129)
  in call from lists:mapfoldl_1/3 (lists.erl, line 1706)
  in call from beam_ssa_codegen:module/2 (beam_ssa_codegen.erl, line 51)

@bjorng
Copy link
Contributor

bjorng commented May 24, 2023

Yet another likely variant, with yet another symptom

I don't think so. It crashes in another compiler pass. Please put this one into a new issue.

@bjorng
Copy link
Contributor

bjorng commented May 25, 2023

Here is another one from #7285:

f(_V0, _V1 = _V0) ->
  _V0#{},
  (case _V0 of _V1 -> _V1 end)#{ok => ok}.

@bjorng bjorng self-assigned this May 27, 2023
bjorng added a commit to bjorng/otp that referenced this issue May 31, 2023
Eliminating a repeated `=:=` test can result in code that
beam_validator doesn't consider safe. This commit makes the optimization
keep the `=:=` if it seems to be significant, that is, if one or both
operands will gain type information from it.

That makes it possible to compile code from erlang#6599 such as:

    f(X, X) when is_integer(X) ->
        ok;
    f(Y, Y = #{}) ->
        Y#{ok := ok}.

(Seven other examples from erlang#6599 can now also be compiled.)

Running `scripts/diffable` shows that this fix prevented the
optimization in 14 modules (out of about 1000).
bjorng added a commit to bjorng/otp that referenced this issue May 31, 2023
Eliminating a repeated `=:=` test can result in code that
beam_validator doesn't consider safe. This commit makes the optimization
keep the `=:=` if it seems to be significant, that is, if one or both
operands will gain type information from it.

That makes it possible to compile code from erlang#6599 such as:

    f(X, X) when is_integer(X) ->
        ok;
    f(Y, Y = #{}) ->
        Y#{ok := ok}.

(Six other examples from erlang#6599 can now also be compiled.)

Running `scripts/diffable` shows that this fix prevented the
optimization in 14 modules (out of about 1000).

Closes erlang#6599
bjorng added a commit to bjorng/otp that referenced this issue May 31, 2023
Eliminating a repeated `=:=` test can result in code that
beam_validator doesn't consider safe. This commit makes the optimization
keep the `=:=` if it seems to be significant, that is, if one or both
operands will gain type information from it.

That makes it possible to compile code from erlang#6599 such as:

    f(X, X) when is_integer(X) ->
        ok;
    f(Y, Y = #{}) ->
        Y#{ok := ok}.

(Six other examples from erlang#6599 can now also be compiled.)

Running `scripts/diffable` shows that this fix prevented the
optimization in 14 modules (out of about 1000).

Closes erlang#6599
jchristgit pushed a commit to jchristgit/otp that referenced this issue Aug 11, 2023
Eliminating a repeated `=:=` test can result in code that
beam_validator doesn't consider safe. This commit makes the optimization
keep the `=:=` if it seems to be significant, that is, if one or both
operands will gain type information from it.

That makes it possible to compile code from erlang#6599 such as:

    f(X, X) when is_integer(X) ->
        ok;
    f(Y, Y = #{}) ->
        Y#{ok := ok}.

(Six other examples from erlang#6599 can now also be compiled.)

Running `scripts/diffable` shows that this fix prevented the
optimization in 14 modules (out of about 1000).

Closes erlang#6599
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM
Projects
None yet
3 participants