RFR: 8372980: [VectorAPI] AArch64: Add intrinsic support for unsigned min/max reduction operations [v3]
Andrew Haley
aph at openjdk.org
Mon Feb 2 09:11:58 UTC 2026
On Mon, 2 Feb 2026 08:55:45 GMT, Xiaohong Gong <xgong at openjdk.org> wrote:
>> src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp line 50:
>>
>>> 48: void sve_maxv(bool is_unsigned, FloatRegister dst, SIMD_RegVariant size,
>>> 49: PRegister pg, FloatRegister src);
>>> 50:
>>
>> Using separate definitions here is adding unnecessary complexity.
>>
>> I'd do something like this in the header file:
>>
>>
>> // Typedefs used to disambiguate overloaded member functions.
>> typedef void (Assembler::*neon_reduction2)
>> (FloatRegister, Assembler::SIMD_Arrangement, FloatRegister);
>> typedef void (Assembler::*sve_reduction3)
>> (FloatRegister, Assembler::SIMD_RegVariant, PRegister, FloatRegister);
>>
>> // Helper functions for min/max reduction operations
>> void neon_minp(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
>> FloatRegister src1, FloatRegister src2) {
>> auto m = is_unsigned ? &Assembler::uminp : &Assembler::sminp;
>> (this->*m)(dst, size, src1, src2);
>> }
>> void neon_maxp(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
>> FloatRegister src1, FloatRegister src2) {
>> auto m = is_unsigned ? &Assembler::umaxp : &Assembler::smaxp;
>> (this->*m)(dst, size, src1, src2);
>> }
>> void neon_minv(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
>> FloatRegister src) {
>> auto m = is_unsigned ? (neon_reduction2)&Assembler::uminv : &Assembler::sminv;
>> (this->*m)(dst, size, src);
>> }
>> void neon_maxv(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
>> FloatRegister src) {
>> auto m = is_unsigned ? (neon_reduction2)&Assembler::umaxv : &Assembler::smaxv;
>> (this->*m)(dst, size, src);
>> }
>> void sve_minv(bool is_unsigned, FloatRegister dst, SIMD_RegVariant size,
>> PRegister pg, FloatRegister src) {
>> auto m = is_unsigned ? (sve_reduction3)&Assembler::sve_uminv : &Assembler::sve_sminv;
>> (this->*m)(dst, size, pg, src);
>> }
>> void sve_maxv(bool is_unsigned, FloatRegister dst, SIMD_RegVariant size,
>> PRegister pg, FloatRegister src) {
>> auto m = is_unsigned ? (sve_reduction3)&Assembler::sve_umaxv : &Assembler::sve_smaxv;
>> (this->*m)(dst, size, pg, src);
>> }
>>
>>
>>
>> To some extent it's a matter of taste, but please try not to use much more repetitive and boilerplate code than you need to.
>
> I’m not sure, but would the code below be better? It might make the macro assembler a bit tidier.
>
> void neon_minmaxp(bool is_unsigned, bool is_max, FloatRegister dst,
> SIMD_Arrangement size, FloatRegister src1, FloatRegister src2) {
> auto m = is_unsigned ? (is_max ? &Assembler::umaxp : &Assembler::uminp)
> : (is_max ? &Assembler::smaxp : &Assembler::sminp);
> (this->*m)(dst, size, src1, src2);
> }
Sure, that's good.
This is exactly the kind of thing we need to keep the code as small and simple as possible.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/28693#discussion_r2753309806
More information about the core-libs-dev
mailing list