diff options
author | Erlang/OTP <otp@erlang.org> | 2023-04-25 17:08:52 +0200 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2023-04-25 17:08:52 +0200 |
commit | ec59a080681865a8a32003ec527b6802e8aefdc5 (patch) | |
tree | 3d6fa69af031753c0190f39c9cdab5f14152ad9f | |
parent | e597996dded611ed8b07a29e666599818607fc12 (diff) | |
parent | c62f3fabe2ee9ca610f1fc9605181b06f820c31c (diff) | |
download | erlang-ec59a080681865a8a32003ec527b6802e8aefdc5.tar.gz |
Merge branch 'john/erts/fix-hd-tl-loader-transformations/GH-7024/OTP-18519' into maint-25
* john/erts/fix-hd-tl-loader-transformations/GH-7024/OTP-18519:
jit: Fix hd/1 and tl/1 BIF specialization
-rw-r--r-- | erts/emulator/beam/jit/arm/ops.tab | 8 | ||||
-rw-r--r-- | erts/emulator/beam/jit/x86/instr_guard_bifs.cpp | 24 | ||||
-rw-r--r-- | erts/emulator/beam/jit/x86/ops.tab | 14 | ||||
-rw-r--r-- | lib/compiler/test/bif_SUITE.erl | 28 |
4 files changed, 44 insertions, 30 deletions
diff --git a/erts/emulator/beam/jit/arm/ops.tab b/erts/emulator/beam/jit/arm/ops.tab index cc0bfeccf0..9cfce18e58 100644 --- a/erts/emulator/beam/jit/arm/ops.tab +++ b/erts/emulator/beam/jit/arm/ops.tab @@ -666,18 +666,14 @@ i_perf_counter bif0 u$bif:erlang:self/0 Dst=d => self Dst bif0 u$bif:erlang:node/0 Dst=d => node Dst -bif1 Fail=f Bif=u$bif:erlang:hd/1 Src=n Dst => - jump Fail -bif1 Fail=f Bif=u$bif:erlang:hd/1 Src Dst => +bif1 Fail=f Bif=u$bif:erlang:hd/1 Src=xy Dst => is_nonempty_list Fail Src | get_hd Src Dst bif1 Fail=p Bif=u$bif:erlang:hd/1 Src Dst => bif_hd Src Dst bif_hd s d -bif1 Fail=f Bif=u$bif:erlang:tl/1 Src=n Dst => - jump Fail -bif1 Fail=f Bif=u$bif:erlang:tl/1 Src Dst => +bif1 Fail=f Bif=u$bif:erlang:tl/1 Src=xy Dst => is_nonempty_list Fail Src | get_tl Src Dst bif1 Fail=p Bif=u$bif:erlang:tl/1 Src Dst => bif_tl Src Dst diff --git a/erts/emulator/beam/jit/x86/instr_guard_bifs.cpp b/erts/emulator/beam/jit/x86/instr_guard_bifs.cpp index 4dfe39cb98..26133d5ac0 100644 --- a/erts/emulator/beam/jit/x86/instr_guard_bifs.cpp +++ b/erts/emulator/beam/jit/x86/instr_guard_bifs.cpp @@ -60,24 +60,22 @@ void BeamGlobalAssembler::emit_handle_hd_error() { * The code size for this specialization of hd/1 is 21 bytes, * while the code size for the bif1 instruction is 24 bytes. */ -void BeamModuleAssembler::emit_bif_hd(const ArgLabel &Fail, - const ArgSource &Src, +void BeamModuleAssembler::emit_bif_hd(const ArgSource &Src, const ArgRegister &Hd) { + Label good_cons = a.newLabel(); + mov_arg(RET, Src); a.test(RETb, imm(_TAG_PRIMARY_MASK - TAG_PRIMARY_LIST)); - if (Fail.get() != 0) { - a.jne(resolve_beam_label(Fail)); - } else { - Label next = a.newLabel(); - a.short_().je(next); - safe_fragment_call(ga->get_handle_hd_error()); - a.bind(next); - } + a.short_().je(good_cons); + safe_fragment_call(ga->get_handle_hd_error()); - x86::Gp boxed_ptr = emit_ptr_val(RET, RET); - a.mov(ARG2, getCARRef(boxed_ptr)); - mov_arg(Hd, ARG2); + a.bind(good_cons); + { + x86::Gp boxed_ptr = emit_ptr_val(RET, RET); + a.mov(ARG2, getCARRef(boxed_ptr)); + mov_arg(Hd, ARG2); + } } void BeamGlobalAssembler::emit_handle_element_error() { diff --git a/erts/emulator/beam/jit/x86/ops.tab b/erts/emulator/beam/jit/x86/ops.tab index 1ce0d6f9c2..5481fff2d8 100644 --- a/erts/emulator/beam/jit/x86/ops.tab +++ b/erts/emulator/beam/jit/x86/ops.tab @@ -660,18 +660,14 @@ i_perf_counter bif0 u$bif:erlang:self/0 Dst=d => self Dst bif0 u$bif:erlang:node/0 Dst=d => node Dst -bif1 Fail=f Bif=u$bif:erlang:hd/1 Src=n Dst => - jump Fail -bif1 Fail=f Bif=u$bif:erlang:hd/1 Src Dst => +bif1 Fail=f Bif=u$bif:erlang:hd/1 Src=xy Dst => is_nonempty_list Fail Src | get_hd Src Dst -bif1 Fail Bif=u$bif:erlang:hd/1 Src Dst => - bif_hd Fail Src Dst +bif1 Fail=p Bif=u$bif:erlang:hd/1 Src Dst => + bif_hd Src Dst -bif_hd j s d +bif_hd s d -bif1 Fail=f Bif=u$bif:erlang:tl/1 Src=n Dst => - jump Fail -bif1 Fail=f Bif=u$bif:erlang:tl/1 Src Dst => +bif1 Fail=f Bif=u$bif:erlang:tl/1 Src=xy Dst => is_nonempty_list Fail Src | get_tl Src Dst bif1 Fail Bif=u$bif:erlang:get/1 Src=s Dst=d => get(Src, Dst) diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl index 8480569507..34bf54a871 100644 --- a/lib/compiler/test/bif_SUITE.erl +++ b/lib/compiler/test/bif_SUITE.erl @@ -24,7 +24,8 @@ -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, init_per_group/2,end_per_group/2, beam_validator/1,trunc_and_friends/1,cover_safe_and_pure_bifs/1, - cover_trim/1]). + cover_trim/1, + head_tail/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -37,7 +38,8 @@ groups() -> [beam_validator, trunc_and_friends, cover_safe_and_pure_bifs, - cover_trim + cover_trim, + head_tail ]}]. init_per_suite(Config) -> @@ -167,6 +169,28 @@ cover_trim_3(Header, N)-> false end. +%% GH-7024: The loader transformations for hd/1 and tl/1 were incorrect and +%% failed when certain optimizations were turned off. +head_tail(_Config) -> + {1, ok} = head_case(), + {1, ok} = tail_case(), + + 1 = hd(id([1])), + [] = tl(id([1])), + + ok. + +head_case() -> + case 1 of + X when hd(X) -> blurf; + X -> {X, ok} + end. + +tail_case() -> + case 1 of + X when tl(X) -> blurf; + X -> {X, ok} + end. id(I) -> I. |