public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/114766] New: ^ constraint modifier unexpectedly affects register class selection.
@ 2024-04-18 12:01 tnfchris at gcc dot gnu.org
  2024-04-19 22:04 ` [Bug rtl-optimization/114766] " vmakarov at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: tnfchris at gcc dot gnu.org @ 2024-04-18 12:01 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114766
           Summary: ^ constraint modifier unexpectedly affects register
                    class selection.
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tnfchris at gcc dot gnu.org
                CC: vmakarov at gcc dot gnu.org
  Target Milestone: ---

The documentation for ^ states:

"This constraint is analogous to ‘?’ but it disparages slightly the alternative
only if the operand with the ‘^’ needs a reload."

From this we gathered that there's only a slight costs when the given operand
required a reload.

In PR114741 we had a regression when using this modifier because it seems to
unexpectedly also change register class selection during coloring.

The pattern was:

(define_insn "<optab><mode>3"
  [(set (match_operand:GPI 0 "register_operand")
        (LOGICAL:GPI (match_operand:GPI 1 "register_operand")
                     (match_operand:GPI 2 "aarch64_logical_operand")))]
  ""
  {@ [ cons: =0 , 1  , 2        ; attrs: type , arch  ]
     [ r        , %r , r        ; logic_reg   , *     ] <logical>\t%<w>0,
%<w>1, %<w>2
     [ rk       , ^r , <lconst> ; logic_imm   , *     ] <logical>\t%<w>0,
%<w>1, %2
     [ w        , 0  , <lconst> ; *           , sve   ] <logical>\t%Z0.<s>,
%Z0.<s>, #%2
     [ w        , w  , w        ; neon_logic  , simd  ] <logical>\t%0.<Vbtype>,
%1.<Vbtype>, %2.<Vbtype>
  }
)

where we wanted to prefer the r->r alternative unless a reload is needed in
which case we preferred the w->w.

But in the simple example of:

    void foo(unsigned v, unsigned *p)
    {
        *p = v & 1;
    }

where the operation can be done on both r->r and w->w, but w->w needs a mov it
would not pick r->r.

This is because during sched1 the penalty applied to the ^ alternative made it
no longer consider GP regs:

        r106: preferred FP_REGS, alternative NO_REGS, allocno FP_REGS
    ;;        3--> b  0: i   9 r106=r105&0x1
        :cortex_a53_slot_any:GENERAL_REGS+0(-1)FP_REGS+1(1)PR_LO_REGS+0(0)
                             PR_HI_REGS+0(0):model 4

The penalty here seems incorrect, and removing it seems to get the constraint
to work properly.
So the question is, is it a bug, or are we using it incorrectly? or a
documentation bug?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug rtl-optimization/114766] ^ constraint modifier unexpectedly affects register class selection.
  2024-04-18 12:01 [Bug rtl-optimization/114766] New: ^ constraint modifier unexpectedly affects register class selection tnfchris at gcc dot gnu.org
@ 2024-04-19 22:04 ` vmakarov at gcc dot gnu.org
  2024-04-20 15:24 ` tnfchris at gcc dot gnu.org
  2024-04-24 12:38 ` vmakarov at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: vmakarov at gcc dot gnu.org @ 2024-04-19 22:04 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to Tamar Christina from comment #0)
> The documentation for ^ states:
> 
> "This constraint is analogous to ‘?’ but it disparages slightly the
> alternative only if the operand with the ‘^’ needs a reload."
> 
> 
> The penalty here seems incorrect, and removing it seems to get the
> constraint to work properly.
> So the question is, is it a bug, or are we using it incorrectly? or a
> documentation bug?

The current behavior of '^' is how it was originally planned. 

With this point of view I would say that it is a documentation ambiguity. 
documentation of '?' also does not clearly say about its affect on the cost
calculation and as a consequence on choosing register class.

On the other hand, I don't know what is really needed.  If you need what you
expected, please try the following patch:

diff --git a/gcc/ira-costs.cc b/gcc/ira-costs.cc
index c86c5a16563..04d2f21b023 100644
--- a/gcc/ira-costs.cc
+++ b/gcc/ira-costs.cc
@@ -771,10 +771,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                  c = *++p;
                  break;

-               case '^':
-                 alt_cost += 2;
-                 break;
-
                case '?':
                  alt_cost += 2;
                  break;

