[v2,2/3] aarch64: Introduce new unspecs for smax/smin

Message ID 20241001120933.1269122-3-saurabh.jha@arm.com
State New
Headers
Series Add support for SVE2 faminmax |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Saurabh Jha Oct. 1, 2024, 12:09 p.m. UTC
  Introduce two new unspecs, UNSPEC_COND_SMAX and UNSPEC_COND_SMIN,
corresponding to rtl operators smax and smin. UNSPEC_COND_SMAX is used
to generate fmaxnm instruction and UNSPEC_COND_SMIN is used to generate
fminnm instruction.

With these new unspecs, we can generate SVE2 max/min instructions using
existing generic unpredicated and predicated instruction patterns that
use optab attribute. Thus, we have removed specialised instruction
patterns for max/min instructions that were using
SVE_COND_FP_MAXMIN_PUBLIC iterator.

No new test cases as the existing test cases should be enough to test
this refactoring.

gcc/ChangeLog:

	* config/aarch64/aarch64-sve.md
	(<fmaxmin><mode>3): Remove this instruction pattern.
	(cond_<fmaxmin><mode>): Remove this instruction pattern.
	* config/aarch64/iterators.md: New unspecs and changes to
	iterators and attrs to use the new unspecs
---
 gcc/config/aarch64/aarch64-sve.md | 33 -------------------
 gcc/config/aarch64/iterators.md   | 55 ++++++++++++++++++++-----------
 2 files changed, 35 insertions(+), 53 deletions(-)
  

Comments

