public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jeff Law <jeffreyalaw@gmail.com>
To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com
Subject: Re: [PATCH] ifcvt: Fix regression in aarch64/fcsel_1.c
Date: Sun, 12 Feb 2023 23:46:22 -0700	[thread overview]
Message-ID: <d3e80085-b334-d025-cd6d-ce79cb671ffc@gmail.com> (raw)
In-Reply-To: <mpt5ycjcdoo.fsf@arm.com>



On 2/3/23 02:15, Richard Sandiford via Gcc-patches wrote:
> aarch64/fcsel_1.c contains:
> 
> double
> f_2 (double a, double b, double c, double d)
> {
>    if (a > b)
>      return c;
>    else
>      return d;
> }
> 
> which started failing in the GCC 12 timeframe.  When it passed,
> the RTL had the form:
> 
> [A]
>    (set (reg ret) (reg c))
>    (set (pc) (if_then_else (gt ...) (label_ref ret) (pc)))
>      edge to ret, fallthru to else
> else:
>    (set (reg ret) (reg d))
>      fallthru to ret
> ret:
>    ...exit...
> 
> i.e. a branch around.  Now the RTL has form:
> 
> [B]
>    (set (reg ret) (reg d))
>    (set (pc) (if_then_else (gt ...) (label_ref then) (pc)))
>      edge to then, fallthru to ret
> ret:
>    ...exit...
> 
> then:
>    (set (reg ret) (reg c))
>      edge to ret
> 
> i.e. a branch out.
> 
> Both are valid, of course, and there's no easy way to predict
> which we'll get.  But ifcvt canonicalises its representation on:
> 
>    if (cond) goto fallthru else goto non-fallthru
> 
> That is, it canoncalises on the branch-around case for half-diamonds.
> It therefore wants to invert the comparison in [B] to get:
> 
>    if (...) goto ret else goto then
> 
> But that isn't possible for strict FP gt, so the optimisation fails.
> 
> Canonicalising on the branch-around case seems like the wrong choice for
> half diamonds.  The natural way of expressing a conditional branch is
> for the label_ref to be the "then" destination and pc to be the "else"
> destination.  And the natural choice of condition seems to be the one
> under which extra stuff *is* done, rather than the one under which extra
> stuff *isn't* done.  But that decision goes back at least 20 years and
> it doesn't seem like a good idea to change it in stage 4.
As I was parsing things up to the last sentence my first thought was no 
isn't the right time to fix this :-)


> 
> This patch instead allows the internal structure to store the
> condition in inverted form.  For simplicity it handles only
> conditional moves, which is the one case that is needed
> to fix the known regression.  (There are probably unknown
> regressions too, but still.)
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
> 
> Richard
> 
> 
> gcc/
> 	* ifcvt.h (noce_if_info::cond_inverted): New field.
> 	* ifcvt.cc (cond_move_convert_if_block): Swap the then and else
> 	values when cond_inverted is true.
> 	(noce_find_if_block): Allow the condition to be inverted when
> 	handling conditional moves.
> ---
>   gcc/ifcvt.cc | 31 +++++++++++++++++++------------
>   gcc/ifcvt.h  |  8 ++++++++
>   2 files changed, 27 insertions(+), 12 deletions(-)
> 
> diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
> index 008796838f7..63ef42b3c34 100644
> --- a/gcc/ifcvt.cc
> +++ b/gcc/ifcvt.cc
> @@ -4253,6 +4253,9 @@ cond_move_convert_if_block (struct noce_if_info *if_infop,
>   	    e = dest;
>   	}
>   
> +      if (if_infop->cond_inverted)
> +	std::swap (t, e);
> +
>         target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1,
>   				t, e);
>         if (!target)
> @@ -4405,7 +4408,6 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
>     basic_block then_bb, else_bb, join_bb;
>     bool then_else_reversed = false;
>     rtx_insn *jump;
> -  rtx cond;
>     rtx_insn *cond_earliest;
>     struct noce_if_info if_info;
>     bool speed_p = optimize_bb_for_speed_p (test_bb);
> @@ -4481,25 +4483,28 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
>     if (! onlyjump_p (jump))
>       return FALSE;
>   
> -  /* If this is not a standard conditional jump, we can't parse it.  */
> -  cond = noce_get_condition (jump, &cond_earliest, then_else_reversed);
> -  if (!cond)
> -    return FALSE;
> -
> -  /* We must be comparing objects whose modes imply the size.  */
> -  if (GET_MODE (XEXP (cond, 0)) == BLKmode)
> -    return FALSE;
> -
>     /* Initialize an IF_INFO struct to pass around.  */
>     memset (&if_info, 0, sizeof if_info);
>     if_info.test_bb = test_bb;
>     if_info.then_bb = then_bb;
>     if_info.else_bb = else_bb;
>     if_info.join_bb = join_bb;
> -  if_info.cond = cond;
> +  if_info.cond = noce_get_condition (jump, &cond_earliest,
> +				     then_else_reversed);;
Extraneous ';'.

OK with that nit fixed.

jeff

  reply	other threads:[~2023-02-13  6:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-03  9:15 Richard Sandiford
2023-02-13  6:46 ` Jeff Law [this message]
2023-02-13 10:41 ` [Ping] " Richard Sandiford
2023-02-13 10:46   ` Richard Sandiford

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d3e80085-b334-d025-cd6d-ce79cb671ffc@gmail.com \
    --to=jeffreyalaw@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.sandiford@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).