If it works for you, we could try to use the patch (although it needs some
investigation how other targets uses the hint).  In any case, the documentation
should be modified or made more clear depending on applying or not applying the
patch.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug rtl-optimization/114766] ^ constraint modifier unexpectedly affects register class selection.
  2024-04-18 12:01 [Bug rtl-optimization/114766] New: ^ constraint modifier unexpectedly affects register class selection tnfchris at gcc dot gnu.org
  2024-04-19 22:04 ` [Bug rtl-optimization/114766] " vmakarov at gcc dot gnu.org
@ 2024-04-20 15:24 ` tnfchris at gcc dot gnu.org
  2024-04-24 12:38 ` vmakarov at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: tnfchris at gcc dot gnu.org @ 2024-04-20 15:24 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
(In reply to Vladimir Makarov from comment #1)
> (In reply to Tamar Christina from comment #0)
> > The documentation for ^ states:
>
> If it works for you, we could try to use the patch (although it needs some
> investigation how other targets uses the hint).  In any case, the
> documentation should be modified or made more clear depending on applying or
> not applying the patch.

Yeah, using the patch gives us the behavior we expected, we added a workaround
for now so we can investigate what other targets do in GCC 15.

But while looking at this we also got some unexpected behavior with using ?

For instance we have the pattern:

;; Equal width integer to fp conversion.
(define_insn "<optab><fcvt_target><GPF:mode>2"
  [(set (match_operand:GPF 0 "register_operand")
        (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand")))]
  "TARGET_FLOAT"
  {@ [ cons: =0 , 1  ; attrs: type             , arch  ]
     [ w        , w  ; neon_int_to_fp_<Vetype> , simd  ]
<su_optab>cvtf\t%<GPF:s>0, %<s>1
     [ w        , ?r ; f_cvti2f                , fp    ]
<su_optab>cvtf\t%<GPF:s>0, %<w1>1
  })

for modeling floating point conversions. We had expected ? to make the
alternative more expensive, but still possible.  However again during IRA the
entire register class is blocked:

    r103: preferred FP_REGS, alternative NO_REGS, allocno FP_REGS

I would have expected that the additional penalty should never make an
alternative impossible.
We thought maybe the move costs were an issue, but we tried with various big
and small numbers but it looks like the move costs have little to no effect. 
Since the original value in this case was in r:

      Choosing alt 0 in insn 7:  (0) =rk  (1) %rk  (2) I {*adddi3_aarch64}

I would have expected the cost for FP_REGS not to be 0, as there's a register
file move involved:

  r103 costs: W8_W11_REGS:2000 W12_W15_REGS:2000 TAILCALL_ADDR_REGS:2000
STUB_REGS:2000 GENERAL_REGS:2000 FP_LO8_REGS:0 FP_LO_REGS:0 FP_REGS:0
POINTER_AND_FP_REGS:7000 MEM:9000

In this particular pattern the ? isn't needed so we're removing it, but the
behavior is still unexpected.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug rtl-optimization/114766] ^ constraint modifier unexpectedly affects register class selection.
  2024-04-18 12:01 [Bug rtl-optimization/114766] New: ^ constraint modifier unexpectedly affects register class selection tnfchris at gcc dot gnu.org
  2024-04-19 22:04 ` [Bug rtl-optimization/114766] " vmakarov at gcc dot gnu.org
  2024-04-20 15:24 ` tnfchris at gcc dot gnu.org
@ 2024-04-24 12:38 ` vmakarov at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: vmakarov at gcc dot gnu.org @ 2024-04-24 12:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to Tamar Christina from comment #2)
> (In reply to Vladimir Makarov from comment #1)
> > (In reply to Tamar Christina from comment #0)
> > > The documentation for ^ states:
> >
> > If it works for you, we could try to use the patch (although it needs some
> > investigation how other targets uses the hint).  In any case, the
> > documentation should be modified or made more clear depending on applying or
> > not applying the patch.
> 
> Yeah, using the patch gives us the behavior we expected, we added a
> workaround for now so we can investigate what other targets do in GCC 15.
> 
> But while looking at this we also got some unexpected behavior with using ?
> 

> 
>   r103 costs: W8_W11_REGS:2000 W12_W15_REGS:2000 TAILCALL_ADDR_REGS:2000
> STUB_REGS:2000 GENERAL_REGS:2000 FP_LO8_REGS:0 FP_LO_REGS:0 FP_REGS:0
> POINTER_AND_FP_REGS:7000 MEM:9000
> 
> In this particular pattern the ? isn't needed so we're removing it, but the
> behavior is still unexpected.

'?' is a very old hint (unlike ^ and @).  It is used by all targets for many
years.  IRA cost calculation uses exactly the same algorithm as it was in now
non-existing regclass.c file.  Changing code related to processing '?' would
have very unpredictable consequences for many targets.  After many years
working on RA, I am still surprised how fragile code calculating costs and reg
classes and how insignificant changes can result in a cascade of GCC test
failures.

There are many factors which still can result in zero cost code even when '?'
is used.  You can try to use more one '?' and see what happens.  If the cost is
still zero, I could look what is going on in the cost calculation.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-04-24 12:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-18 12:01 [Bug rtl-optimization/114766] New: ^ constraint modifier unexpectedly affects register class selection tnfchris at gcc dot gnu.org
2024-04-19 22:04 ` [Bug rtl-optimization/114766] " vmakarov at gcc dot gnu.org
2024-04-20 15:24 ` tnfchris at gcc dot gnu.org
2024-04-24 12:38 ` vmakarov at gcc dot gnu.org

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