Richard Sandiford Oct. 1, 2024, 1:07 p.m. UTC | #1
<saurabh.jha@arm.com> writes:
> Introduce two new unspecs, UNSPEC_COND_SMAX and UNSPEC_COND_SMIN,
> corresponding to rtl operators smax and smin. UNSPEC_COND_SMAX is used
> to generate fmaxnm instruction and UNSPEC_COND_SMIN is used to generate
> fminnm instruction.
>
> With these new unspecs, we can generate SVE2 max/min instructions using
> existing generic unpredicated and predicated instruction patterns that
> use optab attribute. Thus, we have removed specialised instruction
> patterns for max/min instructions that were using
> SVE_COND_FP_MAXMIN_PUBLIC iterator.
>
> No new test cases as the existing test cases should be enough to test
> this refactoring.
>
> gcc/ChangeLog:
>
> 	* config/aarch64/aarch64-sve.md
> 	(<fmaxmin><mode>3): Remove this instruction pattern.
> 	(cond_<fmaxmin><mode>): Remove this instruction pattern.
> 	* config/aarch64/iterators.md: New unspecs and changes to
> 	iterators and attrs to use the new unspecs
> ---
>  gcc/config/aarch64/aarch64-sve.md | 33 -------------------
>  gcc/config/aarch64/iterators.md   | 55 ++++++++++++++++++++-----------
>  2 files changed, 35 insertions(+), 53 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
> index bfa28849adf..989ba9546d7 100644
> --- a/gcc/config/aarch64/aarch64-sve.md
> +++ b/gcc/config/aarch64/aarch64-sve.md
> @@ -6600,39 +6600,6 @@
>  ;; - FMINNM
>  ;; -------------------------------------------------------------------------
>  
> -;; Unpredicated fmax/fmin (the libm functions).  The optabs for the
> -;; smax/smin rtx codes are handled in the generic section above.
> -(define_expand "<fmaxmin><mode>3"
> -  [(set (match_operand:SVE_FULL_F 0 "register_operand")
> -	(unspec:SVE_FULL_F
> -	  [(match_dup 3)
> -	   (const_int SVE_RELAXED_GP)
> -	   (match_operand:SVE_FULL_F 1 "register_operand")
> -	   (match_operand:SVE_FULL_F 2 "aarch64_sve_float_maxmin_operand")]
> -	  SVE_COND_FP_MAXMIN_PUBLIC))]
> -  "TARGET_SVE"
> -  {
> -    operands[3] = aarch64_ptrue_reg (<VPRED>mode);
> -  }
> -)
> -
> -;; Predicated fmax/fmin (the libm functions).  The optabs for the
> -;; smax/smin rtx codes are handled in the generic section above.
> -(define_expand "cond_<fmaxmin><mode>"
> -  [(set (match_operand:SVE_FULL_F 0 "register_operand")
> -	(unspec:SVE_FULL_F
> -	  [(match_operand:<VPRED> 1 "register_operand")
> -	   (unspec:SVE_FULL_F
> -	     [(match_dup 1)
> -	      (const_int SVE_RELAXED_GP)
> -	      (match_operand:SVE_FULL_F 2 "register_operand")
> -	      (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand")]
> -	     SVE_COND_FP_MAXMIN_PUBLIC)
> -	   (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
> -	  UNSPEC_SEL))]
> -  "TARGET_SVE"
> -)
> -
>  ;; Predicated floating-point maximum/minimum.
>  (define_insn "@aarch64_pred_<optab><mode>"
>    [(set (match_operand:SVE_FULL_F 0 "register_operand")
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index cf9ee2639a9..d3a457fc6d9 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -884,6 +884,8 @@
>      UNSPEC_COND_FSUB	; Used in aarch64-sve.md.
>      UNSPEC_COND_SCVTF	; Used in aarch64-sve.md.
>      UNSPEC_COND_UCVTF	; Used in aarch64-sve.md.
> +    UNSPEC_COND_SMAX	; Used in aarch64-sve.md.
> +    UNSPEC_COND_SMIN	; Used in aarch64-sve.md.
>      UNSPEC_LASTA	; Used in aarch64-sve.md.
>      UNSPEC_LASTB	; Used in aarch64-sve.md.
>      UNSPEC_ASHIFT_WIDE  ; Used in aarch64-sve.md.
> @@ -3094,7 +3096,9 @@
>     UNSPEC_COND_FMINNM
>     UNSPEC_COND_FMUL
>     UNSPEC_COND_FMULX
> -   UNSPEC_COND_FSUB])
> +   UNSPEC_COND_FSUB
> +   UNSPEC_COND_SMAX
> +   UNSPEC_COND_SMIN])
>  
>  ;; Same as SVE_COND_FP_BINARY, but without codes that have a dedicated
>  ;; <optab><mode>3 expander.
> @@ -3105,7 +3109,9 @@
>  					       UNSPEC_COND_FMINNM
>  					       UNSPEC_COND_FMUL
>  					       UNSPEC_COND_FMULX
> -					       UNSPEC_COND_FSUB])
> +					       UNSPEC_COND_FSUB
> +					       UNSPEC_COND_SMAX
> +					       UNSPEC_COND_SMIN])
>  
>  (define_int_iterator SVE_COND_FP_BINARY_INT [UNSPEC_COND_FSCALE])
>  
> @@ -3117,13 +3123,17 @@
>  					    UNSPEC_COND_FMAXNM
>  					    UNSPEC_COND_FMIN
>  					    UNSPEC_COND_FMINNM
> -					    UNSPEC_COND_FMUL])
> +					    UNSPEC_COND_FMUL
> +					    UNSPEC_COND_SMAX
> +					    UNSPEC_COND_SMIN])
>  
>  (define_int_iterator SVE_COND_FP_BINARY_REG
>    [(UNSPEC_COND_FAMAX "TARGET_SVE_FAMINMAX")
>     (UNSPEC_COND_FAMIN "TARGET_SVE_FAMINMAX")
>     UNSPEC_COND_FDIV
> -   UNSPEC_COND_FMULX])
> +   UNSPEC_COND_FMULX
> +   UNSPEC_COND_SMAX
> +   UNSPEC_COND_SMIN])
>  
>  (define_int_iterator SVE_COND_FCADD [UNSPEC_COND_FCADD90
>  				     UNSPEC_COND_FCADD270])
> @@ -3133,11 +3143,6 @@
>  					 UNSPEC_COND_FMIN
>  					 UNSPEC_COND_FMINNM])
>  
> -;; Floating-point max/min operations that correspond to optabs,
> -;; as opposed to those that are internal to the port.
> -(define_int_iterator SVE_COND_FP_MAXMIN_PUBLIC [UNSPEC_COND_FMAXNM
> -						UNSPEC_COND_FMINNM])
> -
>  (define_int_iterator SVE_COND_FP_TERNARY [UNSPEC_COND_FMLA
>  					  UNSPEC_COND_FMLS
>  					  UNSPEC_COND_FNMLA
> @@ -3715,9 +3720,9 @@
>  			(UNSPEC_COND_FCVTZU "fixuns_trunc")
>  			(UNSPEC_COND_FDIV "div")
>  			(UNSPEC_COND_FMAX "fmax_nan")
> -			(UNSPEC_COND_FMAXNM "smax")
> +			(UNSPEC_COND_FMAXNM "fmax")
>  			(UNSPEC_COND_FMIN "fmin_nan")
> -			(UNSPEC_COND_FMINNM "smin")
> +			(UNSPEC_COND_FMINNM "fmin")
>  			(UNSPEC_COND_FMLA "fma")
>  			(UNSPEC_COND_FMLS "fnma")
>  			(UNSPEC_COND_FMUL "mul")
> @@ -3737,16 +3742,16 @@
>  			(UNSPEC_COND_FSQRT "sqrt")
>  			(UNSPEC_COND_FSUB "sub")
>  			(UNSPEC_COND_SCVTF "float")
> -			(UNSPEC_COND_UCVTF "floatuns")])
> +			(UNSPEC_COND_UCVTF "floatuns")
> +			(UNSPEC_COND_SMAX "smax")
> +			(UNSPEC_COND_SMIN "smin")])

