Skip to content

Commit

Permalink
Fix failed assertion in debug build
Browse files Browse the repository at this point in the history
Closes #6634
  • Loading branch information
bjorng committed Jan 6, 2023
1 parent f3e2505 commit 428dbdd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
20 changes: 8 additions & 12 deletions erts/emulator/beam/jit/x86/instr_common.cpp
Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down
12 changes: 12 additions & 0 deletions erts/emulator/test/guard_SUITE.erl
Expand Up @@ -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) ->
Expand Down

0 comments on commit 428dbdd

Please sign in to comment.