public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/110852] [14 Regression] ICE: in get_predictor_value, at predict.cc:2695 with -O -fno-tree-fre and __builtin_expect() since r14-2219-geab57b825bcc35
Date: Thu, 04 Jan 2024 14:42:21 +0000	[thread overview]
Message-ID: <bug-110852-4-xBIwebSDFy@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-110852-4@http.gcc.gnu.org/bugzilla/>

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, what happens here is that expr_expected_value_1 is called on a binary
operation (GT_EXPR in this case, but that is irrelevant) with 2 SSA_NAME
operands, where one SSA_NAME is set to an INTEGER_CST (not propagated because
of -fno-tree-fre) and the other one result of __builtin_expect.  For the
INTEGER_CST, we get *predictor PRED_UNCONDITIONAL with *probability -1, for
__builtin_expect predictor2 PRED_BUILTIN_EXPECT with probability2 9000.
Next we try to merge the predictors.  As at least one of them has probability
!= -1,
          /* Combine binary predictions.  */
          if (*probability != -1 || probability2 != -1)
            {
              HOST_WIDE_INT p1 = get_predictor_value (*predictor,
*probability);
              HOST_WIDE_INT p2 = get_predictor_value (predictor2,
probability2);
              *probability = RDIV (p1 * p2, REG_BR_PROB_BASE);
            }
is done to combine the value and we get 9000 out of that in this case,
but then pick the predictor with the smaller value which is PRED_UNCONDITIONAL
in:
          if (predictor2 < *predictor)
            *predictor = predictor2;
which causes the later ICE, because only PRED_BUILTIN_EXPECT* should have
probability
other than -1.
Now, given the combination code I wrote:
--- gcc/predict.cc.jj   2024-01-03 11:51:32.000000000 +0100
+++ gcc/predict.cc      2024-01-04 14:04:40.996639979 +0100
@@ -2626,10 +2626,20 @@ expr_expected_value_1 (tree type, tree o
            {
              HOST_WIDE_INT p1 = get_predictor_value (*predictor,
*probability);
              HOST_WIDE_INT p2 = get_predictor_value (predictor2,
probability2);
+             if (*probability != -1 && probability2 != -1)
+               {
+                 /* If both predictors are PRED_BUILTIN_EXPECT*, pick the
+                    smaller one from them.  */
+                 if (predictor2 < *predictor)
+                   *predictor = predictor2;
+               }
+             /* Otherwise, if at least one predictor is PRED_BUILTIN_EXPECT*,
+                use that one for the combination.  */
+             else if (probability2 != -1)
+               *predictor = predictor2;
              *probability = RDIV (p1 * p2, REG_BR_PROB_BASE);
            }
-
-         if (predictor2 < *predictor)
+         else if (predictor2 < *predictor)
            *predictor = predictor2;

          return res;
which fixes the ICE by preferring PRED_BUILTIN_EXPECT* over others.
At least in this case when one operand is a constant and another one is
__builtin_expect* result that seems like the right choice to me, the fact that
one operand is constant doesn't mean the outcome of the binary operation is
unconditionally constant when the other operand is __builtin_expect* based.
But reading the
"This incorrectly takes precedence over more reliable heuristics predicting
that call
to cold noreturn is likely not going to happen."
in the description makes me wonder whether that is what we want always (though,
I must say I don't understand the cold noreturn argument because
PRED_COLD_FUNCTION is never returned from expr_expected_value_1.  But
PRED_COMPARE_AND_SWAP (in between
PRED_BUILTIN_EXPECT_WITH_PROBABILITY and PRED_BUILTIN_EXPECT), whatever the
fortran IFN_BUILTIN_EXPECTs have (all above PRED_BUILTIN_EXPECT*),
PRED_MALLOC_NONNULL (above PRED_BUILTIN_EXPECT*) can appear.
So, shall we prefer PRED_BUILTIN_EXPECT* over PRED_UNCONDITIONAL for the binary
operations, but prefer PRED_COMPARE_AND_SWAP over PRED_BUILTIN_EXPECT (and then
set *probability to -1 obviously)?  The others don't matter because they have
higher value and so aren't picked up.

The reason this doesn't ICE with -fno-tree-fre is that if one of the binary
operands is already INTEGER_CST, it just uses the predictor from the other
operand (which is another argument in support of ignoring PRED_UNCONDITIONAL
operand vs. other predictors when merging).

Oh, another thing is that before the patch there were two spots that merged the
predictors, one for the binary operands (which previously picked the weaker
predictor and now picks stronger predictor), but also in the PHI handling
(which still picks weaker predictor); shouldn't that be changed to match,
including the != -1 handling?

  parent reply	other threads:[~2024-01-04 14:42 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-30  9:02 [Bug tree-optimization/110852] New: [14 Regression] ICE: in get_predictor_value, at predict.cc:2695 with -O -fno-tree-fre and __builtin_expect() zsojka at seznam dot cz
2023-07-30 20:04 ` [Bug tree-optimization/110852] " pinskia at gcc dot gnu.org
2023-08-01 13:57 ` hubicka at gcc dot gnu.org
2023-10-17 12:23 ` rguenth at gcc dot gnu.org
2023-10-17 12:23 ` rguenth at gcc dot gnu.org
2023-10-22 23:40 ` [Bug tree-optimization/110852] [14 Regression] ICE: in get_predictor_value, at predict.cc:2695 with -O -fno-tree-fre and __builtin_expect() since r14-2219-geab57b825bcc35 sjames at gcc dot gnu.org
2023-11-13  3:27 ` pinskia at gcc dot gnu.org
2024-01-04 14:42 ` jakub at gcc dot gnu.org [this message]
2024-01-04 15:24 ` hubicka at ucw dot cz
2024-01-04 15:30 ` jakub at gcc dot gnu.org
2024-01-04 15:59 ` jakub at gcc dot gnu.org
2024-01-04 16:06 ` hubicka at ucw dot cz
2024-01-04 16:17 ` jakub at gcc dot gnu.org
2024-01-04 16:26 ` hubicka at ucw dot cz
2024-01-04 16:35 ` jakub at gcc dot gnu.org
2024-01-04 16:37 ` jakub at gcc dot gnu.org
2024-01-04 17:06 ` hubicka at ucw dot cz
2024-01-17 14:20 ` cvs-commit at gcc dot gnu.org
2024-01-17 14:22 ` hubicka at gcc dot gnu.org

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=bug-110852-4-xBIwebSDFy@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /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).