public inbox for
 help / color / mirror / Atom feed
From: Segher Boessenkool <>
To: Roger Sayle <>
Subject: Re: [PATCH] Add new target hook: simplify_modecc_const.
Date: Tue, 26 Jul 2022 12:44:51 -0500	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <00fa01d8a0e9$0efdfc60$2cf9f520$>


On Tue, Jul 26, 2022 at 01:13:02PM +0100, Roger Sayle wrote:
> This patch is a major revision of the patch I originally proposed here:
> The primary motivation of this patch is to avoid incorrect optimization
> of MODE_CC comparisons in simplify_const_relational_operation when/if a
> backend represents the (known) contents of a MODE_CC register using a
> CONST_INT.  In such cases, the RTL optimizers don't know the semantics
> of this integer value, so shouldn't change anything (i.e. should return
> NULL_RTX from simplify_const_relational_operation).

This is invalid RTL.  What would  (set (reg:CC) (const_int 0))  mean,
for example?  If this was valid it would make most existing code using
CC modes do essentially random things :-(

The documentation (in tm.texi, "Condition Code") says
  Alternatively, you can use @code{BImode} if the comparison operator is
  specified already in the compare instruction.  In this case, you are not
  interested in most macros in this section.

> The worked example provided with this patch is to allow the i386 backend
> to explicitly model the carry flag (MODE_CCC) using 1 to indicate that
> the carry flag is set, and 0 to indicate the carry flag is clear.  This
> allows the instructions stc (set carry flag), clc (clear carry flag) and
> cmc (complement carry flag) to be represented in RTL.

Hrm, I wonder how other targets do this.

On Power we have a separate hard register for the carry flag of course
(it is a separate bit in the hardware as well, XER[CA]).

On Arm there is arm_carry_operation (as well as arm_borrow_operation).

Aarch64 directly uses
(define_expand "add<mode>3_carryin"
  [(set (match_operand:GPI 0 "register_operand")
            (ltu:GPI (reg:CC_C CC_REGNUM) (const_int 0))
            (match_operand:GPI 1 "aarch64_reg_or_zero"))
          (match_operand:GPI 2 "aarch64_reg_or_zero")))]
(CC_Cmode means only the C bit is validly set).

s390 does similar.  sparc does similar.

> However an even better example would be the rs6000 backend, where this
> patch/target hook would allow improved modelling of the condition register
> CR.  The powerpc's comparison instructions set fields/bits in the CR
> register [where bit 0 indicates less than, bit 1 greater than, bit 2
> equal to and bit3 overflow]

There are eight condition register fields which can be used
interchangeably (some insns only write to CR0, CR1, or CR6).  The
meaning of the four bits in a field depends on the instruction that set
them.  For integer comparisons bit 3 does not mean anything to do with a
comparison: instead, it is a copy of the XER[SO] bit ("summary
overflow").  The rs6000 backend does not currently model this (we do not
model the overflow instructions at all!)

> analogous to x86's flags register [containing
> bits for carry, zero, overflow, parity etc.].  These fields can be
> manipulated directly using crset (aka creqv) and crclr (aka crxor)
> instructions

crand, crnand, cror, crxor, crnor, creqv, crandc, crorc insns, or the
extended mnemonics crmove, crclr, crnot, crset, yes.  All these for
setting single bits; there also is mcrf to copy all four bits of a CR
field to another.

> and even transferred from general purpose registers using
> mtcr.  However, without a patch like this, it's impossible to safely
> model/represent these instructions in

And yet we do.  See for example @cceq_rev_compare_<mode> which
implements crnot.

> +  /* Handle MODE_CC comparisons that have been simplified to
> +     constants.  */
> +  if (GET_MODE_CLASS (mode) == MODE_CC
> +      && op1 == const0_rtx
> +      && CONST_INT_P (op0))
> +    return targetm.simplify_modecc_const (mode, (int)code, op0);

Comparing two integer constants is invalid RTL *in all contexts*.  The
items compared do not have a mode!  From rtl.texi:
  A @code{compare} specifying two @code{VOIDmode} constants is not valid
  since there is no way to know in what mode the comparison is to be
  performed; the comparison must either be folded during the compilation
  or the first operand must be loaded into a register while its mode is
  still known.


  reply	other threads:[~2022-07-26 17:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-07 21:08 [PATCH] Be careful with MODE_CC in simplify_const_relational_operation Roger Sayle
2022-07-07 22:38 ` Segher Boessenkool
2022-07-26 12:13   ` [PATCH] Add new target hook: simplify_modecc_const Roger Sayle
2022-07-26 17:44     ` Segher Boessenkool [this message]
2022-07-26 21:04       ` Roger Sayle
2022-07-26 22:11         ` Segher Boessenkool
2022-07-27  7:51           ` Roger Sayle
2022-07-27 18:37             ` Segher Boessenkool
2022-07-28 12:39         ` Richard Sandiford
2022-10-10 15:50           ` H.J. Lu
2022-10-14 20:31             ` Jeff Law
2022-10-14 21:05               ` H.J. Lu
2022-10-14 20:26       ` Jeff Law

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:

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

  git send-email \ \ \ \ \

* 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).