It would be good to keep the entries sorted alphabetically.

OK for trunk with that change; no need for another review.

I think the can go in now, independently of the rest of the series
(provided it passes individual testing of course!)

Thanks for doing this.

Richard

>  
>  (define_int_attr fmaxmin [(UNSPEC_FMAX "fmax_nan")
>  			  (UNSPEC_FMAXNM "fmax")
>  			  (UNSPEC_FMAXNMV "fmax")
>  			  (UNSPEC_FMIN "fmin_nan")
>  			  (UNSPEC_FMINNM "fmin")
> -			  (UNSPEC_FMINNMV "fmin")
> -			  (UNSPEC_COND_FMAXNM "fmax")
> -			  (UNSPEC_COND_FMINNM "fmin")])
> +			  (UNSPEC_FMINNMV "fmin")])
>  
>  (define_int_attr  maxmin_uns_op [(UNSPEC_UMAXV "umax")
>  				 (UNSPEC_UMINV "umin")
> @@ -4263,7 +4268,9 @@
>  			    (UNSPEC_COND_FRINTZ "frintz")
>  			    (UNSPEC_COND_FSCALE "fscale")
>  			    (UNSPEC_COND_FSQRT "fsqrt")
> -			    (UNSPEC_COND_FSUB "fsub")])
> +			    (UNSPEC_COND_FSUB "fsub")
> +			    (UNSPEC_COND_SMAX "fmaxnm")
> +			    (UNSPEC_COND_SMIN "fminnm")])
>  
>  (define_int_attr sve_fp_op_rev [(UNSPEC_COND_FADD "fadd")
>  				(UNSPEC_COND_FAMAX "famax")
> @@ -4275,7 +4282,9 @@
>  				(UNSPEC_COND_FMINNM "fminnm")
>  				(UNSPEC_COND_FMUL "fmul")
>  				(UNSPEC_COND_FMULX "fmulx")
> -				(UNSPEC_COND_FSUB "fsubr")])
> +				(UNSPEC_COND_FSUB "fsubr")
> +				(UNSPEC_COND_SMAX "fmaxnm")
> +				(UNSPEC_COND_SMIN "fminnm")])
>  
>  (define_int_attr sme_int_op [(UNSPEC_SME_ADD_WRITE "add")
>  			     (UNSPEC_SME_SUB_WRITE "sub")])
> @@ -4413,7 +4422,9 @@
>     (UNSPEC_COND_FMINNM "register_operand")
>     (UNSPEC_COND_FMUL "register_operand")
>     (UNSPEC_COND_FMULX "register_operand")
> -   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")])
> +   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")
> +   (UNSPEC_COND_SMAX "register_operand")
> +   (UNSPEC_COND_SMIN "register_operand")])
>  
>  ;; The predicate to use for the second input operand in a floating-point
>  ;; <optab><mode>3 pattern.
> @@ -4428,7 +4439,9 @@
>     (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_operand")
>     (UNSPEC_COND_FMUL "aarch64_sve_float_mul_operand")
>     (UNSPEC_COND_FMULX "register_operand")
> -   (UNSPEC_COND_FSUB "register_operand")])
> +   (UNSPEC_COND_FSUB "register_operand")
> +   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_operand")
> +   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_operand")])
>  
>  ;; Likewise for immediates only.
>  (define_int_attr sve_pred_fp_rhs2_immediate
> @@ -4436,7 +4449,9 @@
>     (UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_immediate")
>     (UNSPEC_COND_FMIN "aarch64_sve_float_maxmin_immediate")
>     (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_immediate")
> -   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")])
> +   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")
> +   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_immediate")
> +   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_immediate")])
>  
>  ;; The maximum number of element bits that an instruction can handle.
>  (define_int_attr max_elem_bits [(UNSPEC_UADDV "64") (UNSPEC_SADDV "32")
  
Saurabh Jha Oct. 1, 2024, 4:46 p.m. UTC | #2
On 10/1/2024 2:07 PM, Richard Sandiford wrote:
> <saurabh.jha@arm.com> writes:
>> Introduce two new unspecs, UNSPEC_COND_SMAX and UNSPEC_COND_SMIN,
>> corresponding to rtl operators smax and smin. UNSPEC_COND_SMAX is used
>> to generate fmaxnm instruction and UNSPEC_COND_SMIN is used to generate
>> fminnm instruction.
>>
>> With these new unspecs, we can generate SVE2 max/min instructions using
>> existing generic unpredicated and predicated instruction patterns that
>> use optab attribute. Thus, we have removed specialised instruction
>> patterns for max/min instructions that were using
>> SVE_COND_FP_MAXMIN_PUBLIC iterator.
>>
>> No new test cases as the existing test cases should be enough to test
>> this refactoring.
>>
>> gcc/ChangeLog:
>>
>> 	* config/aarch64/aarch64-sve.md
>> 	(<fmaxmin><mode>3): Remove this instruction pattern.
>> 	(cond_<fmaxmin><mode>): Remove this instruction pattern.
>> 	* config/aarch64/iterators.md: New unspecs and changes to
>> 	iterators and attrs to use the new unspecs
>> ---
>>   gcc/config/aarch64/aarch64-sve.md | 33 -------------------
>>   gcc/config/aarch64/iterators.md   | 55 ++++++++++++++++++++-----------
>>   2 files changed, 35 insertions(+), 53 deletions(-)
>>
>> diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
>> index bfa28849adf..989ba9546d7 100644
>> --- a/gcc/config/aarch64/aarch64-sve.md
>> +++ b/gcc/config/aarch64/aarch64-sve.md
>> @@ -6600,39 +6600,6 @@
>>   ;; - FMINNM
>>   ;; -------------------------------------------------------------------------
>>   
>> -;; Unpredicated fmax/fmin (the libm functions).  The optabs for the
>> -;; smax/smin rtx codes are handled in the generic section above.
>> -(define_expand "<fmaxmin><mode>3"
>> -  [(set (match_operand:SVE_FULL_F 0 "register_operand")
>> -	(unspec:SVE_FULL_F
>> -	  [(match_dup 3)
>> -	   (const_int SVE_RELAXED_GP)
>> -	   (match_operand:SVE_FULL_F 1 "register_operand")
>> -	   (match_operand:SVE_FULL_F 2 "aarch64_sve_float_maxmin_operand")]
>> -	  SVE_COND_FP_MAXMIN_PUBLIC))]
>> -  "TARGET_SVE"
>> -  {
>> -    operands[3] = aarch64_ptrue_reg (<VPRED>mode);
>> -  }
>> -)
>> -
>> -;; Predicated fmax/fmin (the libm functions).  The optabs for the
>> -;; smax/smin rtx codes are handled in the generic section above.
>> -(define_expand "cond_<fmaxmin><mode>"
>> -  [(set (match_operand:SVE_FULL_F 0 "register_operand")
>> -	(unspec:SVE_FULL_F
>> -	  [(match_operand:<VPRED> 1 "register_operand")
>> -	   (unspec:SVE_FULL_F
>> -	     [(match_dup 1)
>> -	      (const_int SVE_RELAXED_GP)
>> -	      (match_operand:SVE_FULL_F 2 "register_operand")
>> -	      (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand")]
>> -	     SVE_COND_FP_MAXMIN_PUBLIC)
>> -	   (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
>> -	  UNSPEC_SEL))]
>> -  "TARGET_SVE"
>> -)
>> -
>>   ;; Predicated floating-point maximum/minimum.
>>   (define_insn "@aarch64_pred_<optab><mode>"
>>     [(set (match_operand:SVE_FULL_F 0 "register_operand")
>> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
>> index cf9ee2639a9..d3a457fc6d9 100644
>> --- a/gcc/config/aarch64/iterators.md
>> +++ b/gcc/config/aarch64/iterators.md
>> @@ -884,6 +884,8 @@
>>       UNSPEC_COND_FSUB	; Used in aarch64-sve.md.
>>       UNSPEC_COND_SCVTF	; Used in aarch64-sve.md.
>>       UNSPEC_COND_UCVTF	; Used in aarch64-sve.md.
>> +    UNSPEC_COND_SMAX	; Used in aarch64-sve.md.
>> +    UNSPEC_COND_SMIN	; Used in aarch64-sve.md.
>>       UNSPEC_LASTA	; Used in aarch64-sve.md.
>>       UNSPEC_LASTB	; Used in aarch64-sve.md.
>>       UNSPEC_ASHIFT_WIDE  ; Used in aarch64-sve.md.
>> @@ -3094,7 +3096,9 @@
>>      UNSPEC_COND_FMINNM
>>      UNSPEC_COND_FMUL
>>      UNSPEC_COND_FMULX
>> -   UNSPEC_COND_FSUB])
>> +   UNSPEC_COND_FSUB
>> +   UNSPEC_COND_SMAX
>> +   UNSPEC_COND_SMIN])
>>   
>>   ;; Same as SVE_COND_FP_BINARY, but without codes that have a dedicated
>>   ;; <optab><mode>3 expander.
>> @@ -3105,7 +3109,9 @@
>>   					       UNSPEC_COND_FMINNM
>>   					       UNSPEC_COND_FMUL
>>   					       UNSPEC_COND_FMULX
>> -					       UNSPEC_COND_FSUB])
>> +					       UNSPEC_COND_FSUB
>> +					       UNSPEC_COND_SMAX
>> +					       UNSPEC_COND_SMIN])
>>   
>>   (define_int_iterator SVE_COND_FP_BINARY_INT [UNSPEC_COND_FSCALE])
>>   
>> @@ -3117,13 +3123,17 @@
>>   					    UNSPEC_COND_FMAXNM
>>   					    UNSPEC_COND_FMIN
>>   					    UNSPEC_COND_FMINNM
>> -					    UNSPEC_COND_FMUL])
>> +					    UNSPEC_COND_FMUL
>> +					    UNSPEC_COND_SMAX
>> +					    UNSPEC_COND_SMIN])
>>   
>>   (define_int_iterator SVE_COND_FP_BINARY_REG
>>     [(UNSPEC_COND_FAMAX "TARGET_SVE_FAMINMAX")
>>      (UNSPEC_COND_FAMIN "TARGET_SVE_FAMINMAX")
>>      UNSPEC_COND_FDIV
>> -   UNSPEC_COND_FMULX])
>> +   UNSPEC_COND_FMULX
>> +   UNSPEC_COND_SMAX
>> +   UNSPEC_COND_SMIN])
>>   
>>   (define_int_iterator SVE_COND_FCADD [UNSPEC_COND_FCADD90
>>   				     UNSPEC_COND_FCADD270])
>> @@ -3133,11 +3143,6 @@
>>   					 UNSPEC_COND_FMIN
>>   					 UNSPEC_COND_FMINNM])
>>   
>> -;; Floating-point max/min operations that correspond to optabs,
>> -;; as opposed to those that are internal to the port.
>> -(define_int_iterator SVE_COND_FP_MAXMIN_PUBLIC [UNSPEC_COND_FMAXNM
>> -						UNSPEC_COND_FMINNM])
>> -
>>   (define_int_iterator SVE_COND_FP_TERNARY [UNSPEC_COND_FMLA
>>   					  UNSPEC_COND_FMLS
>>   					  UNSPEC_COND_FNMLA
>> @@ -3715,9 +3720,9 @@
>>   			(UNSPEC_COND_FCVTZU "fixuns_trunc")
>>   			(UNSPEC_COND_FDIV "div")
>>   			(UNSPEC_COND_FMAX "fmax_nan")
>> -			(UNSPEC_COND_FMAXNM "smax")
>> +			(UNSPEC_COND_FMAXNM "fmax")
>>   			(UNSPEC_COND_FMIN "fmin_nan")
>> -			(UNSPEC_COND_FMINNM "smin")
>> +			(UNSPEC_COND_FMINNM "fmin")
>>   			(UNSPEC_COND_FMLA "fma")
>>   			(UNSPEC_COND_FMLS "fnma")
>>   			(UNSPEC_COND_FMUL "mul")
>> @@ -3737,16 +3742,16 @@
>>   			(UNSPEC_COND_FSQRT "sqrt")
>>   			(UNSPEC_COND_FSUB "sub")
>>   			(UNSPEC_COND_SCVTF "float")
>> -			(UNSPEC_COND_UCVTF "floatuns")])
>> +			(UNSPEC_COND_UCVTF "floatuns")
>> +			(UNSPEC_COND_SMAX "smax")
>> +			(UNSPEC_COND_SMIN "smin")])
> 
> It would be good to keep the entries sorted alphabetically.
> 
> OK for trunk with that change; no need for another review.
> 
> I think the can go in now, independently of the rest of the series
> (provided it passes individual testing of course!)
> 
> Thanks for doing this.
> 
> Richard

