https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123027

Hongtao Liu <liuhongt at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |liuhongt at gcc dot gnu.org

--- Comment #3 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #2)
> For "reasons" RTL expansion differs here, using a jumpy sequence w/o
> -ffinite-math-only, but an if-converted variant if not.  IIRC this is the x86
> expander which likely fails to recognize equal compare args and thus
> min/max.  IIRC there's another PR for this already.
> 
> TER should come to the rescue here.  The x86 backend gets
> 
> (ge (reg/v:SF 100 [ a ])
>     (reg/v:SF 101 [ b ])) ? (reg/v:SF 101 [ b ]) : (reg/v:SF 100 [ a ])
> 
> then decides to turn this into (le ...) ? : instead of inverting the compare
> (which should be valid with -ffinite-math-only) and ix86_expand_sse_fp_minmax
> does not recognize the LE min():
> 
> static bool
> ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
>                            rtx cmp_op1, rtx if_true, rtx if_false)
> {
>   machine_mode mode;
>   bool is_min;
>   rtx tmp;
> 
>   if (code == LT)
>     ;
>   else if (code == UNGE)
>     std::swap (if_true, if_false);
>   else
>     return false;
> 
> this could add 
> 
>   else if (code == LE && !HONOR_NANS (mode))
>     ;
> 
> I'll note that we end up with GE only because of prepare_cmp_insn not
> accepting LT for cbranch but GE is and what reversed_comparison_code_parts
> does depends on HONOR_NANS.
> 
> The following works for me:
> 
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index fd9bcaa8541..da96454a73a 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -4163,7 +4163,8 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code
> code, rtx cmp_op0,
>    bool is_min;
>    rtx tmp;
>  
> -  if (code == LT)
> +  mode = GET_MODE (dest);
> +  if (code == LT || (code == LE && !HONOR_NANS (mode)))
>      ;

Yes, please also add UNGT if !HONOR_NANS (mode)


else if (code == UNGE || (code == UNGT && !HONOR_NANS (mode)))
  std::swap (if_true, if_false);

Reply via email to