diff --git a/erts/emulator/beam/jit/arm/instr_common.cpp b/erts/emulator/beam/jit/arm/instr_common.cpp index f08d1a35546b..4b2b89a9ede6 100644 --- a/erts/emulator/beam/jit/arm/instr_common.cpp +++ b/erts/emulator/beam/jit/arm/instr_common.cpp @@ -1581,6 +1581,30 @@ void BeamModuleAssembler::emit_is_eq_exact(const ArgLabel &Fail, return; } + /* Inline the comparison if the RHS argument is a list of one + * immediate value such as `[42]` or `[a]`. */ + if (Y.isLiteral()) { + Eterm literal = beamfile_get_literal(beam, Y.as().get()); + if (is_list(literal) && is_immed(CAR(list_val(literal))) && + is_nil(CDR(list_val(literal)))) { + arm::Gp cons_ptr; + + comment("inlined exact comparison with %T", literal); + if (!exact_type(X)) { + emit_is_cons(resolve_beam_label(Fail, dispUnknown), x.reg); + } + cons_ptr = emit_ptr_val(TMP1, x.reg); + a.sub(TMP1, cons_ptr, imm(TAG_PRIMARY_LIST)); + a.ldp(TMP2, TMP3, arm::Mem(TMP1)); + cmp(TMP2, CAR(list_val(literal))); + mov_imm(TMP4, NIL); + a.ccmp(TMP3, TMP4, imm(NZCV::kNone), imm(arm::CondCode::kEQ)); + a.b_ne(resolve_beam_label(Fail, disp1MB)); + + return; + } + } + /* Both operands are registers or literals. */ Label next = a.newLabel(); auto y = load_source(Y, ARG2);