Thanks. I have commited this patch separately after fixing the sorting 
and regression testing it for aarch64-unknown-linux-gnu.

I will post a new version of patch series without this commit soon.

Thanks,
Saurabh
> 
>>   
>>   (define_int_attr fmaxmin [(UNSPEC_FMAX "fmax_nan")
>>   			  (UNSPEC_FMAXNM "fmax")
>>   			  (UNSPEC_FMAXNMV "fmax")
>>   			  (UNSPEC_FMIN "fmin_nan")
>>   			  (UNSPEC_FMINNM "fmin")
>> -			  (UNSPEC_FMINNMV "fmin")
>> -			  (UNSPEC_COND_FMAXNM "fmax")
>> -			  (UNSPEC_COND_FMINNM "fmin")])
>> +			  (UNSPEC_FMINNMV "fmin")])
>>   
>>   (define_int_attr  maxmin_uns_op [(UNSPEC_UMAXV "umax")
>>   				 (UNSPEC_UMINV "umin")
>> @@ -4263,7 +4268,9 @@
>>   			    (UNSPEC_COND_FRINTZ "frintz")
>>   			    (UNSPEC_COND_FSCALE "fscale")
>>   			    (UNSPEC_COND_FSQRT "fsqrt")
>> -			    (UNSPEC_COND_FSUB "fsub")])
>> +			    (UNSPEC_COND_FSUB "fsub")
>> +			    (UNSPEC_COND_SMAX "fmaxnm")
>> +			    (UNSPEC_COND_SMIN "fminnm")])
>>   
>>   (define_int_attr sve_fp_op_rev [(UNSPEC_COND_FADD "fadd")
>>   				(UNSPEC_COND_FAMAX "famax")
>> @@ -4275,7 +4282,9 @@
>>   				(UNSPEC_COND_FMINNM "fminnm")
>>   				(UNSPEC_COND_FMUL "fmul")
>>   				(UNSPEC_COND_FMULX "fmulx")
>> -				(UNSPEC_COND_FSUB "fsubr")])
>> +				(UNSPEC_COND_FSUB "fsubr")
>> +				(UNSPEC_COND_SMAX "fmaxnm")
>> +				(UNSPEC_COND_SMIN "fminnm")])
>>   
>>   (define_int_attr sme_int_op [(UNSPEC_SME_ADD_WRITE "add")
>>   			     (UNSPEC_SME_SUB_WRITE "sub")])
>> @@ -4413,7 +4422,9 @@
>>      (UNSPEC_COND_FMINNM "register_operand")
>>      (UNSPEC_COND_FMUL "register_operand")
>>      (UNSPEC_COND_FMULX "register_operand")
>> -   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")])
>> +   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")
>> +   (UNSPEC_COND_SMAX "register_operand")
>> +   (UNSPEC_COND_SMIN "register_operand")])
>>   
>>   ;; The predicate to use for the second input operand in a floating-point
>>   ;; <optab><mode>3 pattern.
>> @@ -4428,7 +4439,9 @@
>>      (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_operand")
>>      (UNSPEC_COND_FMUL "aarch64_sve_float_mul_operand")
>>      (UNSPEC_COND_FMULX "register_operand")
>> -   (UNSPEC_COND_FSUB "register_operand")])
>> +   (UNSPEC_COND_FSUB "register_operand")
>> +   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_operand")
>> +   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_operand")])
>>   
>>   ;; Likewise for immediates only.
>>   (define_int_attr sve_pred_fp_rhs2_immediate
>> @@ -4436,7 +4449,9 @@
>>      (UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_immediate")
>>      (UNSPEC_COND_FMIN "aarch64_sve_float_maxmin_immediate")
>>      (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_immediate")
>> -   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")])
>> +   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")
>> +   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_immediate")
>> +   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_immediate")])
>>   
>>   ;; The maximum number of element bits that an instruction can handle.
>>   (define_int_attr max_elem_bits [(UNSPEC_UADDV "64") (UNSPEC_SADDV "32")
  

Patch

diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index bfa28849adf..989ba9546d7 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -6600,39 +6600,6 @@ 
 ;; - FMINNM
 ;; -------------------------------------------------------------------------
 
-;; Unpredicated fmax/fmin (the libm functions).  The optabs for the
-;; smax/smin rtx codes are handled in the generic section above.
-(define_expand "<fmaxmin><mode>3"
-  [(set (match_operand:SVE_FULL_F 0 "register_operand")
-	(unspec:SVE_FULL_F
-	  [(match_dup 3)
-	   (const_int SVE_RELAXED_GP)
-	   (match_operand:SVE_FULL_F 1 "register_operand")
-	   (match_operand:SVE_FULL_F 2 "aarch64_sve_float_maxmin_operand")]
-	  SVE_COND_FP_MAXMIN_PUBLIC))]
-  "TARGET_SVE"
-  {
-    operands[3] = aarch64_ptrue_reg (<VPRED>mode);
-  }
-)
-
-;; Predicated fmax/fmin (the libm functions).  The optabs for the
-;; smax/smin rtx codes are handled in the generic section above.
-(define_expand "cond_<fmaxmin><mode>"
-  [(set (match_operand:SVE_FULL_F 0 "register_operand")
-	(unspec:SVE_FULL_F
-	  [(match_operand:<VPRED> 1 "register_operand")
-	   (unspec:SVE_FULL_F
-	     [(match_dup 1)
-	      (const_int SVE_RELAXED_GP)
-	      (match_operand:SVE_FULL_F 2 "register_operand")
-	      (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand")]
-	     SVE_COND_FP_MAXMIN_PUBLIC)
-	   (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
-	  UNSPEC_SEL))]
-  "TARGET_SVE"
-)
-
 ;; Predicated floating-point maximum/minimum.
 (define_insn "@aarch64_pred_<optab><mode>"
   [(set (match_operand:SVE_FULL_F 0 "register_operand")
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index cf9ee2639a9..d3a457fc6d9 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -884,6 +884,8 @@ 
     UNSPEC_COND_FSUB	; Used in aarch64-sve.md.
     UNSPEC_COND_SCVTF	; Used in aarch64-sve.md.
     UNSPEC_COND_UCVTF	; Used in aarch64-sve.md.
+    UNSPEC_COND_SMAX	; Used in aarch64-sve.md.
+    UNSPEC_COND_SMIN	; Used in aarch64-sve.md.
     UNSPEC_LASTA	; Used in aarch64-sve.md.
     UNSPEC_LASTB	; Used in aarch64-sve.md.
     UNSPEC_ASHIFT_WIDE  ; Used in aarch64-sve.md.
@@ -3094,7 +3096,9 @@ 
    UNSPEC_COND_FMINNM
    UNSPEC_COND_FMUL
    UNSPEC_COND_FMULX
-   UNSPEC_COND_FSUB])
+   UNSPEC_COND_FSUB
+   UNSPEC_COND_SMAX
+   UNSPEC_COND_SMIN])
 
 ;; Same as SVE_COND_FP_BINARY, but without codes that have a dedicated
 ;; <optab><mode>3 expander.
@@ -3105,7 +3109,9 @@ 
 					       UNSPEC_COND_FMINNM
 					       UNSPEC_COND_FMUL
 					       UNSPEC_COND_FMULX
-					       UNSPEC_COND_FSUB])
+					       UNSPEC_COND_FSUB
+					       UNSPEC_COND_SMAX
+					       UNSPEC_COND_SMIN])
 
 (define_int_iterator SVE_COND_FP_BINARY_INT [UNSPEC_COND_FSCALE])
 
@@ -3117,13 +3123,17 @@ 
 					    UNSPEC_COND_FMAXNM
 					    UNSPEC_COND_FMIN
 					    UNSPEC_COND_FMINNM
-					    UNSPEC_COND_FMUL])
+					    UNSPEC_COND_FMUL
+					    UNSPEC_COND_SMAX
+					    UNSPEC_COND_SMIN])
 
 (define_int_iterator SVE_COND_FP_BINARY_REG
   [(UNSPEC_COND_FAMAX "TARGET_SVE_FAMINMAX")
    (UNSPEC_COND_FAMIN "TARGET_SVE_FAMINMAX")
    UNSPEC_COND_FDIV
-   UNSPEC_COND_FMULX])
+   UNSPEC_COND_FMULX
+   UNSPEC_COND_SMAX
+   UNSPEC_COND_SMIN])
 
 (define_int_iterator SVE_COND_FCADD [UNSPEC_COND_FCADD90
 				     UNSPEC_COND_FCADD270])
