RFR: 8333382: [s390x] Enhance popcnt Instruction to use Z15 facilities [v4]
Andrew Haley
aph at openjdk.org
Mon Jun 10 15:36:13 UTC 2024
On Mon, 10 Jun 2024 15:12:47 GMT, Andrew Haley <aph at openjdk.org> wrote:
>>>anywhere else must provide a register to use or have some sort of conditionals at the point pop_count_int is used.
>>
>> So for machines `<=Z14` we will never go in the `if` block; And the moment we enter in `else` block there is check, which confirms `r_tmp` shouldn't be `noreg` which will force author to pass a temporary register. Isn't it ?
>
>> > anywhere else must provide a register to use or have some sort of conditionals at the point pop_count_int is used.
>>
>> So for machines `<=Z14` we will never go in the `if` block; And the moment we enter in `else` block there is check, which confirms `r_tmp` shouldn't be `noreg` which will force author to pass a temporary register. Isn't it ?
>
> The point is to avoid the failure where testing is done on Z15 and up, but some customers have earlier machines. A maintenance programmer uses popcount and all the testing on Z15 passes. The first person to see the failure is the customer. We're setting a trap for maintainers.
>
> This is not a complaint about the ad file use case. It's about anywhere else that popcount is used in hand-written assembly code. I'm telling you this from painful experience on AArch64.
It'd be safer to break `pop_count_long` into two parts, for new and old versions, then use the two parts explicitly in s390x.ad patterns. Say, like this:
instruct popCountI_Ext3(iRegI dst, iRegI src, flagsReg cr) %{
match(Set dst (PopCountI src));
effect(TEMP_DEF dst, KILL cr);
predicate(UsePopCountInstruction &&
VM_Version::has_PopCount() &&
VM_Version::has_MiscInstrExt3());
ins_cost(DEFAULT_COST);
size(8); // popcnt + llgfr
format %{ "POPCNT $dst,$src\t # pop count int" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
__ pop_count_int_post_z15(Rdst, Rsrc);
%}
ins_pipe(pipe_class_dummy);
%}
void MacroAssembler::pop_count_int(Register r_dst, Register r_src, Register r_tmp) {
assert(r_tmp != noreg, "temp register required for popcnt, for machines < z15");
assert_different_registers(r_dst, r_tmp); // if r_src is same as r_tmp, it should be fine
if (VM_Version::has_MiscInstrExt3()) {
pop_count_int_post_z15(r_dst, r_src);
} else {
pop_count_int_pre_z15(r_dst, r_src, r_tmp);
}
}
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/19509#discussion_r1633454445
More information about the hotspot-dev
mailing list