LCOV - code coverage report
Current view: top level - gcc - dojump.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 54.3 % 611 332
Test Date: 2026-02-28 14:20:25 Functions: 63.6 % 22 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Convert tree expression to rtl instructions, for GNU compiler.
       2              :    Copyright (C) 1988-2026 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      3265429 : discard_pending_stack_adjust (void)
      67              : {
      68      3265429 :   stack_pointer_delta -= pending_stack_adjust;
      69      3265429 :   pending_stack_adjust = 0;
      70      3265429 : }
      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      2293671 : clear_pending_stack_adjust (void)
      80              : {
      81      2293671 :   if (optimize > 0
      82      1660973 :       && (! flag_omit_frame_pointer || cfun->calls_alloca)
      83              :       && EXIT_IGNORE_STACK)
      84        31967 :     discard_pending_stack_adjust ();
      85      2293671 : }
      86              : 
      87              : /* Pop any previously-pushed arguments that have not been popped yet.  */
      88              : 
      89              : void
      90     28419957 : do_pending_stack_adjust (void)
      91              : {
      92     28419957 :   if (inhibit_defer_pop == 0)
      93              :     {
      94     28397500 :       if (maybe_ne (pending_stack_adjust, 0))
      95      1343402 :         adjust_stack (gen_int_mode (pending_stack_adjust, Pmode));
      96     28397500 :       pending_stack_adjust = 0;
      97              :     }
      98     28419957 : }
      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       573068 : save_pending_stack_adjust (saved_pending_stack_adjust *save)
     106              : {
     107       573068 :   save->x_pending_stack_adjust = pending_stack_adjust;
     108       573068 :   save->x_stack_pointer_delta = stack_pointer_delta;
     109       573068 : }
     110              : 
     111              : /* Restore the saved pending_stack_adjust/stack_pointer_delta.  */
     112              : 
     113              : void
     114       194060 : restore_pending_stack_adjust (saved_pending_stack_adjust *save)
     115              : {
     116       194060 :   if (inhibit_defer_pop == 0)
     117              :     {
     118       193971 :       pending_stack_adjust = save->x_pending_stack_adjust;
     119       193971 :       stack_pointer_delta = save->x_stack_pointer_delta;
     120              :     }
     121       194060 : }
     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            0 : }
     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      5672783 : 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      5672783 :   machine_mode mode;
     176      5672783 :   rtx_code_label *drop_through_label = 0;
     177      5672783 :   scalar_int_mode int_mode;
     178              : 
     179      5672783 :   switch (code)
     180              :     {
     181      1608163 :     case EQ_EXPR:
     182      1608163 :       {
     183      1608163 :         tree inner_type = TREE_TYPE (op0);
     184              : 
     185      1608163 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     186              :                     != MODE_COMPLEX_FLOAT);
     187      1608163 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     188              :                     != MODE_COMPLEX_INT);
     189              : 
     190      1608163 :         if (integer_zerop (op1))
     191       773561 :           do_jump (op0, if_true_label, if_false_label,
     192              :                    prob.invert ());
     193       834602 :         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
     194       822543 :                  && !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       834602 :           do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
     199              :                                prob);
     200              :         break;
     201              :       }
     202              : 
     203      2834305 :     case NE_EXPR:
     204      2834305 :       {
     205      2834305 :         tree inner_type = TREE_TYPE (op0);
     206              : 
     207      2834305 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     208              :                     != MODE_COMPLEX_FLOAT);
     209      2834305 :         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
     210              :                     != MODE_COMPLEX_INT);
     211              : 
     212      2834305 :         if (integer_zerop (op1))
     213      1213271 :           do_jump (op0, if_false_label, if_true_label, prob);
     214      1621034 :         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
     215      1441554 :                  && !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      1621034 :           do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
     220              :                                prob);
     221              :         break;
     222              :       }
     223              : 
     224       226070 :     case LT_EXPR:
     225       226070 :       mode = TYPE_MODE (TREE_TYPE (op0));
     226       226070 :       if (is_int_mode (mode, &int_mode)
     227       210965 :           && ! 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       226070 :         do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
     232              :                              prob);
     233              :       break;
     234              : 
     235       215722 :     case LE_EXPR:
     236       215722 :       mode = TYPE_MODE (TREE_TYPE (op0));
     237       215722 :       if (is_int_mode (mode, &int_mode)
     238       209134 :           && ! 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       215722 :         do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
     243              :                              prob);
     244              :       break;
     245              : 
     246       526835 :     case GT_EXPR:
     247       526835 :       mode = TYPE_MODE (TREE_TYPE (op0));
     248       526835 :       if (is_int_mode (mode, &int_mode)
     249       508675 :           && ! 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       526835 :         do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
     254              :                              prob);
     255              :       break;
     256              : 
     257       129400 :     case GE_EXPR:
     258       129400 :       mode = TYPE_MODE (TREE_TYPE (op0));
     259       129400 :       if (is_int_mode (mode, &int_mode)
     260       121851 :           && ! 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       129400 :         do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
     265              :                              prob);
     266              :       break;
     267              : 
     268         2601 :     case ORDERED_EXPR:
     269         2601 :       do_compare_and_jump (op0, op1, ORDERED, ORDERED,
     270              :                            if_false_label, if_true_label, prob);
     271         2601 :       break;
     272              : 
     273         3345 :     case UNORDERED_EXPR:
     274         3345 :       do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
     275              :                            if_false_label, if_true_label, prob);
     276         3345 :       break;
     277              : 
     278          746 :     case UNLT_EXPR:
     279          746 :       do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
     280              :                            prob);
     281          746 :       break;
     282              : 
     283         5600 :     case UNLE_EXPR:
     284         5600 :       do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
     285              :                            prob);
     286         5600 :       break;
     287              : 
     288         3021 :     case UNGT_EXPR:
     289         3021 :       do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
     290              :                            prob);
     291         3021 :       break;
     292              : 
     293         3419 :     case UNGE_EXPR:
     294         3419 :       do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
     295              :                            prob);
     296         3419 :       break;
     297              : 
     298          281 :     case UNEQ_EXPR:
     299          281 :       do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
     300              :                            prob);
     301          281 :       break;
     302              : 
     303            2 :     case LTGT_EXPR:
     304            2 :       do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
     305              :                            prob);
     306            2 :       break;
     307              : 
     308        54898 :     case TRUTH_ANDIF_EXPR:
     309        54898 :       {
     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        54898 :         profile_probability op0_prob = profile_probability::uninitialized ();
     317        54898 :         profile_probability op1_prob = profile_probability::uninitialized ();
     318        54898 :         if (prob.initialized_p ())
     319              :           {
     320        54893 :             op1_prob = prob.invert ();
     321        54893 :             op0_prob = op1_prob.split (profile_probability::even ());
     322              :             /* Get the probability that each jump below is true.  */
     323        54893 :             op0_prob = op0_prob.invert ();
     324        54893 :             op1_prob = op1_prob.invert ();
     325              :           }
     326        54898 :         if (if_false_label == NULL)
     327              :           {
     328        31865 :             drop_through_label = gen_label_rtx ();
     329        31865 :             do_jump (op0, drop_through_label, NULL, op0_prob);
     330        31865 :             do_jump (op1, NULL, if_true_label, op1_prob);
     331              :           }
     332              :         else
     333              :           {
     334        23033 :             do_jump (op0, if_false_label, NULL, op0_prob);
     335        23033 :             do_jump (op1, if_false_label, if_true_label, op1_prob);
     336              :           }
     337        31865 :         break;
     338              :       }
     339              : 
     340        58375 :     case TRUTH_ORIF_EXPR:
     341        58375 :       {
     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        58375 :         profile_probability op0_prob = profile_probability::uninitialized ();
     348        58375 :         profile_probability op1_prob = profile_probability::uninitialized ();
     349        58375 :         if (prob.initialized_p ())
     350              :           {
     351        58354 :             op1_prob = prob;
     352        58354 :             op0_prob = op1_prob.split (profile_probability::even ());
     353              :           }
     354        58375 :         if (if_true_label == NULL)
     355              :           {
     356        21737 :             drop_through_label = gen_label_rtx ();
     357        21737 :             do_jump (op0, NULL, drop_through_label, op0_prob);
     358        21737 :             do_jump (op1, if_false_label, NULL, op1_prob);
     359              :           }
     360              :         else
     361              :           {
     362        36638 :             do_jump (op0, NULL, if_true_label, op0_prob);
     363        36638 :             do_jump (op1, if_false_label, if_true_label, op1_prob);
     364              :           }
     365        21737 :         break;
     366              :       }
     367              : 
     368            0 :     default:
     369            0 :       gcc_unreachable ();
     370              :     }
     371              : 
     372      5672783 :   if (drop_through_label)
     373              :     {
     374        53602 :       do_pending_stack_adjust ();
     375        53602 :       emit_label (drop_through_label);
     376              :     }
     377      5672783 : }
     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      2217144 : do_jump (tree exp, rtx_code_label *if_false_label,
     392              :          rtx_code_label *if_true_label, profile_probability prob)
     393              : {
     394      2217144 :   enum tree_code code = TREE_CODE (exp);
     395      2217144 :   rtx temp;
     396      2217144 :   int i;
     397      2217144 :   tree type;
     398      2217144 :   scalar_int_mode mode;
     399      2217144 :   rtx_code_label *drop_through_label = NULL;
     400              : 
     401      2217144 :   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            0 :                                                   : 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_CONVERT:
     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              :       /* If we are narrowing the operand, we have to do the compare in the
     431              :          narrower mode.  */
     432            0 :       if ((TYPE_PRECISION (TREE_TYPE (exp))
     433            0 :            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
     434            0 :         goto normal;
     435              :       /* FALLTHRU */
     436            0 :     case NON_LVALUE_EXPR:
     437            0 :     case ABS_EXPR:
     438            0 :     case ABSU_EXPR:
     439            0 :     case NEGATE_EXPR:
     440            0 :     case LROTATE_EXPR:
     441            0 :     case RROTATE_EXPR:
     442              :       /* These cannot change zero->nonzero or vice versa.  */
     443            0 :       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
     444              :       break;
     445              : 
     446            0 :     case TRUTH_NOT_EXPR:
     447            0 :       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
     448              :                prob.invert ());
     449            0 :       break;
     450              : 
     451            0 :     case COND_EXPR:
     452            0 :       {
     453            0 :         rtx_code_label *label1 = gen_label_rtx ();
     454            0 :         if (!if_true_label || !if_false_label)
     455              :           {
     456            0 :             drop_through_label = gen_label_rtx ();
     457            0 :             if (!if_true_label)
     458            0 :               if_true_label = drop_through_label;
     459            0 :             if (!if_false_label)
     460            0 :               if_false_label = drop_through_label;
     461              :           }
     462              : 
     463            0 :         do_pending_stack_adjust ();
     464            0 :         do_jump (TREE_OPERAND (exp, 0), label1, NULL,
     465              :                  profile_probability::uninitialized ());
     466            0 :         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
     467            0 :         emit_label (label1);
     468            0 :         do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
     469            0 :         break;
     470              :       }
     471              : 
     472            0 :     case COMPOUND_EXPR:
     473              :       /* Lowered by gimplify.cc.  */
     474            0 :       gcc_unreachable ();
     475              : 
     476            0 :     case MINUS_EXPR:
     477              :       /* Nonzero iff operands of minus differ.  */
     478            0 :       code = NE_EXPR;
     479              : 
     480              :       /* FALLTHRU */
     481            0 :     case EQ_EXPR:
     482            0 :     case NE_EXPR:
     483            0 :     case LT_EXPR:
     484            0 :     case LE_EXPR:
     485            0 :     case GT_EXPR:
     486            0 :     case GE_EXPR:
     487            0 :     case ORDERED_EXPR:
     488            0 :     case UNORDERED_EXPR:
     489            0 :     case UNLT_EXPR:
     490            0 :     case UNLE_EXPR:
     491            0 :     case UNGT_EXPR:
     492            0 :     case UNGE_EXPR:
     493            0 :     case UNEQ_EXPR:
     494            0 :     case LTGT_EXPR:
     495            0 :     case TRUTH_ANDIF_EXPR:
     496            0 :     case TRUTH_ORIF_EXPR:
     497            0 :     other_code:
     498            0 :       do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
     499              :                  if_false_label, if_true_label, prob);
     500            0 :       break;
     501              : 
     502            0 :     case BIT_AND_EXPR:
     503              :       /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
     504              :          See if the former is preferred for jump tests and restore it
     505              :          if so.  */
     506            0 :       if (integer_onep (TREE_OPERAND (exp, 1)))
     507              :         {
     508            0 :           tree exp0 = TREE_OPERAND (exp, 0);
     509            0 :           rtx_code_label *set_label, *clr_label;
     510            0 :           profile_probability setclr_prob = prob;
     511              : 
     512              :           /* Strip narrowing integral type conversions.  */
     513            0 :           while (CONVERT_EXPR_P (exp0)
     514            0 :                  && TREE_OPERAND (exp0, 0) != error_mark_node
     515            0 :                  && TYPE_PRECISION (TREE_TYPE (exp0))
     516            0 :                     <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
     517            0 :             exp0 = TREE_OPERAND (exp0, 0);
     518              : 
     519              :           /* "exp0 ^ 1" inverts the sense of the single bit test.  */
     520            0 :           if (TREE_CODE (exp0) == BIT_XOR_EXPR
     521            0 :               && integer_onep (TREE_OPERAND (exp0, 1)))
     522              :             {
     523            0 :               exp0 = TREE_OPERAND (exp0, 0);
     524            0 :               clr_label = if_true_label;
     525            0 :               set_label = if_false_label;
     526            0 :               setclr_prob = prob.invert ();
     527              :             }
     528              :           else
     529              :             {
     530              :               clr_label = if_false_label;
     531              :               set_label = if_true_label;
     532              :             }
     533              : 
     534            0 :           if (TREE_CODE (exp0) == RSHIFT_EXPR)
     535              :             {
     536            0 :               tree arg = TREE_OPERAND (exp0, 0);
     537            0 :               tree shift = TREE_OPERAND (exp0, 1);
     538            0 :               tree argtype = TREE_TYPE (arg);
     539            0 :               if (TREE_CODE (shift) == INTEGER_CST
     540            0 :                   && compare_tree_int (shift, 0) >= 0
     541            0 :                   && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
     542            0 :                   && prefer_and_bit_test (SCALAR_INT_TYPE_MODE (argtype),
     543            0 :                                           TREE_INT_CST_LOW (shift)))
     544              :                 {
     545            0 :                   unsigned HOST_WIDE_INT mask
     546            0 :                     = HOST_WIDE_INT_1U << TREE_INT_CST_LOW (shift);
     547            0 :                   do_jump (build2 (BIT_AND_EXPR, argtype, arg,
     548            0 :                                    build_int_cstu (argtype, mask)),
     549              :                            clr_label, set_label, setclr_prob);
     550            0 :                   break;
     551              :                 }
     552              :             }
     553              :         }
     554              : 
     555              :       /* If we are AND'ing with a small constant, do this comparison in the
     556              :          smallest type that fits.  If the machine doesn't have comparisons
     557              :          that small, it will be converted back to the wider comparison.
     558              :          This helps if we are testing the sign bit of a narrower object.
     559              :          combine can't do this for us because it can't know whether a
     560              :          ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
     561              : 
     562            0 :       if (! SLOW_BYTE_ACCESS
     563            0 :           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
     564            0 :           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
     565            0 :           && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
     566            0 :           && int_mode_for_size (i + 1, 0).exists (&mode)
     567            0 :           && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
     568            0 :           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
     569            0 :           && have_insn_for (COMPARE, TYPE_MODE (type)))
     570              :         {
     571            0 :           do_jump (fold_convert (type, exp), if_false_label, if_true_label,
     572              :                    prob);
     573              :           break;
     574              :         }
     575              : 
     576            0 :       if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
     577            0 :           || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
     578            0 :         goto normal;
     579              : 
     580              :       /* Boolean comparisons can be compiled as TRUTH_AND_EXPR.  */
     581              :       /* FALLTHRU */
     582              : 
     583            0 :     case TRUTH_AND_EXPR:
     584              :       /* High branch cost, expand as the bitwise AND of the conditions.
     585              :          Do the same if the RHS has side effects, because we're effectively
     586              :          turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR.  */
     587            0 :       if (BRANCH_COST (optimize_insn_for_speed_p (),
     588              :                        false) >= 4
     589            0 :           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
     590            0 :         goto normal;
     591            0 :       code = TRUTH_ANDIF_EXPR;
     592            0 :       goto other_code;
     593              : 
     594            0 :     case BIT_IOR_EXPR:
     595            0 :     case TRUTH_OR_EXPR:
     596              :       /* High branch cost, expand as the bitwise OR of the conditions.
     597              :          Do the same if the RHS has side effects, because we're effectively
     598              :          turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR.  */
     599            0 :       if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
     600            0 :           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
     601            0 :         goto normal;
     602            0 :       code = TRUTH_ORIF_EXPR;
     603            0 :       goto other_code;
     604              : 
     605              :       /* Fall through and generate the normal code.  */
     606      2217143 :     default:
     607      2217143 :     normal:
     608      2217143 :       temp = expand_normal (exp);
     609      2217143 :       do_pending_stack_adjust ();
     610              :       /* The RTL optimizers prefer comparisons against pseudos.  */
     611      2217143 :       if (GET_CODE (temp) == SUBREG)
     612              :         {
     613              :           /* Compare promoted variables in their promoted mode.  */
     614        37298 :           if (SUBREG_PROMOTED_VAR_P (temp)
     615        37298 :               && REG_P (XEXP (temp, 0)))
     616              :             temp = XEXP (temp, 0);
     617              :           else
     618        37298 :             temp = copy_to_reg (temp);
     619              :         }
     620      4434286 :       do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
     621      2217143 :                                NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
     622      2217143 :                                exp, GET_MODE (temp), NULL_RTX,
     623              :                                if_false_label, if_true_label, prob);
     624              :     }
     625              : 
     626      2217143 :   if (drop_through_label)
     627              :     {
     628            0 :       do_pending_stack_adjust ();
     629            0 :       emit_label (drop_through_label);
     630              :     }
     631      2217144 : }
     632              : 
     633              : /* Compare OP0 with OP1, word at a time, in mode MODE.
     634              :    UNSIGNEDP says to do unsigned comparison.
     635              :    Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
     636              : 
     637              : static void
     638            0 : do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0,
     639              :                               rtx op1, rtx_code_label *if_false_label,
     640              :                               rtx_code_label *if_true_label,
     641              :                               profile_probability prob)
     642              : {
     643            0 :   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
     644            0 :   rtx_code_label *drop_through_label = 0;
     645            0 :   bool drop_through_if_true = false, drop_through_if_false = false;
     646            0 :   enum rtx_code code = GT;
     647            0 :   int i;
     648              : 
     649            0 :   if (! if_true_label || ! if_false_label)
     650            0 :     drop_through_label = gen_label_rtx ();
     651            0 :   if (! if_true_label)
     652              :     {
     653            0 :       if_true_label = drop_through_label;
     654            0 :       drop_through_if_true = true;
     655              :     }
     656            0 :   if (! if_false_label)
     657              :     {
     658            0 :       if_false_label = drop_through_label;
     659            0 :       drop_through_if_false = true;
     660              :     }
     661              : 
     662              :   /* Deal with the special case 0 > x: only one comparison is necessary and
     663              :      we reverse it to avoid jumping to the drop-through label.  */
     664            0 :   if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
     665              :     {
     666            0 :       code = LE;
     667            0 :       if_true_label = if_false_label;
     668            0 :       if_false_label = drop_through_label;
     669            0 :       prob = prob.invert ();
     670              :     }
     671              : 
     672              :   /* Compare a word at a time, high order first.  */
     673            0 :   for (i = 0; i < nwords; i++)
     674              :     {
     675            0 :       rtx op0_word, op1_word;
     676              : 
     677            0 :       if (WORDS_BIG_ENDIAN)
     678              :         {
     679              :           op0_word = operand_subword_force (op0, i, mode);
     680              :           op1_word = operand_subword_force (op1, i, mode);
     681              :         }
     682              :       else
     683              :         {
     684            0 :           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
     685            0 :           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
     686              :         }
     687              : 
     688              :       /* All but high-order word must be compared as unsigned.  */
     689            0 :       do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
     690              :                                NULL, word_mode, NULL_RTX, NULL, if_true_label,
     691              :                                prob);
     692              : 
     693              :       /* Emit only one comparison for 0.  Do not emit the last cond jump.  */
     694            0 :       if (op0 == const0_rtx || i == nwords - 1)
     695              :         break;
     696              : 
     697              :       /* Consider lower words only if these are equal.  */
     698            0 :       do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, NULL,
     699              :                                word_mode, NULL_RTX, NULL, if_false_label,
     700              :                                prob.invert ());
     701              :     }
     702              : 
     703            0 :   if (!drop_through_if_false)
     704            0 :     emit_jump (if_false_label);
     705            0 :   if (drop_through_label)
     706            0 :     emit_label (drop_through_label);
     707            0 : }
     708              : 
     709              : /* Given a comparison expression EXP for values too wide to be compared
     710              :    with one insn, test the comparison and jump to the appropriate label.
     711              :    The code of EXP is ignored; we always test GT if SWAP is 0,
     712              :    and LT if SWAP is 1.  MODE is the mode of the two operands.  */
     713              : 
     714              : static void
     715            0 : do_jump_by_parts_greater (scalar_int_mode mode, tree treeop0, tree treeop1,
     716              :                           int swap, rtx_code_label *if_false_label,
     717              :                           rtx_code_label *if_true_label,
     718              :                           profile_probability prob)
     719              : {
     720            0 :   rtx op0 = expand_normal (swap ? treeop1 : treeop0);
     721            0 :   rtx op1 = expand_normal (swap ? treeop0 : treeop1);
     722            0 :   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
     723              : 
     724            0 :   do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
     725              :                                 if_true_label, prob);
     726            0 : }
     727              : 
     728              : /* Jump according to whether OP0 is 0.  We assume that OP0 has an integer
     729              :    mode, MODE, that is too wide for the available compare insns.  Either
     730              :    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL
     731              :    to indicate drop through.  */
     732              : 
     733              : static void
     734            0 : do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0,
     735              :                            rtx_code_label *if_false_label,
     736              :                            rtx_code_label *if_true_label,
     737              :                            profile_probability prob)
     738              : {
     739            0 :   int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
     740            0 :   rtx part;
     741            0 :   int i;
     742            0 :   rtx_code_label *drop_through_label = NULL;
     743              : 
     744              :   /* The fastest way of doing this comparison on almost any machine is to
     745              :      "or" all the words and compare the result.  If all have to be loaded
     746              :      from memory and this is a very wide item, it's possible this may
     747              :      be slower, but that's highly unlikely.  */
     748              : 
     749            0 :   part = gen_reg_rtx (word_mode);
     750            0 :   emit_move_insn (part, operand_subword_force (op0, 0, mode));
     751            0 :   for (i = 1; i < nwords && part != 0; i++)
     752            0 :     part = expand_binop (word_mode, ior_optab, part,
     753            0 :                          operand_subword_force (op0, i, mode),
     754              :                          part, 1, OPTAB_WIDEN);
     755              : 
     756            0 :   if (part != 0)
     757              :     {
     758            0 :       do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, NULL, word_mode,
     759              :                                NULL_RTX, if_false_label, if_true_label, prob);
     760            0 :       return;
     761              :     }
     762              : 
     763              :   /* If we couldn't do the "or" simply, do this with a series of compares.  */
     764            0 :   if (! if_false_label)
     765            0 :     if_false_label = drop_through_label = gen_label_rtx ();
     766              : 
     767            0 :   for (i = 0; i < nwords; i++)
     768            0 :     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
     769              :                              const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX,
     770              :                              if_false_label, NULL, prob);
     771              : 
     772            0 :   if (if_true_label)
     773            0 :     emit_jump (if_true_label);
     774              : 
     775            0 :   if (drop_through_label)
     776            0 :     emit_label (drop_through_label);
     777              : }
     778              : 
     779              : /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
     780              :    where MODE is an integer mode too wide to be compared with one insn.
     781              :    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
     782              :    to indicate drop through.  */
     783              : 
     784              : static void
     785            0 : do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1,
     786              :                                rtx_code_label *if_false_label,
     787              :                                rtx_code_label *if_true_label,
     788              :                                profile_probability prob)
     789              : {
     790            0 :   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
     791            0 :   rtx_code_label *drop_through_label = NULL;
     792            0 :   int i;
     793              : 
     794            0 :   if (op1 == const0_rtx)
     795              :     {
     796            0 :       do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
     797              :                                  prob);
     798            0 :       return;
     799              :     }
     800            0 :   else if (op0 == const0_rtx)
     801              :     {
     802            0 :       do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
     803              :                                  prob);
     804            0 :       return;
     805              :     }
     806              : 
     807            0 :   if (! if_false_label)
     808            0 :     drop_through_label = if_false_label = gen_label_rtx ();
     809              : 
     810            0 :   for (i = 0; i < nwords; i++)
     811            0 :     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
     812            0 :                              operand_subword_force (op1, i, mode),
     813              :                              EQ, 0, NULL, word_mode, NULL_RTX,
     814              :                              if_false_label, NULL, prob);
     815              : 
     816            0 :   if (if_true_label)
     817            0 :     emit_jump (if_true_label);
     818            0 :   if (drop_through_label)
     819            0 :     emit_label (drop_through_label);
     820              : }
     821              : 
     822              : /* Given an EQ_EXPR expression EXP for values too wide to be compared
     823              :    with one insn, test the comparison and jump to the appropriate label.
     824              :    MODE is the mode of the two operands.  */
     825              : 
     826              : static void
     827            0 : do_jump_by_parts_equality (scalar_int_mode mode, tree treeop0, tree treeop1,
     828              :                            rtx_code_label *if_false_label,
     829              :                            rtx_code_label *if_true_label,
     830              :                            profile_probability prob)
     831              : {
     832            0 :   rtx op0 = expand_normal (treeop0);
     833            0 :   rtx op1 = expand_normal (treeop1);
     834            0 :   do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
     835              :                                  if_true_label, prob);
     836            0 : }
     837              : 
     838              : /* Split a comparison into two others, the second of which has the other
     839              :    "orderedness".  The first is always ORDERED or UNORDERED if MODE
     840              :    does not honor NaNs (which means that it can be skipped in that case;
     841              :    see do_compare_rtx_and_jump).
     842              : 
     843              :    The two conditions are written in *CODE1 and *CODE2.  Return true if
     844              :    the conditions must be ANDed, false if they must be ORed.  */
     845              : 
     846              : bool
     847       238198 : split_comparison (enum rtx_code code, machine_mode mode,
     848              :                   enum rtx_code *code1, enum rtx_code *code2)
     849              : {
     850       238198 :   switch (code)
     851              :     {
     852           57 :     case LT:
     853           57 :       *code1 = ORDERED;
     854           57 :       *code2 = UNLT;
     855           57 :       return true;
     856          150 :     case LE:
     857          150 :       *code1 = ORDERED;
     858          150 :       *code2 = UNLE;
     859          150 :       return true;
     860           39 :     case GT:
     861           39 :       *code1 = ORDERED;
     862           39 :       *code2 = UNGT;
     863           39 :       return true;
     864          148 :     case GE:
     865          148 :       *code1 = ORDERED;
     866          148 :       *code2 = UNGE;
     867          148 :       return true;
     868        11582 :     case EQ:
     869        11582 :       *code1 = ORDERED;
     870        11582 :       *code2 = UNEQ;
     871        11582 :       return true;
     872       219346 :     case NE:
     873       219346 :       *code1 = UNORDERED;
     874       219346 :       *code2 = LTGT;
     875       219346 :       return false;
     876          207 :     case UNLT:
     877          207 :       *code1 = UNORDERED;
     878          207 :       *code2 = LT;
     879          207 :       return false;
     880         3383 :     case UNLE:
     881         3383 :       *code1 = UNORDERED;
     882         3383 :       *code2 = LE;
     883         3383 :       return false;
     884          699 :     case UNGT:
     885          699 :       *code1 = UNORDERED;
     886          699 :       *code2 = GT;
     887          699 :       return false;
     888         2550 :     case UNGE:
     889         2550 :       *code1 = UNORDERED;
     890         2550 :       *code2 = GE;
     891         2550 :       return false;
     892           36 :     case UNEQ:
     893           36 :       *code1 = UNORDERED;
     894           36 :       *code2 = EQ;
     895           36 :       return false;
     896            1 :     case LTGT:
     897              :       /* Do not turn a trapping comparison into a non-trapping one.  */
     898            1 :       if (HONOR_NANS (mode))
     899              :         {
     900            1 :           *code1 = LT;
     901            1 :           *code2 = GT;
     902            1 :           return false;
     903              :         }
     904              :       else
     905              :         {
     906            0 :           *code1 = ORDERED;
     907            0 :           *code2 = NE;
     908            0 :           return true;
     909              :         }
     910            0 :     default:
     911            0 :       gcc_unreachable ();
     912              :     }
     913              : }
     914              : 
     915              : /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.
     916              :    PROB is probability of jump to LABEL.  */
     917              : 
     918              : void
     919            0 : jumpif (tree exp, rtx_code_label *label, profile_probability prob)
     920              : {
     921            0 :   do_jump (exp, NULL, label, prob);
     922            0 : }
     923              : 
     924              : /* Similar to jumpif but dealing with exploded comparisons of the type
     925              :    OP0 CODE OP1 .  LABEL and PROB are like in jumpif.  */
     926              : 
     927              : void
     928      2669964 : jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
     929              :           profile_probability prob)
     930              : {
     931      2669964 :   do_jump_1 (code, op0, op1, NULL, label, prob);
     932      2669964 : }
     933              : 
     934              : /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
     935              :    PROB is probability of jump to LABEL.  */
     936              : 
     937              : void
     938         3766 : jumpifnot (tree exp, rtx_code_label *label, profile_probability prob)
     939              : {
     940         3766 :   do_jump (exp, label, NULL, prob.invert ());
     941         3766 : }
     942              : 
     943              : /* Similar to jumpifnot but dealing with exploded comparisons of the type
     944              :    OP0 CODE OP1 .  LABEL and PROB are like in jumpifnot.  */
     945              : 
     946              : void
     947      3002819 : jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
     948              :              profile_probability prob)
     949              : {
     950      3002819 :   do_jump_1 (code, op0, op1, label, NULL, prob.invert ());
     951      3002819 : }
     952              : 
     953              : /* Like do_compare_and_jump but expects the values to compare as two rtx's.
     954              :    The decision as to signed or unsigned comparison must be made by the caller.
     955              : 
     956              :    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
     957              :    compared.  */
     958              : 
     959              : void
     960       243769 : do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
     961              :                          machine_mode mode, rtx size,
     962              :                          rtx_code_label *if_false_label,
     963              :                          rtx_code_label *if_true_label,
     964              :                          profile_probability prob)
     965              : {
     966       243769 :   do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size,
     967              :                           if_false_label, if_true_label, prob);
     968       243769 : }
     969              : 
     970              : /* Like do_compare_and_jump but expects the values to compare as two rtx's.
     971              :    The decision as to signed or unsigned comparison must be made by the caller.
     972              : 
     973              :    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
     974              :    compared.  */
     975              : 
     976              : void
     977      6202173 : do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
     978              :                          tree val, machine_mode mode, rtx size,
     979              :                          rtx_code_label *if_false_label,
     980              :                          rtx_code_label *if_true_label,
     981              :                          profile_probability prob)
     982              : {
     983      6202173 :   rtx tem;
     984      6202173 :   rtx_code_label *dummy_label = NULL;
     985              : 
     986              :   /* Reverse the comparison if that is safe and we want to jump if it is
     987              :      false.  Also convert to the reverse comparison if the target can
     988              :      implement it.  */
     989      6202173 :   if ((! if_true_label
     990      3372015 :        || ! can_compare_p (code, mode, ccp_jump))
     991      6344414 :       && (! FLOAT_MODE_P (mode)
     992       261836 :           || code == ORDERED || code == UNORDERED
     993       243735 :           || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
     994       243735 :           || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
     995              :     {
     996      2919522 :       enum rtx_code rcode;
     997      2919522 :       if (FLOAT_MODE_P (mode))
     998       208959 :         rcode = reverse_condition_maybe_unordered (code);
     999              :       else
    1000      2710563 :         rcode = reverse_condition (code);
    1001              : 
    1002              :       /* Canonicalize to UNORDERED for the libcall.  */
    1003      2919522 :       if (can_compare_p (rcode, mode, ccp_jump)
    1004      2919522 :           || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
    1005              :         {
    1006      2723636 :           std::swap (if_true_label, if_false_label);
    1007      2723636 :           code = rcode;
    1008      2723636 :           prob = prob.invert ();
    1009              :         }
    1010              :     }
    1011              : 
    1012              :   /* If one operand is constant, make it the second one.  Only do this
    1013              :      if the other operand is not constant as well.  */
    1014              : 
    1015      6202173 :   if (swap_commutative_operands_p (op0, op1))
    1016              :     {
    1017        31466 :       std::swap (op0, op1);
    1018        31466 :       code = swap_condition (code);
    1019              :     }
    1020              : 
    1021      6202173 :   do_pending_stack_adjust ();
    1022              : 
    1023      6202173 :   code = unsignedp ? unsigned_condition (code) : code;
    1024      6202173 :   if ((tem = simplify_relational_operation (code, mode, VOIDmode,
    1025              :                                             op0, op1)) != 0)
    1026              :     {
    1027         4169 :       if (CONSTANT_P (tem))
    1028              :         {
    1029         6466 :           rtx_code_label *label = (tem == const0_rtx
    1030         1039 :                                    || tem == CONST0_RTX (mode))
    1031         3233 :                                         ? if_false_label : if_true_label;
    1032         3233 :           if (label)
    1033          921 :             emit_jump (label);
    1034         3233 :           return;
    1035              :         }
    1036              : 
    1037          936 :       code = GET_CODE (tem);
    1038          936 :       mode = GET_MODE (tem);
    1039          936 :       op0 = XEXP (tem, 0);
    1040          936 :       op1 = XEXP (tem, 1);
    1041          936 :       unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
    1042              :     }
    1043              : 
    1044      6198940 :   if (! if_true_label)
    1045       106779 :     dummy_label = if_true_label = gen_label_rtx ();
    1046              : 
    1047      6198940 :   scalar_int_mode int_mode;
    1048      6198940 :   if (is_int_mode (mode, &int_mode)
    1049      5744980 :       && ! can_compare_p (code, int_mode, ccp_jump))
    1050              :     {
    1051            0 :       switch (code)
    1052              :         {
    1053            0 :         case LTU:
    1054            0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
    1055              :                                         if_false_label, if_true_label, prob);
    1056            0 :           break;
    1057              : 
    1058            0 :         case LEU:
    1059            0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
    1060              :                                         if_true_label, if_false_label,
    1061              :                                         prob.invert ());
    1062            0 :           break;
    1063              : 
    1064            0 :         case GTU:
    1065            0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
    1066              :                                         if_false_label, if_true_label, prob);
    1067            0 :           break;
    1068              : 
    1069            0 :         case GEU:
    1070            0 :           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
    1071              :                                         if_true_label, if_false_label,
    1072              :                                         prob.invert ());
    1073            0 :           break;
    1074              : 
    1075            0 :         case LT:
    1076            0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
    1077              :                                         if_false_label, if_true_label, prob);
    1078            0 :           break;
    1079              : 
    1080            0 :         case LE:
    1081            0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
    1082              :                                         if_true_label, if_false_label,
    1083              :                                         prob.invert ());
    1084            0 :           break;
    1085              : 
    1086            0 :         case GT:
    1087            0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
    1088              :                                         if_false_label, if_true_label, prob);
    1089            0 :           break;
    1090              : 
    1091            0 :         case GE:
    1092            0 :           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
    1093              :                                         if_true_label, if_false_label,
    1094              :                                         prob.invert ());
    1095            0 :           break;
    1096              : 
    1097            0 :         case EQ:
    1098            0 :           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_false_label,
    1099              :                                          if_true_label, prob);
    1100            0 :           break;
    1101              : 
    1102            0 :         case NE:
    1103            0 :           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_true_label,
    1104              :                                          if_false_label,
    1105              :                                          prob.invert ());
    1106            0 :           break;
    1107              : 
    1108            0 :         default:
    1109            0 :           gcc_unreachable ();
    1110              :         }
    1111              :     }
    1112              :   else
    1113              :     {
    1114      6198940 :       if (SCALAR_FLOAT_MODE_P (mode)
    1115       434765 :           && ! can_compare_p (code, mode, ccp_jump)
    1116      6433911 :           && can_compare_p (swap_condition (code), mode, ccp_jump))
    1117              :         {
    1118        24587 :           code = swap_condition (code);
    1119        24587 :           std::swap (op0, op1);
    1120              :         }
    1121      6174353 :       else if (SCALAR_FLOAT_MODE_P (mode)
    1122       410178 :                && ! can_compare_p (code, mode, ccp_jump)
    1123              :                /* Never split ORDERED and UNORDERED.
    1124              :                   These must be implemented.  */
    1125       210384 :                && (code != ORDERED && code != UNORDERED)
    1126              :                /* Split a floating-point comparison if
    1127              :                   we can jump on other conditions...  */
    1128      6379127 :                && (have_insn_for (COMPARE, mode)
    1129              :                    /* ... or if there is no libcall for it.  */
    1130        38572 :                    || code_to_optab (code) == unknown_optab))
    1131              :         {
    1132       170941 :           enum rtx_code first_code, orig_code = code;
    1133       170941 :           bool and_them = split_comparison (code, mode, &first_code, &code);
    1134              : 
    1135              :           /* If there are no NaNs, the first comparison should always fall
    1136              :              through.  */
    1137       170941 :           if (!HONOR_NANS (mode))
    1138         1662 :             gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
    1139              : 
    1140       170097 :           else if ((orig_code == EQ || orig_code == NE)
    1141       170097 :                    && rtx_equal_p (op0, op1))
    1142              :             /* Self-comparisons x == x or x != x can be optimized into
    1143              :                just x ord x or x nord x.  */
    1144         2639 :             code = orig_code == EQ ? ORDERED : UNORDERED;
    1145              : 
    1146              :           else
    1147              :             {
    1148       168583 :               profile_probability cprob
    1149       168583 :                 = profile_probability::guessed_always ();
    1150       168583 :               if (first_code == UNORDERED)
    1151       159899 :                 cprob /= 100;
    1152         8684 :               else if (first_code == ORDERED)
    1153         8683 :                 cprob = cprob.apply_scale (99, 100);
    1154              :               else
    1155            1 :                 cprob = profile_probability::even ();
    1156              :               /* For and_them we want to split:
    1157              :                  if (x) goto t; // prob;
    1158              :                  goto f;
    1159              :                  into
    1160              :                  if (a) ; else goto f; // first_prob for ;
    1161              :                                        // 1 - first_prob for goto f;
    1162              :                  if (b) goto t; // adjusted prob;
    1163              :                  goto f;
    1164              :                  such that the overall probability of jumping to t
    1165              :                  remains the same.  The and_them case should be
    1166              :                  probability-wise equivalent to the !and_them case with
    1167              :                  f and t swapped and also the conditions inverted, i.e.
    1168              :                  if (!a) goto f;
    1169              :                  if (!b) goto f;
    1170              :                  goto t;
    1171              :                  where the overall probability of jumping to f is
    1172              :                  1 - prob (thus the first prob.invert () below).
    1173              :                  cprob.invert () is because the a condition is inverted,
    1174              :                  so if it was originally ORDERED, !a is UNORDERED and
    1175              :                  thus should be relative 1% rather than 99%.
    1176              :                  The invert () on assignment to first_prob is because
    1177              :                  first_prob represents the probability of fallthru,
    1178              :                  rather than goto f.  And the last prob.invert () is
    1179              :                  because the adjusted prob represents the probability of
    1180              :                  jumping to t rather than to f.  */
    1181       168583 :               if (and_them)
    1182              :                 {
    1183         8683 :                   rtx_code_label *dest_label;
    1184         8683 :                   prob = prob.invert ();
    1185         8683 :                   profile_probability first_prob
    1186         8683 :                     = prob.split (cprob.invert ()).invert ();
    1187         8683 :                   prob = prob.invert ();
    1188              :                   /* If we only jump if true, just bypass the second jump.  */
    1189         8683 :                   if (! if_false_label)
    1190              :                     {
    1191         3928 :                       if (! dummy_label)
    1192         3928 :                         dummy_label = gen_label_rtx ();
    1193              :                       dest_label = dummy_label;
    1194              :                     }
    1195              :                   else
    1196              :                     dest_label = if_false_label;
    1197              : 
    1198         8683 :                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
    1199              :                                            val, mode, size, dest_label, NULL,
    1200              :                                            first_prob);
    1201              :                 }
    1202              :               /* For !and_them we want to split:
    1203              :                  if (x) goto t; // prob;
    1204              :                  goto f;
    1205              :                  into
    1206              :                  if (a) goto t; // first_prob;
    1207              :                  if (b) goto t; // adjusted prob;
    1208              :                  goto f;
    1209              :                  such that the overall probability of jumping to t
    1210              :                  remains the same and first_prob is prob * cprob.  */
    1211              :               else
    1212              :                 {
    1213       159900 :                   profile_probability first_prob = prob.split (cprob);
    1214       159900 :                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
    1215              :                                            val, mode, size, NULL,
    1216              :                                            if_true_label, first_prob);
    1217       159900 :                   if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump))
    1218              :                     {
    1219              :                       /* x != y can be split into x unord y || x ltgt y
    1220              :                          or x unord y || !(x uneq y).  The latter has the
    1221              :                          advantage that both comparisons are non-signalling and
    1222              :                          so there is a higher chance that the RTL optimizations
    1223              :                          merge the two comparisons into just one.  */
    1224       155161 :                       code = UNEQ;
    1225       155161 :                       prob = prob.invert ();
    1226       155161 :                       if (! if_false_label)
    1227              :                         {
    1228        95107 :                           if (! dummy_label)
    1229        95107 :                             dummy_label = gen_label_rtx ();
    1230              :                           if_false_label = dummy_label;
    1231              :                         }
    1232              :                       std::swap (if_false_label, if_true_label);
    1233              :                     }
    1234              :                 }
    1235              :             }
    1236              :         }
    1237              : 
    1238              :       /* For boolean vectors with less than mode precision
    1239              :          make sure to fill padding with consistent values.  */
    1240      6198940 :       if (val
    1241      5955330 :           && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (val))
    1242      6201474 :           && SCALAR_INT_MODE_P (mode))
    1243              :         {
    1244          898 :           auto nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (val)).to_constant ();
    1245          898 :           if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
    1246              :             {
    1247          159 :               op0 = expand_binop (mode, and_optab, op0,
    1248          159 :                                   GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
    1249              :                                   NULL_RTX, true, OPTAB_WIDEN);
    1250          159 :               op1 = expand_binop (mode, and_optab, op1,
    1251              :                                   GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
    1252              :                                   NULL_RTX, true, OPTAB_WIDEN);
    1253              :             }
    1254              :         }
    1255              : 
    1256      6198940 :       emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val,
    1257              :                                if_true_label, prob);
    1258              :     }
    1259              : 
    1260      6198940 :   if (if_false_label)
    1261       201886 :     emit_jump (if_false_label);
    1262      6198940 :   if (dummy_label)
    1263       205814 :     emit_label (dummy_label);
    1264              : }
    1265              : 
    1266              : /* Generate code for a comparison expression EXP (including code to compute
    1267              :    the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
    1268              :    IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
    1269              :    generated code will drop through.
    1270              :    SIGNED_CODE should be the rtx operation for this comparison for
    1271              :    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
    1272              : 
    1273              :    We force a stack adjustment unless there are currently
    1274              :    things pushed on the stack that aren't yet used.  */
    1275              : 
    1276              : static void
    1277      3572678 : do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
    1278              :                      enum rtx_code unsigned_code,
    1279              :                      rtx_code_label *if_false_label,
    1280              :                      rtx_code_label *if_true_label, profile_probability prob)
    1281              : {
    1282      3572678 :   rtx op0, op1;
    1283      3572678 :   tree type;
    1284      3572678 :   machine_mode mode;
    1285      3572678 :   int unsignedp;
    1286      3572678 :   enum rtx_code code;
    1287              : 
    1288              :   /* Don't crash if the comparison was erroneous.  */
    1289      3572678 :   op0 = expand_normal (treeop0);
    1290      3572678 :   if (TREE_CODE (treeop0) == ERROR_MARK)
    1291              :     return;
    1292              : 
    1293      3572678 :   op1 = expand_normal (treeop1);
    1294      3572678 :   if (TREE_CODE (treeop1) == ERROR_MARK)
    1295              :     return;
    1296              : 
    1297      3572678 :   type = TREE_TYPE (treeop0);
    1298      3572678 :   if (TREE_CODE (treeop0) == INTEGER_CST
    1299      3572678 :       && (TREE_CODE (treeop1) != INTEGER_CST
    1300            0 :           || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type))
    1301      3572231 :               > GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (treeop1))))))
    1302              :     /* op0 might have been replaced by promoted constant, in which
    1303              :        case the type of second argument should be used.  */
    1304          447 :     type = TREE_TYPE (treeop1);
    1305      3572678 :   mode = TYPE_MODE (type);
    1306      3572678 :   unsignedp = TYPE_UNSIGNED (type);
    1307      3572678 :   code = unsignedp ? unsigned_code : signed_code;
    1308              : 
    1309              :   /* If function pointers need to be "canonicalized" before they can
    1310              :      be reliably compared, then canonicalize them.  Canonicalize the
    1311              :      expression when one of the operands is a function pointer.  This
    1312              :      handles the case where the other operand is a void pointer.  See
    1313              :      PR middle-end/17564.  */
    1314      3572678 :   if (targetm.have_canonicalize_funcptr_for_compare ()
    1315      3572678 :       && ((POINTER_TYPE_P (TREE_TYPE (treeop0))
    1316            0 :            && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))))
    1317            0 :           || (POINTER_TYPE_P (TREE_TYPE (treeop1))
    1318            0 :               && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
    1319              :     {
    1320            0 :       rtx new_op0 = gen_reg_rtx (mode);
    1321            0 :       rtx new_op1 = gen_reg_rtx (mode);
    1322              : 
    1323            0 :       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0));
    1324            0 :       op0 = new_op0;
    1325              : 
    1326            0 :       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
    1327            0 :       op1 = new_op1;
    1328              :     }
    1329              : 
    1330      3572678 :   do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode,
    1331              :                            ((mode == BLKmode)
    1332            0 :                             ? expr_size (treeop0) : NULL_RTX),
    1333              :                            if_false_label, if_true_label, prob);
    1334              : }
    1335              : 
    1336              : #include "gt-dojump.h"
        

Generated by: LCOV version 2.4-beta

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,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.