@@ -3133,11 +3143,6 @@ 
 					 UNSPEC_COND_FMIN
 					 UNSPEC_COND_FMINNM])
 
-;; Floating-point max/min operations that correspond to optabs,
-;; as opposed to those that are internal to the port.
-(define_int_iterator SVE_COND_FP_MAXMIN_PUBLIC [UNSPEC_COND_FMAXNM
-						UNSPEC_COND_FMINNM])
-
 (define_int_iterator SVE_COND_FP_TERNARY [UNSPEC_COND_FMLA
 					  UNSPEC_COND_FMLS
 					  UNSPEC_COND_FNMLA
@@ -3715,9 +3720,9 @@ 
 			(UNSPEC_COND_FCVTZU "fixuns_trunc")
 			(UNSPEC_COND_FDIV "div")
 			(UNSPEC_COND_FMAX "fmax_nan")
-			(UNSPEC_COND_FMAXNM "smax")
+			(UNSPEC_COND_FMAXNM "fmax")
 			(UNSPEC_COND_FMIN "fmin_nan")
-			(UNSPEC_COND_FMINNM "smin")
+			(UNSPEC_COND_FMINNM "fmin")
 			(UNSPEC_COND_FMLA "fma")
 			(UNSPEC_COND_FMLS "fnma")
 			(UNSPEC_COND_FMUL "mul")
@@ -3737,16 +3742,16 @@ 
 			(UNSPEC_COND_FSQRT "sqrt")
 			(UNSPEC_COND_FSUB "sub")
 			(UNSPEC_COND_SCVTF "float")
-			(UNSPEC_COND_UCVTF "floatuns")])
+			(UNSPEC_COND_UCVTF "floatuns")
+			(UNSPEC_COND_SMAX "smax")
+			(UNSPEC_COND_SMIN "smin")])
 
 (define_int_attr fmaxmin [(UNSPEC_FMAX "fmax_nan")
 			  (UNSPEC_FMAXNM "fmax")
 			  (UNSPEC_FMAXNMV "fmax")
 			  (UNSPEC_FMIN "fmin_nan")
 			  (UNSPEC_FMINNM "fmin")
-			  (UNSPEC_FMINNMV "fmin")
-			  (UNSPEC_COND_FMAXNM "fmax")
-			  (UNSPEC_COND_FMINNM "fmin")])
+			  (UNSPEC_FMINNMV "fmin")])
 
 (define_int_attr  maxmin_uns_op [(UNSPEC_UMAXV "umax")
 				 (UNSPEC_UMINV "umin")
@@ -4263,7 +4268,9 @@ 
 			    (UNSPEC_COND_FRINTZ "frintz")
 			    (UNSPEC_COND_FSCALE "fscale")
 			    (UNSPEC_COND_FSQRT "fsqrt")
-			    (UNSPEC_COND_FSUB "fsub")])
+			    (UNSPEC_COND_FSUB "fsub")
+			    (UNSPEC_COND_SMAX "fmaxnm")
+			    (UNSPEC_COND_SMIN "fminnm")])
 
 (define_int_attr sve_fp_op_rev [(UNSPEC_COND_FADD "fadd")
 				(UNSPEC_COND_FAMAX "famax")
@@ -4275,7 +4282,9 @@ 
 				(UNSPEC_COND_FMINNM "fminnm")
 				(UNSPEC_COND_FMUL "fmul")
 				(UNSPEC_COND_FMULX "fmulx")
-				(UNSPEC_COND_FSUB "fsubr")])
+				(UNSPEC_COND_FSUB "fsubr")
+				(UNSPEC_COND_SMAX "fmaxnm")
+				(UNSPEC_COND_SMIN "fminnm")])
 
 (define_int_attr sme_int_op [(UNSPEC_SME_ADD_WRITE "add")
 			     (UNSPEC_SME_SUB_WRITE "sub")])
