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