diff --git a/erts/emulator/beam/jit/x86/instr_common.cpp b/erts/emulator/beam/jit/x86/instr_common.cpp index 9157ed6e9c46..1631cb99b0c6 100644 --- a/erts/emulator/beam/jit/x86/instr_common.cpp +++ b/erts/emulator/beam/jit/x86/instr_common.cpp @@ -1249,12 +1249,10 @@ void BeamModuleAssembler::emit_i_test_arity(const ArgLabel &Fail, void BeamModuleAssembler::emit_is_eq_exact(const ArgLabel &Fail, const ArgSource &X, const ArgSource &Y) { - /* If either argument is known to be an immediate, we can fail immediately - * if they're not equal. */ - if (always_immediate(X) || always_immediate(Y)) { - if (!X.isImmed() && !Y.isImmed()) { - comment("simplified check since one argument is an immediate"); - } + /* If one argument is known to be an immediate, we can fail + * immediately if they're not equal. */ + if (X.isRegister() && always_immediate(Y)) { + comment("simplified check since one argument is an immediate"); cmp_arg(getArgRef(X), Y); a.jne(resolve_beam_label(Fail)); @@ -1320,12 +1318,10 @@ void BeamModuleAssembler::emit_i_is_eq_exact_literal(const ArgLabel &Fail, void BeamModuleAssembler::emit_is_ne_exact(const ArgLabel &Fail, const ArgSource &X, const ArgSource &Y) { - /* If either argument is known to be an immediate, we can fail immediately - * if they're equal. */ - if (always_immediate(X) || always_immediate(Y)) { - if (!X.isImmed() && !Y.isImmed()) { - comment("simplified check since one argument is an immediate"); - } + /* If one argument is known to be an immediate, we can fail + * immediately if they're equal. */ + if (X.isRegister() && always_immediate(Y)) { + comment("simplified check since one argument is an immediate"); cmp_arg(getArgRef(X), Y); a.je(resolve_beam_label(Fail)); diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl index 9d829ffc59d8..fc0dbf80a919 100644 --- a/erts/emulator/test/guard_SUITE.erl +++ b/erts/emulator/test/guard_SUITE.erl @@ -391,6 +391,18 @@ guard_bifs(Config) when is_list(Config) -> try_fail_gbif('node/0', 0, xxxx), try_fail_gbif('node/1', self(), xxx), try_fail_gbif('node/1', yyy, xxx), + + {'EXIT', {function_clause, _}} = catch gh_6634({a,b}), + {'EXIT', {function_clause, _}} = catch gh_6634(42), + + ok. + +gh_6634(X) when is_tuple(X) andalso not ok -> + %% `not ok` would be translated to an is_eq_exact instruction, + %% which the JIT would not handle correctly because it had two + %% immediate operands. In a release build incorrect code would be + %% generated, which might crash the runtime system; in a debug + %% build an assertion would fire at load time ok. try_gbif(Id, X, Y) ->