@@ -4413,7 +4422,9 @@ 
    (UNSPEC_COND_FMINNM "register_operand")
    (UNSPEC_COND_FMUL "register_operand")
    (UNSPEC_COND_FMULX "register_operand")
-   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")])
+   (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")
+   (UNSPEC_COND_SMAX "register_operand")
+   (UNSPEC_COND_SMIN "register_operand")])
 
 ;; The predicate to use for the second input operand in a floating-point
 ;; <optab><mode>3 pattern.
@@ -4428,7 +4439,9 @@ 
    (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_operand")
    (UNSPEC_COND_FMUL "aarch64_sve_float_mul_operand")
    (UNSPEC_COND_FMULX "register_operand")
-   (UNSPEC_COND_FSUB "register_operand")])
+   (UNSPEC_COND_FSUB "register_operand")
+   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_operand")
+   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_operand")])
 
 ;; Likewise for immediates only.
 (define_int_attr sve_pred_fp_rhs2_immediate
@@ -4436,7 +4449,9 @@ 
    (UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_immediate")
    (UNSPEC_COND_FMIN "aarch64_sve_float_maxmin_immediate")
    (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_immediate")
-   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")])
+   (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")
+   (UNSPEC_COND_SMAX "aarch64_sve_float_maxmin_immediate")
+   (UNSPEC_COND_SMIN "aarch64_sve_float_maxmin_immediate")])
 
 ;; The maximum number of element bits that an instruction can handle.
 (define_int_attr max_elem_bits [(UNSPEC_UADDV "64") (UNSPEC_SADDV "32")