LCOV - code coverage report
Current view: top level - gcc - dojump.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 330 589 56.0 %
Date: 2020-04-04 11:58:09 Functions: 13 21 61.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Convert tree expression to rtl instructions, for GNU compiler.
       2                 :            :    Copyright (C) 1988-2020 Free Software Foundation, Inc.
       3                 :            : 
       4                 :            : This file is part of GCC.
       5                 :            : 
       6                 :            : GCC is free software; you can redistribute it and/or modify it under
       7                 :            : the terms of the GNU General Public License as published by the Free
       8                 :            : Software Foundation; either version 3, or (at your option) any later
       9                 :            : version.
      10                 :            : 
      11                 :            : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :            : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :            : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :            : for more details.
      15                 :            : 
      16                 :            : You should have received a copy of the GNU General Public License
      17                 :            : along with GCC; see the file COPYING3.  If not see
      18                 :            : <http://www.gnu.org/licenses/>.  */
      19                 :            : 
      20                 :            : #include "config.h"
      21                 :            : #include "system.h"
      22                 :            : #include "coretypes.h"
      23                 :            : #include "backend.h"
      24                 :            : #include "target.h"
      25                 :            : #include "rtl.h"
      26                 :            : #include "tree.h"
      27                 :            : #include "predict.h"
      28                 :            : #include "memmodel.h"
      29                 :            : #include "tm_p.h"
      30                 :            : #include "optabs.h"
      31                 :            : #include "emit-rtl.h"
      32                 :            : #include "fold-const.h"
      33                 :            : #include "stor-layout.h"
      34                 :            : /* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
      35                 :            : #include "dojump.h"
      36                 :            : #include "explow.h"
      37                 :            : #include "expr.h"
      38                 :            : #include "langhooks.h"
      39                 :            : 
      40                 :            : static bool prefer_and_bit_test (scalar_int_mode, int);
      41                 :            : static void do_jump (tree, rtx_code_label *, rtx_code_label *,
      42                 :            :                      profile_probability);
      43                 :            : static void do_jump_by_parts_greater (scalar_int_mode, tree, tree, int,
      44                 :            :                                       rtx_code_label *, rtx_code_label *,
      45                 :            :                                       profile_probability);
      46                 :            : static void do_jump_by_parts_equality (scalar_int_mode, tree, tree,
      47                 :            :                                        rtx_code_label *, rtx_code_label *,
      48                 :            :                                        profile_probability);
      49                 :            : static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code,
      50                 :            :                                  rtx_code_label *, rtx_code_label *,
      51                 :            :                                  profile_probability);
      52                 :            : 
      53                 :            : /* At the start of a function, record that we have no previously-pushed
      54                 :            :    arguments waiting to be popped.  */
      55                 :            : 
      56                 :            : void
      57                 :          0 : init_pending_stack_adjust (void)
      58                 :            : {
      59                 :          0 :   pending_stack_adjust = 0;
      60                 :          0 : }
      61                 :            : 
      62                 :            : /* Discard any pending stack adjustment.  This avoid relying on the
      63                 :            :    RTL optimizers to remove useless adjustments when we know the
      64                 :            :    stack pointer value is dead.  */
      65                 :            : void
      66                 :      26227 : discard_pending_stack_adjust (void)
      67                 :            : {
      68                 :      26227 :   stack_pointer_delta -= pending_stack_adjust;
      69                 :      26227 :   pending_stack_adjust = 0;
      70                 :      26227 : }
      71                 :            : 
      72                 :            : /* When exiting from function, if safe, clear out any pending stack adjust
      73                 :            :    so the adjustment won't get done.
      74                 :            : 
      75                 :            :    Note, if the current function calls alloca, then it must have a
      76                 :            :    frame pointer regardless of the value of flag_omit_frame_pointer.  */
      77                 :            : 
      78                 :            : void
      79                 :    1469920 : clear_pending_stack_adjust (void)
      80                 :            : {
      81                 :    1469920 :   if (optimize > 0
      82                 :    1090790 :       && (! flag_omit_frame_pointer || cfun->calls_alloca)
      83                 :            :       && EXIT_IGNORE_STACK)
      84                 :      23773 :     discard_pending_stack_adjust ();
      85                 :    1469920 : }
      86                 :            : 
      87                 :            : /* Pop any previously-pushed arguments that have not been popped yet.  */
      88                 :            : 
      89                 :            : void
      90                 :   18753400 : do_pending_stack_adjust (void)
      91                 :            : {
      92                 :   18753400 :   if (inhibit_defer_pop == 0)
      93                 :            :     {
      94                 :   18733600 :       if (maybe_ne (pending_stack_adjust, 0))
      95                 :    1104080 :         adjust_stack (gen_int_mode (pending_stack_adjust, Pmode));
      96                 :   18733600 :       pending_stack_adjust = 0;
      97                 :            :     }
      98                 :   18753400 : }
      99                 :            : 
     100                 :            : /* Remember pending_stack_adjust/stack_pointer_delta.
     101                 :            :    To be used around code that may call do_pending_stack_adjust (),
     102                 :            :    but the generated code could be discarded e.g. using delete_insns_since.  */
     103                 :            : 
     104                 :            : void
     105                 :     397033 : save_pending_stack_adjust (saved_pending_stack_adjust *save)
     106                 :            : {
     107                 :     397033 :   save->x_pending_stack_adjust = pending_stack_adjust;
     108                 :     397033 :   save->x_stack_pointer_delta = stack_pointer_delta;
     109                 :     397033 : }
     110                 :            : 
     111                 :            : /* Restore the saved pending_stack_adjust/stack_pointer_delta.  */
     112                 :            : 
     113                 :            : void
     114                 :     104020 : restore_pending_stack_adjust (saved_pending_stack_adjust *save)
     115                 :            : {
     116                 :     104020 :   if (inhibit_defer_pop == 0)
     117                 :            :     {
     118                 :     103922 :       pending_stack_adjust = save->x_pending_stack_adjust;
     119                 :     103922 :       stack_pointer_delta = save->x_stack_pointer_delta;
     120                 :            :     }
     121                 :     104020 : }
     122                 :            : 
     123                 :            : /* Used internally by prefer_and_bit_test.  */
     124                 :            : 
     125                 :            : static GTY(()) rtx and_reg;
     126                 :            : static GTY(()) rtx and_test;
     127                 :            : static GTY(()) rtx shift_test;
     128                 :            : 
     129                 :            : /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
     130                 :            :    where X is an arbitrary register of mode MODE.  Return true if the former
     131                 :            :    is preferred.  */
     132                 :            : 
     133                 :            : static bool
     134                 :          0 : prefer_and_bit_test (scalar_int_mode mode, int bitnum)
     135                 :            : {
     136                 :          0 :   bool speed_p;
     137                 :          0 :   wide_int mask = wi::set_bit_in_zero (bitnum, GET_MODE_PRECISION (mode));
     138                 :            : 
     139                 :          0 :   if (and_test == 0)
     140                 :            :     {
     141                 :            :       /* Set up rtxes for the two variations.  Use NULL as a placeholder
     142                 :            :          for the BITNUM-based constants.  */
     143                 :          0 :       and_reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
     144                 :          0 :       and_test = gen_rtx_AND (mode, and_reg, NULL);
     145                 :          0 :       shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
     146                 :            :                                 const1_rtx);
     147                 :            :     }
     148                 :            :   else
     149                 :            :     {
     150                 :            :       /* Change the mode of the previously-created rtxes.  */
     151                 :          0 :       PUT_MODE (and_reg, mode);
     152                 :          0 :       PUT_MODE (and_test, mode);
     153                 :          0 :       PUT_MODE (shift_test, mode);
     154                 :          0 :       PUT_MODE (XEXP (shift_test, 0), mode);
     155                 :            :     }
     156                 :            : 
     157                 :            :   /* Fill in the integers.  */
     158                 :          0 :   XEXP (and_test, 1) = immed_wide_int_const (mask, mode);
     159                 :          0 :   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
     160                 :            : 
     161                 :          0 :   speed_p = optimize_insn_for_speed_p ();
     162                 :          0 :   return (rtx_cost (and_test, mode, IF_THEN_ELSE, 0, speed_p)
     163                 :          0 :           <= rtx_cost (shift_test, mode, IF_THEN_ELSE, 0, speed_p));
     164                 :            : }
     165                 :            : 
     166                 :            : /* Subroutine of do_jump, dealing with exploded comparisons of the type
     167                 :            :    OP0 CODE OP1 .  IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
     168                 :            :    PROB is probability of jump to if_true_label.  */
     169                 :            : 
     170                 :            : static void
     171                 :    3462920 : do_jump_1 (enum tree_code code, tree op0, tree op1,
     172                 :            :            rtx_code_label *if_false_label, rtx_code_label *if_true_label,
     173                 :            :            profile_probability prob)
     174                 :            : {
     175                 :    3462920 :   machine_mode mode;
     176                 :    3462920 :   rtx_code_label *drop_through_label = 0;
     177                 :    3462920 :   scalar_int_mode int_mode;
     178                 :            : 
     179                 :    3462920 :   switch (code)
     180                 :            :     {
     181                 :     899374 :     case EQ_EXPR:
     182                 :     899374 :       {
     183                 :     899374 :         tree inner_type = TREE_TYPE (op0);
     184                 :            : 
     185                 :     899374 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     186                 :            :                     != MODE_COMPLEX_FLOAT);
     187                 :     899374 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     188                 :            :                     != MODE_COMPLEX_INT);
     189                 :            : 
     190                 :     899374 :         if (integer_zerop (op1))
     191                 :     501212 :           do_jump (op0, if_true_label, if_false_label,
     192                 :            :                    prob.invert ());
     193                 :     788988 :         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
     194                 :     390826 :                  && !can_compare_p (EQ, int_mode, ccp_jump))
     195                 :          0 :           do_jump_by_parts_equality (int_mode, op0, op1, if_false_label,
     196                 :            :                                      if_true_label, prob);
     197                 :            :         else
     198                 :     398162 :           do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
     199                 :            :                                prob);
     200                 :            :         break;
     201                 :            :       }
     202                 :            : 
     203                 :    1794790 :     case NE_EXPR:
     204                 :    1794790 :       {
     205                 :    1794790 :         tree inner_type = TREE_TYPE (op0);
     206                 :            : 
     207                 :    1794790 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     208                 :            :                     != MODE_COMPLEX_FLOAT);
     209                 :    1794790 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     210                 :            :                     != MODE_COMPLEX_INT);
     211                 :            : 
     212                 :    1794790 :         if (integer_zerop (op1))
     213                 :     765309 :           do_jump (op0, if_false_label, if_true_label, prob);
     214                 :    1904860 :         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
     215                 :     875381 :                  && !can_compare_p (NE, int_mode, ccp_jump))
     216                 :          0 :           do_jump_by_parts_equality (int_mode, op0, op1, if_true_label,
     217                 :            :                                      if_false_label, prob.invert ());
     218                 :            :         else
     219                 :    1029480 :           do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
     220                 :            :                                prob);
     221                 :            :         break;
     222                 :            :       }
     223                 :            : 
     224                 :     153179 :     case LT_EXPR:
     225                 :     153179 :       mode = TYPE_MODE (TREE_TYPE (op0));
     226                 :     153179 :       if (is_int_mode (mode, &int_mode)
     227                 :     139535 :           && ! can_compare_p (LT, int_mode, ccp_jump))
     228                 :          0 :         do_jump_by_parts_greater (int_mode, op0, op1, 1, if_false_label,
     229                 :            :                                   if_true_label, prob);
     230                 :            :       else
     231                 :     153179 :         do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
     232                 :            :                              prob);
     233                 :            :       break;
     234                 :            : 
     235                 :     127881 :     case LE_EXPR:
     236                 :     127881 :       mode = TYPE_MODE (TREE_TYPE (op0));
     237                 :     127881 :       if (is_int_mode (mode, &int_mode)
     238                 :     124220 :           && ! can_compare_p (LE, int_mode, ccp_jump))
     239                 :          0 :         do_jump_by_parts_greater (int_mode, op0, op1, 0, if_true_label,
     240                 :            :                                   if_false_label, prob.invert ());
     241                 :            :       else
     242                 :     127881 :         do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
     243                 :            :                              prob);
     244                 :            :       break;
     245                 :            : 
     246                 :     312729 :     case GT_EXPR:
     247                 :     312729 :       mode = TYPE_MODE (TREE_TYPE (op0));
     248                 :     312729 :       if (is_int_mode (mode, &int_mode)
     249                 :     298020 :           && ! can_compare_p (GT, int_mode, ccp_jump))
     250                 :          0 :         do_jump_by_parts_greater (int_mode, op0, op1, 0, if_false_label,
     251                 :            :                                   if_true_label, prob);
     252                 :            :       else
     253                 :     312729 :         do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
     254                 :            :                              prob);
     255                 :            :       break;
     256                 :            : 
     257                 :      73920 :     case GE_EXPR:
     258                 :      73920 :       mode = TYPE_MODE (TREE_TYPE (op0));
     259                 :      73920 :       if (is_int_mode (mode, &int_mode)
     260                 :      68982 :           && ! can_compare_p (GE, int_mode, ccp_jump))
     261                 :          0 :         do_jump_by_parts_greater (int_mode, op0, op1, 1, if_true_label,
     262                 :            :                                   if_false_label, prob.invert ());
     263                 :            :       else
     264                 :      73920 :         do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
     265                 :            :                              prob);
     266                 :            :       break;
     267                 :            : 
     268                 :       2126 :     case ORDERED_EXPR:
     269                 :       2126 :       do_compare_and_jump (op0, op1, ORDERED, ORDERED,
     270                 :            :                            if_false_label, if_true_label, prob);
     271                 :       2126 :       break;
     272                 :            : 
     273                 :       3140 :     case UNORDERED_EXPR:
     274                 :       3140 :       do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
     275                 :            :                            if_false_label, if_true_label, prob);
     276                 :       3140 :       break;
     277                 :            : 
     278                 :        570 :     case UNLT_EXPR:
     279                 :        570 :       do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
     280                 :            :                            prob);
     281                 :        570 :       break;
     282                 :            : 
     283                 :       2662 :     case UNLE_EXPR:
     284                 :       2662 :       do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
     285                 :            :                            prob);
     286                 :       2662 :       break;
     287                 :            : 
     288                 :       1006 :     case UNGT_EXPR:
     289                 :       1006 :       do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
     290                 :            :                            prob);
     291                 :       1006 :       break;
     292                 :            : 
     293                 :       2084 :     case UNGE_EXPR:
     294                 :       2084 :       do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
     295                 :            :                            prob);
     296                 :       2084 :       break;
     297                 :            : 
     298                 :        258 :     case UNEQ_EXPR:
     299                 :        258 :       do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
     300                 :            :                            prob);
     301                 :        258 :       break;
     302                 :            : 
     303                 :          1 :     case LTGT_EXPR:
     304                 :          1 :       do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
     305                 :            :                            prob);
     306                 :          1 :       break;
     307                 :            : 
     308                 :      41285 :     case TRUTH_ANDIF_EXPR:
     309                 :      41285 :       {
     310                 :            :         /* Spread the probability that the expression is false evenly between
     311                 :            :            the two conditions. So the first condition is false half the total
     312                 :            :            probability of being false. The second condition is false the other
     313                 :            :            half of the total probability of being false, so its jump has a false
     314                 :            :            probability of half the total, relative to the probability we
     315                 :            :            reached it (i.e. the first condition was true).  */
     316                 :      41285 :         profile_probability op0_prob = profile_probability::uninitialized ();
     317                 :      41285 :         profile_probability op1_prob = profile_probability::uninitialized ();
     318                 :      41285 :         if (prob.initialized_p ())
     319                 :            :           {
     320                 :      41285 :             op1_prob = prob.invert ();
     321                 :      41285 :             op0_prob = op1_prob.split (profile_probability::even ());
     322                 :            :             /* Get the probability that each jump below is true.  */
     323                 :      41285 :             op0_prob = op0_prob.invert ();
     324                 :      41285 :             op1_prob = op1_prob.invert ();
     325                 :            :           }
     326                 :      41285 :         if (if_false_label == NULL)
     327                 :            :           {
     328                 :      25660 :             drop_through_label = gen_label_rtx ();
     329                 :      25660 :             do_jump (op0, drop_through_label, NULL, op0_prob);
     330                 :      25660 :             do_jump (op1, NULL, if_true_label, op1_prob);
     331                 :            :           }
     332                 :            :         else
     333                 :            :           {
     334                 :      15625 :             do_jump (op0, if_false_label, NULL, op0_prob);
     335                 :      15625 :             do_jump (op1, if_false_label, if_true_label, op1_prob);
     336                 :            :           }
     337                 :      25660 :         break;
     338                 :            :       }
     339                 :            : 
     340                 :      47920 :     case TRUTH_ORIF_EXPR:
     341                 :      47920 :       {
     342                 :            :         /* Spread the probability evenly between the two conditions. So
     343                 :            :            the first condition has half the total probability of being true.
     344                 :            :            The second condition has the other half of the total probability,
     345                 :            :            so its jump has a probability of half the total, relative to
     346                 :            :            the probability we reached it (i.e. the first condition was false).  */
     347                 :      47920 :         profile_probability op0_prob = profile_probability::uninitialized ();
     348                 :      47920 :         profile_probability op1_prob = profile_probability::uninitialized ();
     349                 :      47920 :         if (prob.initialized_p ())
     350                 :            :           {
     351                 :      47911 :             op1_prob = prob;
     352                 :      47911 :             op0_prob = op1_prob.split (profile_probability::even ());
     353                 :            :           }
     354                 :      47920 :         if (if_true_label == NULL)
     355                 :            :           {
     356                 :      23960 :             drop_through_label = gen_label_rtx ();
     357                 :      23960 :             do_jump (op0, NULL, drop_through_label, op0_prob);
     358                 :      23960 :             do_jump (op1, if_false_label, NULL, op1_prob);
     359                 :            :           }
     360                 :            :         else
     361                 :            :           {
     362                 :      23960 :             do_jump (op0, NULL, if_true_label, op0_prob);
     363                 :      23960 :             do_jump (op1, if_false_label, if_true_label, op1_prob);
     364                 :            :           }
     365                 :      23960 :         break;
     366                 :            :       }
     367                 :            : 
     368                 :          0 :     default:
     369                 :          0 :       gcc_unreachable ();
     370                 :            :     }
     371                 :            : 
     372                 :    3462920 :   if (drop_through_label)
     373                 :            :     {
     374                 :      49620 :       do_pending_stack_adjust ();
     375                 :      49620 :       emit_label (drop_through_label);
     376                 :            :     }
     377                 :    3462920 : }
     378                 :            : 
     379                 :            : /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
     380                 :            :    the result is zero, or IF_TRUE_LABEL if the result is one.
     381                 :            :    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
     382                 :            :    meaning fall through in that case.
     383                 :            : 
     384                 :            :    do_jump always does any pending stack adjust except when it does not
     385                 :            :    actually perform a jump.  An example where there is no jump
     386                 :            :    is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
     387                 :            : 
     388                 :            :    PROB is probability of jump to if_true_label.  */
     389                 :            : 
     390                 :            : static void
     391                 :    1446920 : do_jump (tree exp, rtx_code_label *if_false_label,
     392                 :            :          rtx_code_label *if_true_label, profile_probability prob)
     393                 :            : {
     394                 :    1446920 :   enum tree_code code = TREE_CODE (exp);
     395                 :    1446920 :   rtx temp;
     396                 :    1446920 :   int i;
     397                 :    1446920 :   tree type;
     398                 :    1446920 :   scalar_int_mode mode;
     399                 :    1446920 :   rtx_code_label *drop_through_label = NULL;
     400                 :            : 
     401                 :    1446920 :   switch (code)
     402                 :            :     {
     403                 :            :     case ERROR_MARK:
     404                 :            :       break;
     405                 :            : 
     406                 :          1 :     case INTEGER_CST:
     407                 :          1 :       {
     408                 :          1 :         rtx_code_label *lab = integer_zerop (exp) ? if_false_label
     409                 :          1 :                                                   : if_true_label;
     410                 :          1 :         if (lab)
     411                 :          0 :           emit_jump (lab);
     412                 :            :         break;
     413                 :            :       }
     414                 :            : 
     415                 :            : #if 0
     416                 :            :       /* This is not true with #pragma weak  */
     417                 :            :     case ADDR_EXPR:
     418                 :            :       /* The address of something can never be zero.  */
     419                 :            :       if (if_true_label)
     420                 :            :         emit_jump (if_true_label);
     421                 :            :       break;
     422                 :            : #endif
     423                 :            : 
     424                 :          0 :     case NOP_EXPR:
     425                 :          0 :       if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
     426                 :          0 :           || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
     427                 :          0 :           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
     428                 :          0 :           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
     429                 :          0 :         goto normal;
     430                 :            :       /* FALLTHRU */
     431                 :          0 :     case CONVERT_EXPR:
     432                 :            :       /* If we are narrowing the operand, we have to do the compare in the
     433                 :            :          narrower mode.  */
     434                 :          0 :       if ((TYPE_PRECISION (TREE_TYPE (exp))
     435                 :          0 :            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
     436                 :          0 :         goto normal;
     437                 :            :       /* FALLTHRU */
     438                 :          0 :     case NON_LVALUE_EXPR:
     439                 :          0 :     case ABS_EXPR:
     440                 :          0 :     case ABSU_EXPR:
     441                 :          0 :     case NEGATE_EXPR:
     442                 :          0 :     case LROTATE_EXPR:
     443                 :          0 :     case RROTATE_EXPR:
     444                 :            :       /* These cannot change zero->nonzero or vice versa.  */
     445                 :          0 :       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
     446                 :          0 :       break;
     447                 :            : 
     448                 :          0 :     case TRUTH_NOT_EXPR:
     449                 :          0 :       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
     450                 :            :                prob.invert ());
     451                 :          0 :       break;
     452                 :            : 
     453                 :          0 :     case COND_EXPR:
     454                 :          0 :       {
     455                 :          0 :         rtx_code_label *label1 = gen_label_rtx ();
     456                 :          0 :         if (!if_true_label || !if_false_label)
     457                 :            :           {
     458                 :          0 :             drop_through_label = gen_label_rtx ();
     459                 :          0 :             if (!if_true_label)
     460                 :          0 :               if_true_label = drop_through_label;
     461                 :          0 :             if (!if_false_label)
     462                 :          0 :               if_false_label = drop_through_label;
     463                 :            :           }
     464                 :            : 
     465                 :          0 :         do_pending_stack_adjust ();
     466                 :          0 :         do_jump (TREE_OPERAND (exp, 0), label1, NULL,
     467                 :            :                  profile_probability::uninitialized ());
     468                 :          0 :         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
     469                 :          0 :         emit_label (label1);
     470                 :          0 :         do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
     471                 :          0 :         break;
     472                 :            :       }
     473                 :            : 
     474                 :          0 :     case COMPOUND_EXPR:
     475                 :            :       /* Lowered by gimplify.c.  */
     476                 :          0 :       gcc_unreachable ();
     477                 :            : 
     478                 :          0 :     case MINUS_EXPR:
     479                 :            :       /* Nonzero iff operands of minus differ.  */
     480                 :          0 :       code = NE_EXPR;
     481                 :            : 
     482                 :            :       /* FALLTHRU */
     483                 :       1979 :     case EQ_EXPR:
     484                 :       1979 :     case NE_EXPR:
     485                 :       1979 :     case LT_EXPR:
     486                 :       1979 :     case LE_EXPR:
     487                 :       1979 :     case GT_EXPR:
     488                 :       1979 :     case GE_EXPR:
     489                 :       1979 :     case ORDERED_EXPR:
     490                 :       1979 :     case UNORDERED_EXPR:
     491                 :       1979 :     case UNLT_EXPR:
     492                 :       1979 :     case UNLE_EXPR:
     493                 :       1979 :     case UNGT_EXPR:
     494                 :       1979 :     case UNGE_EXPR:
     495                 :       1979 :     case UNEQ_EXPR:
     496                 :       1979 :     case LTGT_EXPR:
     497                 :       1979 :     case TRUTH_ANDIF_EXPR:
     498                 :       1979 :     case TRUTH_ORIF_EXPR:
     499                 :       1979 :     other_code:
     500                 :       1979 :       do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
     501                 :            :                  if_false_label, if_true_label, prob);
     502                 :       1979 :       break;
     503                 :            : 
     504                 :          0 :     case BIT_AND_EXPR:
     505                 :            :       /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
     506                 :            :          See if the former is preferred for jump tests and restore it
     507                 :            :          if so.  */
     508                 :          0 :       if (integer_onep (TREE_OPERAND (exp, 1)))
     509                 :            :         {
     510                 :          0 :           tree exp0 = TREE_OPERAND (exp, 0);
     511                 :          0 :           rtx_code_label *set_label, *clr_label;
     512                 :          0 :           profile_probability setclr_prob = prob;
     513                 :            : 
     514                 :            :           /* Strip narrowing integral type conversions.  */
     515                 :          0 :           while (CONVERT_EXPR_P (exp0)
     516                 :          0 :                  && TREE_OPERAND (exp0, 0) != error_mark_node
     517                 :          0 :                  && TYPE_PRECISION (TREE_TYPE (exp0))
     518                 :          0 :                     <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
     519                 :          0 :             exp0 = TREE_OPERAND (exp0, 0);
     520                 :            : 
     521                 :            :           /* "exp0 ^ 1" inverts the sense of the single bit test.  */
     522                 :          0 :           if (TREE_CODE (exp0) == BIT_XOR_EXPR
     523                 :          0 :               && integer_onep (TREE_OPERAND (exp0, 1)))
     524                 :            :             {
     525                 :          0 :               exp0 = TREE_OPERAND (exp0, 0);
     526                 :          0 :               clr_label = if_true_label;
     527                 :          0 :               set_label = if_false_label;
     528                 :          0 :               setclr_prob = prob.invert ();
     529                 :            :             }
     530                 :            :           else
     531                 :            :             {
     532                 :            :               clr_label = if_false_label;
     533                 :            :               set_label = if_true_label;
     534                 :            :             }
     535                 :            : 
     536                 :          0 :           if (TREE_CODE (exp0) == RSHIFT_EXPR)
     537                 :            :             {
     538                 :          0 :               tree arg = TREE_OPERAND (exp0, 0);
     539                 :          0 :               tree shift = TREE_OPERAND (exp0, 1);
     540                 :          0 :               tree argtype = TREE_TYPE (arg);
     541                 :          0 :               if (TREE_CODE (shift) == INTEGER_CST
     542                 :          0 :                   && compare_tree_int (shift, 0) >= 0
     543                 :          0 :                   && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
     544                 :          0 :                   && prefer_and_bit_test (SCALAR_INT_TYPE_MODE (argtype),
     545                 :          0 :                                           TREE_INT_CST_LOW (shift)))
     546                 :            :                 {
     547                 :          0 :                   unsigned HOST_WIDE_INT mask
     548                 :          0 :                     = HOST_WIDE_INT_1U << TREE_INT_CST_LOW (shift);
     549                 :          0 :                   do_jump (build2 (BIT_AND_EXPR, argtype, arg,
     550                 :            :                                    build_int_cstu (argtype, mask)),
     551                 :            :                            clr_label, set_label, setclr_prob);
     552                 :          0 :                   break;
     553                 :            :                 }
     554                 :            :             }
     555                 :            :         }
     556                 :            : 
     557                 :            :       /* If we are AND'ing with a small constant, do this comparison in the
     558                 :            :          smallest type that fits.  If the machine doesn't have comparisons
     559                 :            :          that small, it will be converted back to the wider comparison.
     560                 :            :          This helps if we are testing the sign bit of a narrower object.
     561                 :            :          combine can't do this for us because it can't know whether a
     562                 :            :          ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
     563                 :            : 
     564                 :          0 :       if (! SLOW_BYTE_ACCESS
     565                 :          0 :           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
     566                 :          0 :           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
     567                 :          0 :           && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
     568                 :          0 :           && int_mode_for_size (i + 1, 0).exists (&mode)
     569                 :          0 :           && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
     570                 :          0 :           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
     571                 :          0 :           && have_insn_for (COMPARE, TYPE_MODE (type)))
     572                 :            :         {
     573                 :          0 :           do_jump (fold_convert (type, exp), if_false_label, if_true_label,
     574                 :            :                    prob);
     575                 :          0 :           break;
     576                 :            :         }
     577                 :            : 
     578                 :          0 :       if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
     579                 :          0 :           || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
     580                 :          0 :         goto normal;
     581                 :            : 
     582                 :            :       /* Boolean comparisons can be compiled as TRUTH_AND_EXPR.  */
     583                 :            :       /* FALLTHRU */
     584                 :            : 
     585                 :          0 :     case TRUTH_AND_EXPR:
     586                 :            :       /* High branch cost, expand as the bitwise AND of the conditions.
     587                 :            :          Do the same if the RHS has side effects, because we're effectively
     588                 :            :          turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR.  */
     589                 :          0 :       if (BRANCH_COST (optimize_insn_for_speed_p (),
     590                 :            :                        false) >= 4
     591                 :          0 :           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
     592                 :          0 :         goto normal;
     593                 :          0 :       code = TRUTH_ANDIF_EXPR;
     594                 :          0 :       goto other_code;
     595                 :            : 
     596                 :          0 :     case BIT_IOR_EXPR:
     597                 :          0 :     case TRUTH_OR_EXPR:
     598                 :            :       /* High branch cost, expand as the bitwise OR of the conditions.
     599                 :            :          Do the same if the RHS has side effects, because we're effectively
     600                 :            :          turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR.  */
     601                 :          0 :       if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
     602                 :          0 :           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
     603                 :          0 :         goto normal;
     604                 :          0 :       code = TRUTH_ORIF_EXPR;
     605                 :          0 :       goto other_code;
     606                 :            : 
     607                 :            :       /* Fall through and generate the normal code.  */
     608                 :    1444940 :     default:
     609                 :    1444940 :     normal:
     610                 :    1444940 :       temp = expand_normal (exp);
     611                 :    1444940 :       do_pending_stack_adjust ();
     612                 :            :       /* The RTL optimizers prefer comparisons against pseudos.  */
     613                 :    1444940 :       if (GET_CODE (temp) == SUBREG)
     614                 :            :         {
     615                 :            :           /* Compare promoted variables in their promoted mode.  */
     616                 :      32199 :           if (SUBREG_PROMOTED_VAR_P (temp)
     617                 :      32199 :               && REG_P (XEXP (temp, 0)))
     618                 :            :             temp = XEXP (temp, 0);
     619                 :            :           else
     620                 :      32199 :             temp = copy_to_reg (temp);
     621                 :            :         }
     622                 :    2889880 :       do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
     623                 :    1444940 :                                NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
     624                 :    1444940 :                                GET_MODE (temp), NULL_RTX,
     625                 :            :                                if_false_label, if_true_label, prob);
     626                 :            :     }
     627                 :            : 
     628                 :    1446920 :   if (drop_through_label)
     629                 :            :     {
     630                 :          0 :       do_pending_stack_adjust ();
     631                 :          0 :       emit_label (drop_through_label);
     632                 :            :     }
     633                 :    1446920 : }
     634                 :            : 
     635                 :            : /* Compare OP0 with OP1, word at a time, in mode MODE.
     636                 :            :    UNSIGNEDP says to do unsigned comparison.
     637                 :            :    Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
     638                 :            : 
     639                 :            : static void
     640                 :          0 : do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0,
     641                 :            :                               rtx op1, rtx_code_label *if_false_label,
     642                 :            :                               rtx_code_label *if_true_label,
     643                 :            :                               profile_probability prob)
     644                 :            : {
     645                 :          0 :   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
     646                 :          0 :   rtx_code_label *drop_through_label = 0;
     647                 :          0 :   bool drop_through_if_true = false, drop_through_if_false = false;
     648                 :          0 :   enum rtx_code code = GT;
     649                 :          0 :   int i;
     650                 :            : 
     651                 :          0 :   if (! if_true_label || ! if_false_label)
     652                 :          0 :     drop_through_label = gen_label_rtx ();
     653                 :          0 :   if (! if_true_label)
     654                 :            :     {
     655                 :          0 :       if_true_label = drop_through_label;
     656                 :          0 :       drop_through_if_true = true;
     657                 :            :     }
     658                 :          0 :   if (! if_false_label)
     659                 :            :     {
     660                 :          0 :       if_false_label = drop_through_label;
     661                 :          0 :       drop_through_if_false = true;
     662                 :            :     }
     663                 :            : 
     664                 :            :   /* Deal with the special case 0 > x: only one comparison is necessary and
     665                 :            :      we reverse it to avoid jumping to the drop-through label.  */
     666                 :          0 :   if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
     667                 :            :     {
     668                 :          0 :       code = LE;
     669                 :          0 :       if_true_label = if_false_label;
     670                 :          0 :       if_false_label = drop_through_label;
     671                 :          0 :       prob = prob.invert ();
     672                 :            :     }
     673                 :            : 
     674                 :            :   /* Compare a word at a time, high order first.  */
     675                 :          0 :   for (i = 0; i < nwords; i++)
     676                 :            :     {
     677                 :          0 :       rtx op0_word, op1_word;
     678                 :            : 
     679                 :          0 :       if (WORDS_BIG_ENDIAN)
     680                 :            :         {
     681                 :            :           op0_word = operand_subword_force (op0, i, mode);
     682                 :            :           op1_word = operand_subword_force (op1, i, mode);
     683                 :            :         }
     684                 :            :       else
     685                 :            :         {
     686                 :          0 :           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
     687                 :          0 :           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
     688                 :            :         }
     689                 :            : 
     690                 :            :       /* All but high-order word must be compared as unsigned.  */
     691                 :          0 :       do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
     692                 :            :                                word_mode, NULL_RTX, NULL, if_true_label,
     693                 :            :                                prob);
     694                 :            : 
     695                 :            :       /* Emit only one comparison for 0.  Do not emit the last cond jump.  */
     696                 :          0 :       if (op0 == const0_rtx || i == nwords - 1)
     697                 :            :         break;
     698                 :            : 
     699                 :            :       /* Consider lower words only if these are equal.  */
     700                 :          0 :       do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
     701                 :            :                                NULL_RTX, NULL, if_false_label,
     702                 :            :                                prob.invert ());
     703                 :            :     }
     704                 :            : 
     705                 :          0 :   if (!drop_through_if_false)
     706                 :          0 :     emit_jump (if_false_label);
     707                 :          0 :   if (drop_through_label)
     708                 :          0 :     emit_label (drop_through_label);
     709                 :          0 : }
     710                 :            : 
     711                 :            : /* Given a comparison expression EXP for values too wide to be compared
     712                 :            :    with one insn, test the comparison and jump to the appropriate label.
     713                 :            :    The code of EXP is ignored; we always test GT if SWAP is 0,
     714                 :            :    and LT if SWAP is 1.  MODE is the mode of the two operands.  */
     715                 :            : 
     716                 :            : static void
     717                 :          0 : do_jump_by_parts_greater (scalar_int_mode mode, tree treeop0, tree treeop1,
     718                 :            :                           int swap, rtx_code_label *if_false_label,
     719                 :            :                           rtx_code_label *if_true_label,
     720                 :            :                           profile_probability prob)
     721                 :            : {
     722                 :          0 :   rtx op0 = expand_normal (swap ? treeop1 : treeop0);
     723                 :          0 :   rtx op1 = expand_normal (swap ? treeop0 : treeop1);
     724                 :          0 :   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
     725                 :            : 
     726                 :          0 :   do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
     727                 :            :                                 if_true_label, prob);
     728                 :          0 : }
     729                 :            : 
     730                 :            : /* Jump according to whether OP0 is 0.  We assume that OP0 has an integer
     731                 :            :    mode, MODE, that is too wide for the available compare insns.  Either
     732                 :            :    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL
     733                 :            :    to indicate drop through.  */
     734                 :            : 
     735                 :            : static void
     736                 :          0 : do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0,
     737                 :            :                            rtx_code_label *if_false_label,
     738                 :            :                            rtx_code_label *if_true_label,
     739                 :            :                            profile_probability prob)
     740                 :            : {
     741                 :          0 :   int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
     742                 :          0 :   rtx part;
     743                 :          0 :   int i;
     744                 :          0 :   rtx_code_label *drop_through_label = NULL;
     745                 :            : 
     746                 :            :   /* The fastest way of doing this comparison on almost any machine is to
     747                 :            :      "or" all the words and compare the result.  If all have to be loaded
     748                 :            :      from memory and this is a very wide item, it's possible this may
     749                 :            :      be slower, but that's highly unlikely.  */
     750                 :            : 
     751                 :          0 :   part = gen_reg_rtx (word_mode);
     752                 :          0 :   emit_move_insn (part, operand_subword_force (op0, 0, mode));
     753                 :          0 :   for (i = 1; i < nwords && part != 0; i++)
     754                 :          0 :     part = expand_binop (word_mode, ior_optab, part,
     755                 :            :                          operand_subword_force (op0, i, mode),
     756                 :            :                          part, 1, OPTAB_WIDEN);
     757                 :            : 
     758                 :          0 :   if (part != 0)
     759                 :            :     {
     760                 :          0 :       do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
     761                 :            :                                NULL_RTX, if_false_label, if_true_label, prob);
     762                 :          0 :       return;
     763                 :            :     }
     764                 :            : 
     765                 :            :   /* If we couldn't do the "or" simply, do this with a series of compares.  */
     766                 :          0 :   if (! if_false_label)
     767                 :          0 :     if_false_label = drop_through_label = gen_label_rtx ();
     768                 :            : 
     769                 :          0 :   for (i = 0; i < nwords; i++)
     770                 :          0 :     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
     771                 :            :                              const0_rtx, EQ, 1, word_mode, NULL_RTX,
     772                 :            :                              if_false_label, NULL, prob);
     773                 :            : 
     774                 :          0 :   if (if_true_label)
     775                 :          0 :     emit_jump (if_true_label);
     776                 :            : 
     777                 :          0 :   if (drop_through_label)
     778                 :          0 :     emit_label (drop_through_label);
     779                 :            : }
     780                 :            : 
     781                 :            : /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
     782                 :            :    where MODE is an integer mode too wide to be compared with one insn.
     783                 :            :    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
     784                 :            :    to indicate drop through.  */
     785                 :            : 
     786                 :            : static void
     787                 :          0 : do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1,
     788                 :            :                                rtx_code_label *if_false_label,
     789                 :            :                                rtx_code_label *if_true_label,
     790                 :            :                                profile_probability prob)
     791                 :            : {
     792                 :          0 :   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
     793                 :          0 :   rtx_code_label *drop_through_label = NULL;
     794                 :          0 :   int i;
     795                 :            : 
     796                 :          0 :   if (op1 == const0_rtx)
     797                 :            :     {
     798                 :          0 :       do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
     799                 :            :                                  prob);
     800                 :          0 :       return;
     801                 :            :     }
     802                 :          0 :   else if (op0 == const0_rtx)
     803                 :            :     {
     804                 :          0 :       do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
     805                 :            :                                  prob);
     806                 :          0 :       return;
     807                 :            :     }
     808                 :            : 
     809                 :          0 :   if (! if_false_label)
     810                 :          0 :     drop_through_label = if_false_label = gen_label_rtx ();
     811                 :            : 
     812                 :          0 :   for (i = 0; i < nwords; i++)
     813                 :          0 :     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
     814                 :            :                              operand_subword_force (op1, i, mode),
     815                 :            :                              EQ, 0, word_mode, NULL_RTX,
     816                 :            :                              if_false_label, NULL, prob);
     817                 :            : 
     818                 :          0 :   if (if_true_label)
     819                 :          0 :     emit_jump (if_true_label);
     820                 :          0 :   if (drop_through_label)
     821                 :          0 :     emit_label (drop_through_label);
     822                 :            : }
     823                 :            : 
     824                 :            : /* Given an EQ_EXPR expression EXP for values too wide to be compared
     825                 :            :    with one insn, test the comparison and jump to the appropriate label.
     826                 :            :    MODE is the mode of the two operands.  */
     827                 :            : 
     828                 :            : static void
     829                 :          0 : do_jump_by_parts_equality (scalar_int_mode mode, tree treeop0, tree treeop1,
     830                 :            :                            rtx_code_label *if_false_label,
     831                 :            :                            rtx_code_label *if_true_label,
     832                 :            :                            profile_probability prob)
     833                 :            : {
     834                 :          0 :   rtx op0 = expand_normal (treeop0);
     835                 :          0 :   rtx op1 = expand_normal (treeop1);
     836                 :          0 :   do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
     837                 :            :                                  if_true_label, prob);
     838                 :          0 : }
     839                 :            : 
     840                 :            : /* Split a comparison into two others, the second of which has the other
     841                 :            :    "orderedness".  The first is always ORDERED or UNORDERED if MODE
     842                 :            :    does not honor NaNs (which means that it can be skipped in that case;
     843                 :            :    see do_compare_rtx_and_jump).
     844                 :            : 
     845                 :            :    The two conditions are written in *CODE1 and *CODE2.  Return true if
     846                 :            :    the conditions must be ANDed, false if they must be ORed.  */
     847                 :            : 
     848                 :            : bool
     849                 :     204078 : split_comparison (enum rtx_code code, machine_mode mode,
     850                 :            :                   enum rtx_code *code1, enum rtx_code *code2)
     851                 :            : {
     852                 :     204078 :   switch (code)
     853                 :            :     {
     854                 :         35 :     case LT:
     855                 :         35 :       *code1 = ORDERED;
     856                 :         35 :       *code2 = UNLT;
     857                 :         35 :       return true;
     858                 :          7 :     case LE:
     859                 :          7 :       *code1 = ORDERED;
     860                 :          7 :       *code2 = UNLE;
     861                 :          7 :       return true;
     862                 :          4 :     case GT:
     863                 :          4 :       *code1 = ORDERED;
     864                 :          4 :       *code2 = UNGT;
     865                 :          4 :       return true;
     866                 :         11 :     case GE:
     867                 :         11 :       *code1 = ORDERED;
     868                 :         11 :       *code2 = UNGE;
     869                 :         11 :       return true;
     870                 :       7310 :     case EQ:
     871                 :       7310 :       *code1 = ORDERED;
     872                 :       7310 :       *code2 = UNEQ;
     873                 :       7310 :       return true;
     874                 :     188745 :     case NE:
     875                 :     188745 :       *code1 = UNORDERED;
     876                 :     188745 :       *code2 = LTGT;
     877                 :     188745 :       return false;
     878                 :        124 :     case UNLT:
     879                 :        124 :       *code1 = UNORDERED;
     880                 :        124 :       *code2 = LT;
     881                 :        124 :       return false;
     882                 :       4163 :     case UNLE:
     883                 :       4163 :       *code1 = UNORDERED;
     884                 :       4163 :       *code2 = LE;
     885                 :       4163 :       return false;
     886                 :        215 :     case UNGT:
     887                 :        215 :       *code1 = UNORDERED;
     888                 :        215 :       *code2 = GT;
     889                 :        215 :       return false;
     890                 :       3427 :     case UNGE:
     891                 :       3427 :       *code1 = UNORDERED;
     892                 :       3427 :       *code2 = GE;
     893                 :       3427 :       return false;
     894                 :         36 :     case UNEQ:
     895                 :         36 :       *code1 = UNORDERED;
     896                 :         36 :       *code2 = EQ;
     897                 :         36 :       return false;
     898                 :          1 :     case LTGT:
     899                 :            :       /* Do not turn a trapping comparison into a non-trapping one.  */
     900                 :          1 :       if (HONOR_NANS (mode))
     901                 :            :         {
     902                 :          1 :           *code1 = LT;
     903                 :          1 :           *code2 = GT;
     904                 :          1 :           return false;
     905                 :            :         }
     906                 :            :       else
     907                 :            :         {
     908                 :          0 :           *code1 = ORDERED;
     909                 :          0 :           *code2 = NE;
     910                 :          0 :           return true;
     911                 :            :         }
     912                 :          0 :     default:
     913                 :          0 :       gcc_unreachable ();
     914                 :            :     }
     915                 :            : }
     916                 :            : 
     917                 :            : /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.
     918                 :            :    PROB is probability of jump to LABEL.  */
     919                 :            : 
     920                 :            : void
     921                 :          0 : jumpif (tree exp, rtx_code_label *label, profile_probability prob)
     922                 :            : {
     923                 :          0 :   do_jump (exp, NULL, label, prob);
     924                 :          0 : }
     925                 :            : 
     926                 :            : /* Similar to jumpif but dealing with exploded comparisons of the type
     927                 :            :    OP0 CODE OP1 .  LABEL and PROB are like in jumpif.  */
     928                 :            : 
     929                 :            : void
     930                 :    1495630 : jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
     931                 :            :           profile_probability prob)
     932                 :            : {
     933                 :    1495630 :   do_jump_1 (code, op0, op1, NULL, label, prob);
     934                 :    1495630 : }
     935                 :            : 
     936                 :            : /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
     937                 :            :    PROB is probability of jump to LABEL.  */
     938                 :            : 
     939                 :            : void
     940                 :       1989 : jumpifnot (tree exp, rtx_code_label *label, profile_probability prob)
     941                 :            : {
     942                 :       1989 :   do_jump (exp, label, NULL, prob.invert ());
     943                 :       1989 : }
     944                 :            : 
     945                 :            : /* Similar to jumpifnot but dealing with exploded comparisons of the type
     946                 :            :    OP0 CODE OP1 .  LABEL and PROB are like in jumpifnot.  */
     947                 :            : 
     948                 :            : void
     949                 :    1965320 : jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
     950                 :            :              profile_probability prob)
     951                 :            : {
     952                 :    1965320 :   do_jump_1 (code, op0, op1, label, NULL, prob.invert ());
     953                 :    1965320 : }
     954                 :            : 
     955                 :            : /* Like do_compare_and_jump but expects the values to compare as two rtx's.
     956                 :            :    The decision as to signed or unsigned comparison must be made by the caller.
     957                 :            : 
     958                 :            :    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
     959                 :            :    compared.  */
     960                 :            : 
     961                 :            : void
     962                 :    3835250 : do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
     963                 :            :                          machine_mode mode, rtx size,
     964                 :            :                          rtx_code_label *if_false_label,
     965                 :            :                          rtx_code_label *if_true_label,
     966                 :            :                          profile_probability prob)
     967                 :            : {
     968                 :    3835250 :   rtx tem;
     969                 :    3835250 :   rtx_code_label *dummy_label = NULL;
     970                 :            : 
     971                 :            :   /* Reverse the comparison if that is safe and we want to jump if it is
     972                 :            :      false.  Also convert to the reverse comparison if the target can
     973                 :            :      implement it.  */
     974                 :    3835250 :   if ((! if_true_label
     975                 :    1988700 :        || ! can_compare_p (code, mode, ccp_jump))
     976                 :    3960040 :       && (! FLOAT_MODE_P (mode)
     977                 :     219050 :           || code == ORDERED || code == UNORDERED
     978                 :     204265 :           || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
     979                 :     204265 :           || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
     980                 :            :     {
     981                 :    1930190 :       enum rtx_code rcode;
     982                 :    1930190 :       if (FLOAT_MODE_P (mode))
     983                 :     177896 :         rcode = reverse_condition_maybe_unordered (code);
     984                 :            :       else
     985                 :    1752300 :         rcode = reverse_condition (code);
     986                 :            : 
     987                 :            :       /* Canonicalize to UNORDERED for the libcall.  */
     988                 :    1930190 :       if (can_compare_p (rcode, mode, ccp_jump)
     989                 :    1930190 :           || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
     990                 :            :         {
     991                 :    1761900 :           std::swap (if_true_label, if_false_label);
     992                 :    1761900 :           code = rcode;
     993                 :    1761900 :           prob = prob.invert ();
     994                 :            :         }
     995                 :            :     }
     996                 :            : 
     997                 :            :   /* If one operand is constant, make it the second one.  Only do this
     998                 :            :      if the other operand is not constant as well.  */
     999                 :            : 
    1000                 :    3835250 :   if (swap_commutative_operands_p (op0, op1))
    1001                 :            :     {
    1002                 :      53927 :       std::swap (op0, op1);
    1003                 :      53927 :       code = swap_condition (code);
    1004                 :            :     }
    1005                 :            : 
    1006                 :    3835250 :   do_pending_stack_adjust ();
    1007                 :            : 
    1008                 :    3835250 :   code = unsignedp ? unsigned_condition (code) : code;
    1009                 :    3835250 :   if ((tem = simplify_relational_operation (code, mode, VOIDmode,
    1010                 :            :                                             op0, op1)) != 0)
    1011                 :            :     {
    1012                 :       3365 :       if (CONSTANT_P (tem))
    1013                 :            :         {
    1014                 :       5688 :           rtx_code_label *label = (tem == const0_rtx
    1015                 :        789 :                                    || tem == CONST0_RTX (mode))
    1016                 :       2844 :                                         ? if_false_label : if_true_label;
    1017                 :       2844 :           if (label)
    1018                 :        782 :             emit_jump (label);
    1019                 :       2844 :           return;
    1020                 :            :         }
    1021                 :            : 
    1022                 :        521 :       code = GET_CODE (tem);
    1023                 :        521 :       mode = GET_MODE (tem);
    1024                 :        521 :       op0 = XEXP (tem, 0);
    1025                 :        521 :       op1 = XEXP (tem, 1);
    1026                 :       1042 :       unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
    1027                 :            :     }
    1028                 :            : 
    1029                 :    3832400 :   if (! if_true_label)
    1030                 :      85042 :     dummy_label = if_true_label = gen_label_rtx ();
    1031                 :            : 
    1032                 :    3832400 :   scalar_int_mode int_mode;
    1033                 :    3832400 :   if (is_int_mode (mode, &int_mode)
    1034                 :    3468670 :       && ! can_compare_p (code, int_mode, ccp_jump))
    1035                 :            :     {
    1036                 :          0 :       switch (code)
    1037                 :            :         {
    1038                 :          0 :         case LTU:
    1039                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
    1040                 :            :                                         if_false_label, if_true_label, prob);
    1041                 :          0 :           break;
    1042                 :            : 
    1043                 :          0 :         case LEU:
    1044                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
    1045                 :            :                                         if_true_label, if_false_label,
    1046                 :            :                                         prob.invert ());
    1047                 :          0 :           break;
    1048                 :            : 
    1049                 :          0 :         case GTU:
    1050                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
    1051                 :            :                                         if_false_label, if_true_label, prob);
    1052                 :          0 :           break;
    1053                 :            : 
    1054                 :          0 :         case GEU:
    1055                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
    1056                 :            :                                         if_true_label, if_false_label,
    1057                 :            :                                         prob.invert ());
    1058                 :          0 :           break;
    1059                 :            : 
    1060                 :          0 :         case LT:
    1061                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
    1062                 :            :                                         if_false_label, if_true_label, prob);
    1063                 :          0 :           break;
    1064                 :            : 
    1065                 :          0 :         case LE:
    1066                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
    1067                 :            :                                         if_true_label, if_false_label,
    1068                 :            :                                         prob.invert ());
    1069                 :          0 :           break;
    1070                 :            : 
    1071                 :          0 :         case GT:
    1072                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
    1073                 :            :                                         if_false_label, if_true_label, prob);
    1074                 :          0 :           break;
    1075                 :            : 
    1076                 :          0 :         case GE:
    1077                 :          0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
    1078                 :            :                                         if_true_label, if_false_label,
    1079                 :            :                                         prob.invert ());
    1080                 :          0 :           break;
    1081                 :            : 
    1082                 :          0 :         case EQ:
    1083                 :          0 :           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_false_label,
    1084                 :            :                                          if_true_label, prob);
    1085                 :          0 :           break;
    1086                 :            : 
    1087                 :          0 :         case NE:
    1088                 :          0 :           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_true_label,
    1089                 :            :                                          if_false_label,
    1090                 :            :                                          prob.invert ());
    1091                 :          0 :           break;
    1092                 :            : 
    1093                 :          0 :         default:
    1094                 :          0 :           gcc_unreachable ();
    1095                 :            :         }
    1096                 :            :     }
    1097                 :            :   else
    1098                 :            :     {
    1099                 :    3832400 :       if (SCALAR_FLOAT_MODE_P (mode)
    1100                 :     363642 :           && ! can_compare_p (code, mode, ccp_jump)
    1101                 :    4030970 :           && can_compare_p (swap_condition (code), mode, ccp_jump))
    1102                 :            :         {
    1103                 :      17778 :           code = swap_condition (code);
    1104                 :      17778 :           std::swap (op0, op1);
    1105                 :            :         }
    1106                 :    3814630 :       else if (SCALAR_FLOAT_MODE_P (mode)
    1107                 :     345864 :                && ! can_compare_p (code, mode, ccp_jump)
    1108                 :            :                /* Never split ORDERED and UNORDERED.
    1109                 :            :                   These must be implemented.  */
    1110                 :     180786 :                && (code != ORDERED && code != UNORDERED)
    1111                 :            :                /* Split a floating-point comparison if
    1112                 :            :                   we can jump on other conditions...  */
    1113                 :    3989760 :                && (have_insn_for (COMPARE, mode)
    1114                 :            :                    /* ... or if there is no libcall for it.  */
    1115                 :      34366 :                    || code_to_optab (code) == unknown_optab))
    1116                 :            :         {
    1117                 :     145694 :           enum rtx_code first_code;
    1118                 :     145694 :           bool and_them = split_comparison (code, mode, &first_code, &code);
    1119                 :            : 
    1120                 :            :           /* If there are no NaNs, the first comparison should always fall
    1121                 :            :              through.  */
    1122                 :     145694 :           if (!HONOR_NANS (mode))
    1123                 :       1430 :             gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
    1124                 :            : 
    1125                 :            :           else
    1126                 :            :             {
    1127                 :     144970 :               profile_probability cprob
    1128                 :     144970 :                 = profile_probability::guessed_always ();
    1129                 :     144970 :               if (first_code == UNORDERED)
    1130                 :     139494 :                 cprob = cprob.apply_scale (1, 100);
    1131                 :       5476 :               else if (first_code == ORDERED)
    1132                 :       5475 :                 cprob = cprob.apply_scale (99, 100);
    1133                 :            :               else
    1134                 :          1 :                 cprob = profile_probability::even ();
    1135                 :            :               /* We want to split:
    1136                 :            :                  if (x) goto t; // prob;
    1137                 :            :                  into
    1138                 :            :                  if (a) goto t; // first_prob;
    1139                 :            :                  if (b) goto t; // prob;
    1140                 :            :                  such that the overall probability of jumping to t
    1141                 :            :                  remains the same and first_prob is prob * cprob.  */
    1142                 :     144970 :               if (and_them)
    1143                 :            :                 {
    1144                 :       5475 :                   rtx_code_label *dest_label;
    1145                 :       5475 :                   prob = prob.invert ();
    1146                 :       5475 :                   profile_probability first_prob = prob.split (cprob).invert ();
    1147                 :       5475 :                   prob = prob.invert ();
    1148                 :            :                   /* If we only jump if true, just bypass the second jump.  */
    1149                 :       5475 :                   if (! if_false_label)
    1150                 :            :                     {
    1151                 :       2620 :                       if (! dummy_label)
    1152                 :       2620 :                         dummy_label = gen_label_rtx ();
    1153                 :            :                       dest_label = dummy_label;
    1154                 :            :                     }
    1155                 :            :                   else
    1156                 :            :                     dest_label = if_false_label;
    1157                 :       5475 :                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
    1158                 :            :                                            size, dest_label, NULL, first_prob);
    1159                 :            :                 }
    1160                 :            :               else
    1161                 :            :                 {
    1162                 :     139495 :                   profile_probability first_prob = prob.split (cprob);
    1163                 :     139495 :                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
    1164                 :            :                                            size, NULL, if_true_label, first_prob);
    1165                 :            :                 }
    1166                 :            :             }
    1167                 :            :         }
    1168                 :            : 
    1169                 :    3832400 :       emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
    1170                 :            :                                if_true_label, prob);
    1171                 :            :     }
    1172                 :            : 
    1173                 :    3832400 :   if (if_false_label)
    1174                 :      85042 :     emit_jump (if_false_label);
    1175                 :    3832400 :   if (dummy_label)
    1176                 :      87662 :     emit_label (dummy_label);
    1177                 :            : }
    1178                 :            : 
    1179                 :            : /* Generate code for a comparison expression EXP (including code to compute
    1180                 :            :    the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
    1181                 :            :    IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
    1182                 :            :    generated code will drop through.
    1183                 :            :    SIGNED_CODE should be the rtx operation for this comparison for
    1184                 :            :    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
    1185                 :            : 
    1186                 :            :    We force a stack adjustment unless there are currently
    1187                 :            :    things pushed on the stack that aren't yet used.  */
    1188                 :            : 
    1189                 :            : static void
    1190                 :    2107200 : do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
    1191                 :            :                      enum rtx_code unsigned_code,
    1192                 :            :                      rtx_code_label *if_false_label,
    1193                 :            :                      rtx_code_label *if_true_label, profile_probability prob)
    1194                 :            : {
    1195                 :    2107200 :   rtx op0, op1;
    1196                 :    2107200 :   tree type;
    1197                 :    2107200 :   machine_mode mode;
    1198                 :    2107200 :   int unsignedp;
    1199                 :    2107200 :   enum rtx_code code;
    1200                 :            : 
    1201                 :            :   /* Don't crash if the comparison was erroneous.  */
    1202                 :    2107200 :   op0 = expand_normal (treeop0);
    1203                 :    2107200 :   if (TREE_CODE (treeop0) == ERROR_MARK)
    1204                 :            :     return;
    1205                 :            : 
    1206                 :    2107200 :   op1 = expand_normal (treeop1);
    1207                 :    2107200 :   if (TREE_CODE (treeop1) == ERROR_MARK)
    1208                 :            :     return;
    1209                 :            : 
    1210                 :    2107200 :   type = TREE_TYPE (treeop0);
    1211                 :    2107200 :   if (TREE_CODE (treeop0) == INTEGER_CST
    1212                 :    2107200 :       && (TREE_CODE (treeop1) != INTEGER_CST
    1213                 :          0 :           || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type))
    1214                 :          0 :               > GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (treeop1))))))
    1215                 :            :     /* op0 might have been replaced by promoted constant, in which
    1216                 :            :        case the type of second argument should be used.  */
    1217                 :        115 :     type = TREE_TYPE (treeop1);
    1218                 :    2107200 :   mode = TYPE_MODE (type);
    1219                 :    2107200 :   unsignedp = TYPE_UNSIGNED (type);
    1220                 :    2107200 :   code = unsignedp ? unsigned_code : signed_code;
    1221                 :            : 
    1222                 :            :   /* If function pointers need to be "canonicalized" before they can
    1223                 :            :      be reliably compared, then canonicalize them.  Canonicalize the
    1224                 :            :      expression when one of the operands is a function pointer.  This
    1225                 :            :      handles the case where the other operand is a void pointer.  See
    1226                 :            :      PR middle-end/17564.  */
    1227                 :    2107200 :   if (targetm.have_canonicalize_funcptr_for_compare ()
    1228                 :    2107200 :       && ((POINTER_TYPE_P (TREE_TYPE (treeop0))
    1229                 :          0 :            && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))))
    1230                 :          0 :           || (POINTER_TYPE_P (TREE_TYPE (treeop1))
    1231                 :          0 :               && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
    1232                 :            :     {
    1233                 :          0 :       rtx new_op0 = gen_reg_rtx (mode);
    1234                 :          0 :       rtx new_op1 = gen_reg_rtx (mode);
    1235                 :            : 
    1236                 :          0 :       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0));
    1237                 :          0 :       op0 = new_op0;
    1238                 :            : 
    1239                 :          0 :       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
    1240                 :          0 :       op1 = new_op1;
    1241                 :            :     }
    1242                 :            : 
    1243                 :    2107200 :   do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
    1244                 :            :                            ((mode == BLKmode)
    1245                 :          0 :                             ? expr_size (treeop0) : NULL_RTX),
    1246                 :            :                            if_false_label, if_true_label, prob);
    1247                 :            : }
    1248                 :            : 
    1249                 :            : #include "gt-dojump.h"

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.