analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / dojump.cc
1 /* Convert tree expression to rtl instructions, for GNU compiler.
2    Copyright (C) 1988-2022 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 init_pending_stack_adjust (void)
58 {
59   pending_stack_adjust = 0;
60 }
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 discard_pending_stack_adjust (void)
67 {
68   stack_pointer_delta -= pending_stack_adjust;
69   pending_stack_adjust = 0;
70 }
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 clear_pending_stack_adjust (void)
80 {
81   if (optimize > 0
82       && (! flag_omit_frame_pointer || cfun->calls_alloca)
83       && EXIT_IGNORE_STACK)
84     discard_pending_stack_adjust ();
85 }
86
87 /* Pop any previously-pushed arguments that have not been popped yet.  */
88
89 void
90 do_pending_stack_adjust (void)
91 {
92   if (inhibit_defer_pop == 0)
93     {
94       if (maybe_ne (pending_stack_adjust, 0))
95         adjust_stack (gen_int_mode (pending_stack_adjust, Pmode));
96       pending_stack_adjust = 0;
97     }
98 }
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 save_pending_stack_adjust (saved_pending_stack_adjust *save)
106 {
107   save->x_pending_stack_adjust = pending_stack_adjust;
108   save->x_stack_pointer_delta = stack_pointer_delta;
109 }
110
111 /* Restore the saved pending_stack_adjust/stack_pointer_delta.  */
112
113 void
114 restore_pending_stack_adjust (saved_pending_stack_adjust *save)
115 {
116   if (inhibit_defer_pop == 0)
117     {
118       pending_stack_adjust = save->x_pending_stack_adjust;
119       stack_pointer_delta = save->x_stack_pointer_delta;
120     }
121 }
122 \f
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 prefer_and_bit_test (scalar_int_mode mode, int bitnum)
135 {
136   bool speed_p;
137   wide_int mask = wi::set_bit_in_zero (bitnum, GET_MODE_PRECISION (mode));
138
139   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       and_reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
144       and_test = gen_rtx_AND (mode, and_reg, NULL);
145       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       PUT_MODE (and_reg, mode);
152       PUT_MODE (and_test, mode);
153       PUT_MODE (shift_test, mode);
154       PUT_MODE (XEXP (shift_test, 0), mode);
155     }
156
157   /* Fill in the integers.  */
158   XEXP (and_test, 1) = immed_wide_int_const (mask, mode);
159   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
160
161   speed_p = optimize_insn_for_speed_p ();
162   return (rtx_cost (and_test, mode, IF_THEN_ELSE, 0, speed_p)
163           <= 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 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   machine_mode mode;
176   rtx_code_label *drop_through_label = 0;
177   scalar_int_mode int_mode;
178
179   switch (code)
180     {
181     case EQ_EXPR:
182       {
183         tree inner_type = TREE_TYPE (op0);
184
185         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
186                     != MODE_COMPLEX_FLOAT);
187         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
188                     != MODE_COMPLEX_INT);
189
190         if (integer_zerop (op1))
191           do_jump (op0, if_true_label, if_false_label,
192                    prob.invert ());
193         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
194                  && !can_compare_p (EQ, int_mode, ccp_jump))
195           do_jump_by_parts_equality (int_mode, op0, op1, if_false_label,
196                                      if_true_label, prob);
197         else
198           do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
199                                prob);
200         break;
201       }
202
203     case NE_EXPR:
204       {
205         tree inner_type = TREE_TYPE (op0);
206
207         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
208                     != MODE_COMPLEX_FLOAT);
209         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
210                     != MODE_COMPLEX_INT);
211
212         if (integer_zerop (op1))
213           do_jump (op0, if_false_label, if_true_label, prob);
214         else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
215                  && !can_compare_p (NE, int_mode, ccp_jump))
216           do_jump_by_parts_equality (int_mode, op0, op1, if_true_label,
217                                      if_false_label, prob.invert ());
218         else
219           do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
220                                prob);
221         break;
222       }
223
224     case LT_EXPR:
225       mode = TYPE_MODE (TREE_TYPE (op0));
226       if (is_int_mode (mode, &int_mode)
227           && ! can_compare_p (LT, int_mode, ccp_jump))
228         do_jump_by_parts_greater (int_mode, op0, op1, 1, if_false_label,
229                                   if_true_label, prob);
230       else
231         do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
232                              prob);
233       break;
234
235     case LE_EXPR:
236       mode = TYPE_MODE (TREE_TYPE (op0));
237       if (is_int_mode (mode, &int_mode)
238           && ! can_compare_p (LE, int_mode, ccp_jump))
239         do_jump_by_parts_greater (int_mode, op0, op1, 0, if_true_label,
240                                   if_false_label, prob.invert ());
241       else
242         do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
243                              prob);
244       break;
245
246     case GT_EXPR:
247       mode = TYPE_MODE (TREE_TYPE (op0));
248       if (is_int_mode (mode, &int_mode)
249           && ! can_compare_p (GT, int_mode, ccp_jump))
250         do_jump_by_parts_greater (int_mode, op0, op1, 0, if_false_label,
251                                   if_true_label, prob);
252       else
253         do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
254                              prob);
255       break;
256
257     case GE_EXPR:
258       mode = TYPE_MODE (TREE_TYPE (op0));
259       if (is_int_mode (mode, &int_mode)
260           && ! can_compare_p (GE, int_mode, ccp_jump))
261         do_jump_by_parts_greater (int_mode, op0, op1, 1, if_true_label,
262                                   if_false_label, prob.invert ());
263       else
264         do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
265                              prob);
266       break;
267
268     case ORDERED_EXPR:
269       do_compare_and_jump (op0, op1, ORDERED, ORDERED,
270                            if_false_label, if_true_label, prob);
271       break;
272
273     case UNORDERED_EXPR:
274       do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
275                            if_false_label, if_true_label, prob);
276       break;
277
278     case UNLT_EXPR:
279       do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
280                            prob);
281       break;
282
283     case UNLE_EXPR:
284       do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
285                            prob);
286       break;
287
288     case UNGT_EXPR:
289       do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
290                            prob);
291       break;
292
293     case UNGE_EXPR:
294       do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
295                            prob);
296       break;
297
298     case UNEQ_EXPR:
299       do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
300                            prob);
301       break;
302
303     case LTGT_EXPR:
304       do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
305                            prob);
306       break;
307
308     case TRUTH_ANDIF_EXPR:
309       {
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         profile_probability op0_prob = profile_probability::uninitialized ();
317         profile_probability op1_prob = profile_probability::uninitialized ();
318         if (prob.initialized_p ())
319           {
320             op1_prob = prob.invert ();
321             op0_prob = op1_prob.split (profile_probability::even ());
322             /* Get the probability that each jump below is true.  */
323             op0_prob = op0_prob.invert ();
324             op1_prob = op1_prob.invert ();
325           }
326         if (if_false_label == NULL)
327           {
328             drop_through_label = gen_label_rtx ();
329             do_jump (op0, drop_through_label, NULL, op0_prob);
330             do_jump (op1, NULL, if_true_label, op1_prob);
331           }
332         else
333           {
334             do_jump (op0, if_false_label, NULL, op0_prob);
335             do_jump (op1, if_false_label, if_true_label, op1_prob);
336           }
337         break;
338       }
339
340     case TRUTH_ORIF_EXPR:
341       {
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         profile_probability op0_prob = profile_probability::uninitialized ();
348         profile_probability op1_prob = profile_probability::uninitialized ();
349         if (prob.initialized_p ())
350           {
351             op1_prob = prob;
352             op0_prob = op1_prob.split (profile_probability::even ());
353           }
354         if (if_true_label == NULL)
355           {
356             drop_through_label = gen_label_rtx ();
357             do_jump (op0, NULL, drop_through_label, op0_prob);
358             do_jump (op1, if_false_label, NULL, op1_prob);
359           }
360         else
361           {
362             do_jump (op0, NULL, if_true_label, op0_prob);
363             do_jump (op1, if_false_label, if_true_label, op1_prob);
364           }
365         break;
366       }
367
368     default:
369       gcc_unreachable ();
370     }
371
372   if (drop_through_label)
373     {
374       do_pending_stack_adjust ();
375       emit_label (drop_through_label);
376     }
377 }
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 do_jump (tree exp, rtx_code_label *if_false_label,
392          rtx_code_label *if_true_label, profile_probability prob)
393 {
394   enum tree_code code = TREE_CODE (exp);
395   rtx temp;
396   int i;
397   tree type;
398   scalar_int_mode mode;
399   rtx_code_label *drop_through_label = NULL;
400
401   switch (code)
402     {
403     case ERROR_MARK:
404       break;
405
406     case INTEGER_CST:
407       {
408         rtx_code_label *lab = integer_zerop (exp) ? if_false_label
409                                                   : if_true_label;
410         if (lab)
411           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     CASE_CONVERT:
425       if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
426           || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
427           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
428           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
429         goto normal;
430       /* If we are narrowing the operand, we have to do the compare in the
431          narrower mode.  */
432       if ((TYPE_PRECISION (TREE_TYPE (exp))
433            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
434         goto normal;
435       /* FALLTHRU */
436     case NON_LVALUE_EXPR:
437     case ABS_EXPR:
438     case ABSU_EXPR:
439     case NEGATE_EXPR:
440     case LROTATE_EXPR:
441     case RROTATE_EXPR:
442       /* These cannot change zero->nonzero or vice versa.  */
443       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
444       break;
445
446     case TRUTH_NOT_EXPR:
447       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
448                prob.invert ());
449       break;
450
451     case COND_EXPR:
452       {
453         rtx_code_label *label1 = gen_label_rtx ();
454         if (!if_true_label || !if_false_label)
455           {
456             drop_through_label = gen_label_rtx ();
457             if (!if_true_label)
458               if_true_label = drop_through_label;
459             if (!if_false_label)
460               if_false_label = drop_through_label;
461           }
462
463         do_pending_stack_adjust ();
464         do_jump (TREE_OPERAND (exp, 0), label1, NULL,
465                  profile_probability::uninitialized ());
466         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
467         emit_label (label1);
468         do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
469         break;
470       }
471
472     case COMPOUND_EXPR:
473       /* Lowered by gimplify.cc.  */
474       gcc_unreachable ();
475
476     case MINUS_EXPR:
477       /* Nonzero iff operands of minus differ.  */
478       code = NE_EXPR;
479
480       /* FALLTHRU */
481     case EQ_EXPR:
482     case NE_EXPR:
483     case LT_EXPR:
484     case LE_EXPR:
485     case GT_EXPR:
486     case GE_EXPR:
487     case ORDERED_EXPR:
488     case UNORDERED_EXPR:
489     case UNLT_EXPR:
490     case UNLE_EXPR:
491     case UNGT_EXPR:
492     case UNGE_EXPR:
493     case UNEQ_EXPR:
494     case LTGT_EXPR:
495     case TRUTH_ANDIF_EXPR:
496     case TRUTH_ORIF_EXPR:
497     other_code:
498       do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
499                  if_false_label, if_true_label, prob);
500       break;
501
502     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       if (integer_onep (TREE_OPERAND (exp, 1)))
507         {
508           tree exp0 = TREE_OPERAND (exp, 0);
509           rtx_code_label *set_label, *clr_label;
510           profile_probability setclr_prob = prob;
511
512           /* Strip narrowing integral type conversions.  */
513           while (CONVERT_EXPR_P (exp0)
514                  && TREE_OPERAND (exp0, 0) != error_mark_node
515                  && TYPE_PRECISION (TREE_TYPE (exp0))
516                     <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
517             exp0 = TREE_OPERAND (exp0, 0);
518
519           /* "exp0 ^ 1" inverts the sense of the single bit test.  */
520           if (TREE_CODE (exp0) == BIT_XOR_EXPR
521               && integer_onep (TREE_OPERAND (exp0, 1)))
522             {
523               exp0 = TREE_OPERAND (exp0, 0);
524               clr_label = if_true_label;
525               set_label = if_false_label;
526               setclr_prob = prob.invert ();
527             }
528           else
529             {
530               clr_label = if_false_label;
531               set_label = if_true_label;
532             }
533
534           if (TREE_CODE (exp0) == RSHIFT_EXPR)
535             {
536               tree arg = TREE_OPERAND (exp0, 0);
537               tree shift = TREE_OPERAND (exp0, 1);
538               tree argtype = TREE_TYPE (arg);
539               if (TREE_CODE (shift) == INTEGER_CST
540                   && compare_tree_int (shift, 0) >= 0
541                   && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
542                   && prefer_and_bit_test (SCALAR_INT_TYPE_MODE (argtype),
543                                           TREE_INT_CST_LOW (shift)))
544                 {
545                   unsigned HOST_WIDE_INT mask
546                     = HOST_WIDE_INT_1U << TREE_INT_CST_LOW (shift);
547                   do_jump (build2 (BIT_AND_EXPR, argtype, arg,
548                                    build_int_cstu (argtype, mask)),
549                            clr_label, set_label, setclr_prob);
550                   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       if (! SLOW_BYTE_ACCESS
563           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
564           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
565           && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
566           && int_mode_for_size (i + 1, 0).exists (&mode)
567           && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
568           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
569           && have_insn_for (COMPARE, TYPE_MODE (type)))
570         {
571           do_jump (fold_convert (type, exp), if_false_label, if_true_label,
572                    prob);
573           break;
574         }
575
576       if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
577           || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
578         goto normal;
579
580       /* Boolean comparisons can be compiled as TRUTH_AND_EXPR.  */
581       /* FALLTHRU */
582
583     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       if (BRANCH_COST (optimize_insn_for_speed_p (),
588                        false) >= 4
589           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
590         goto normal;
591       code = TRUTH_ANDIF_EXPR;
592       goto other_code;
593
594     case BIT_IOR_EXPR:
595     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       if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
600           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
601         goto normal;
602       code = TRUTH_ORIF_EXPR;
603       goto other_code;
604
605       /* Fall through and generate the normal code.  */
606     default:
607     normal:
608       temp = expand_normal (exp);
609       do_pending_stack_adjust ();
610       /* The RTL optimizers prefer comparisons against pseudos.  */
611       if (GET_CODE (temp) == SUBREG)
612         {
613           /* Compare promoted variables in their promoted mode.  */
614           if (SUBREG_PROMOTED_VAR_P (temp)
615               && REG_P (XEXP (temp, 0)))
616             temp = XEXP (temp, 0);
617           else
618             temp = copy_to_reg (temp);
619         }
620       do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
621                                NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
622                                GET_MODE (temp), NULL_RTX,
623                                if_false_label, if_true_label, prob);
624     }
625
626   if (drop_through_label)
627     {
628       do_pending_stack_adjust ();
629       emit_label (drop_through_label);
630     }
631 }
632 \f
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 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   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
644   rtx_code_label *drop_through_label = 0;
645   bool drop_through_if_true = false, drop_through_if_false = false;
646   enum rtx_code code = GT;
647   int i;
648
649   if (! if_true_label || ! if_false_label)
650     drop_through_label = gen_label_rtx ();
651   if (! if_true_label)
652     {
653       if_true_label = drop_through_label;
654       drop_through_if_true = true;
655     }
656   if (! if_false_label)
657     {
658       if_false_label = drop_through_label;
659       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   if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
665     {
666       code = LE;
667       if_true_label = if_false_label;
668       if_false_label = drop_through_label;
669       prob = prob.invert ();
670     }
671
672   /* Compare a word at a time, high order first.  */
673   for (i = 0; i < nwords; i++)
674     {
675       rtx op0_word, op1_word;
676
677       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           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
685           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
686         }
687
688       /* All but high-order word must be compared as unsigned.  */
689       do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
690                                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       if (op0 == const0_rtx || i == nwords - 1)
695         break;
696
697       /* Consider lower words only if these are equal.  */
698       do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
699                                NULL_RTX, NULL, if_false_label,
700                                prob.invert ());
701     }
702
703   if (!drop_through_if_false)
704     emit_jump (if_false_label);
705   if (drop_through_label)
706     emit_label (drop_through_label);
707 }
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 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   rtx op0 = expand_normal (swap ? treeop1 : treeop0);
721   rtx op1 = expand_normal (swap ? treeop0 : treeop1);
722   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
723
724   do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
725                                 if_true_label, prob);
726 }
727 \f
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 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   int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
740   rtx part;
741   int i;
742   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   part = gen_reg_rtx (word_mode);
750   emit_move_insn (part, operand_subword_force (op0, 0, mode));
751   for (i = 1; i < nwords && part != 0; i++)
752     part = expand_binop (word_mode, ior_optab, part,
753                          operand_subword_force (op0, i, mode),
754                          part, 1, OPTAB_WIDEN);
755
756   if (part != 0)
757     {
758       do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
759                                NULL_RTX, if_false_label, if_true_label, prob);
760       return;
761     }
762
763   /* If we couldn't do the "or" simply, do this with a series of compares.  */
764   if (! if_false_label)
765     if_false_label = drop_through_label = gen_label_rtx ();
766
767   for (i = 0; i < nwords; i++)
768     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
769                              const0_rtx, EQ, 1, word_mode, NULL_RTX,
770                              if_false_label, NULL, prob);
771
772   if (if_true_label)
773     emit_jump (if_true_label);
774
775   if (drop_through_label)
776     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 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   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
791   rtx_code_label *drop_through_label = NULL;
792   int i;
793
794   if (op1 == const0_rtx)
795     {
796       do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
797                                  prob);
798       return;
799     }
800   else if (op0 == const0_rtx)
801     {
802       do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
803                                  prob);
804       return;
805     }
806
807   if (! if_false_label)
808     drop_through_label = if_false_label = gen_label_rtx ();
809
810   for (i = 0; i < nwords; i++)
811     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
812                              operand_subword_force (op1, i, mode),
813                              EQ, 0, word_mode, NULL_RTX,
814                              if_false_label, NULL, prob);
815
816   if (if_true_label)
817     emit_jump (if_true_label);
818   if (drop_through_label)
819     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 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   rtx op0 = expand_normal (treeop0);
833   rtx op1 = expand_normal (treeop1);
834   do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
835                                  if_true_label, prob);
836 }
837 \f
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 split_comparison (enum rtx_code code, machine_mode mode,
848                   enum rtx_code *code1, enum rtx_code *code2)
849 {
850   switch (code)
851     {
852     case LT:
853       *code1 = ORDERED;
854       *code2 = UNLT;
855       return true;
856     case LE:
857       *code1 = ORDERED;
858       *code2 = UNLE;
859       return true;
860     case GT:
861       *code1 = ORDERED;
862       *code2 = UNGT;
863       return true;
864     case GE:
865       *code1 = ORDERED;
866       *code2 = UNGE;
867       return true;
868     case EQ:
869       *code1 = ORDERED;
870       *code2 = UNEQ;
871       return true;
872     case NE:
873       *code1 = UNORDERED;
874       *code2 = LTGT;
875       return false;
876     case UNLT:
877       *code1 = UNORDERED;
878       *code2 = LT;
879       return false;
880     case UNLE:
881       *code1 = UNORDERED;
882       *code2 = LE;
883       return false;
884     case UNGT:
885       *code1 = UNORDERED;
886       *code2 = GT;
887       return false;
888     case UNGE:
889       *code1 = UNORDERED;
890       *code2 = GE;
891       return false;
892     case UNEQ:
893       *code1 = UNORDERED;
894       *code2 = EQ;
895       return false;
896     case LTGT:
897       /* Do not turn a trapping comparison into a non-trapping one.  */
898       if (HONOR_NANS (mode))
899         {
900           *code1 = LT;
901           *code2 = GT;
902           return false;
903         }
904       else
905         {
906           *code1 = ORDERED;
907           *code2 = NE;
908           return true;
909         }
910     default:
911       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 jumpif (tree exp, rtx_code_label *label, profile_probability prob)
920 {
921   do_jump (exp, NULL, label, prob);
922 }
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 jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
929           profile_probability prob)
930 {
931   do_jump_1 (code, op0, op1, NULL, label, prob);
932 }
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 jumpifnot (tree exp, rtx_code_label *label, profile_probability prob)
939 {
940   do_jump (exp, label, NULL, prob.invert ());
941 }
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 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
948              profile_probability prob)
949 {
950   do_jump_1 (code, op0, op1, label, NULL, prob.invert ());
951 }
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 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   rtx tem;
967   rtx_code_label *dummy_label = NULL;
968
969   /* Reverse the comparison if that is safe and we want to jump if it is
970      false.  Also convert to the reverse comparison if the target can
971      implement it.  */
972   if ((! if_true_label
973        || ! can_compare_p (code, mode, ccp_jump))
974       && (! FLOAT_MODE_P (mode)
975           || code == ORDERED || code == UNORDERED
976           || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
977           || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
978     {
979       enum rtx_code rcode;
980       if (FLOAT_MODE_P (mode))
981         rcode = reverse_condition_maybe_unordered (code);
982       else
983         rcode = reverse_condition (code);
984
985       /* Canonicalize to UNORDERED for the libcall.  */
986       if (can_compare_p (rcode, mode, ccp_jump)
987           || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
988         {
989           std::swap (if_true_label, if_false_label);
990           code = rcode;
991           prob = prob.invert ();
992         }
993     }
994
995   /* If one operand is constant, make it the second one.  Only do this
996      if the other operand is not constant as well.  */
997
998   if (swap_commutative_operands_p (op0, op1))
999     {
1000       std::swap (op0, op1);
1001       code = swap_condition (code);
1002     }
1003
1004   do_pending_stack_adjust ();
1005
1006   code = unsignedp ? unsigned_condition (code) : code;
1007   if ((tem = simplify_relational_operation (code, mode, VOIDmode,
1008                                             op0, op1)) != 0)
1009     {
1010       if (CONSTANT_P (tem))
1011         {
1012           rtx_code_label *label = (tem == const0_rtx
1013                                    || tem == CONST0_RTX (mode))
1014                                         ? if_false_label : if_true_label;
1015           if (label)
1016             emit_jump (label);
1017           return;
1018         }
1019
1020       code = GET_CODE (tem);
1021       mode = GET_MODE (tem);
1022       op0 = XEXP (tem, 0);
1023       op1 = XEXP (tem, 1);
1024       unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
1025     }
1026
1027   if (! if_true_label)
1028     dummy_label = if_true_label = gen_label_rtx ();
1029
1030   scalar_int_mode int_mode;
1031   if (is_int_mode (mode, &int_mode)
1032       && ! can_compare_p (code, int_mode, ccp_jump))
1033     {
1034       switch (code)
1035         {
1036         case LTU:
1037           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
1038                                         if_false_label, if_true_label, prob);
1039           break;
1040
1041         case LEU:
1042           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
1043                                         if_true_label, if_false_label,
1044                                         prob.invert ());
1045           break;
1046
1047         case GTU:
1048           do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
1049                                         if_false_label, if_true_label, prob);
1050           break;
1051
1052         case GEU:
1053           do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
1054                                         if_true_label, if_false_label,
1055                                         prob.invert ());
1056           break;
1057
1058         case LT:
1059           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
1060                                         if_false_label, if_true_label, prob);
1061           break;
1062
1063         case LE:
1064           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
1065                                         if_true_label, if_false_label,
1066                                         prob.invert ());
1067           break;
1068
1069         case GT:
1070           do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
1071                                         if_false_label, if_true_label, prob);
1072           break;
1073
1074         case GE:
1075           do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
1076                                         if_true_label, if_false_label,
1077                                         prob.invert ());
1078           break;
1079
1080         case EQ:
1081           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_false_label,
1082                                          if_true_label, prob);
1083           break;
1084
1085         case NE:
1086           do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_true_label,
1087                                          if_false_label,
1088                                          prob.invert ());
1089           break;
1090
1091         default:
1092           gcc_unreachable ();
1093         }
1094     }
1095   else
1096     {
1097       if (SCALAR_FLOAT_MODE_P (mode)
1098           && ! can_compare_p (code, mode, ccp_jump)
1099           && can_compare_p (swap_condition (code), mode, ccp_jump))
1100         {
1101           code = swap_condition (code);
1102           std::swap (op0, op1);
1103         }
1104       else if (SCALAR_FLOAT_MODE_P (mode)
1105                && ! can_compare_p (code, mode, ccp_jump)
1106                /* Never split ORDERED and UNORDERED.
1107                   These must be implemented.  */
1108                && (code != ORDERED && code != UNORDERED)
1109                /* Split a floating-point comparison if
1110                   we can jump on other conditions...  */
1111                && (have_insn_for (COMPARE, mode)
1112                    /* ... or if there is no libcall for it.  */
1113                    || code_to_optab (code) == unknown_optab))
1114         {
1115           enum rtx_code first_code, orig_code = code;
1116           bool and_them = split_comparison (code, mode, &first_code, &code);
1117
1118           /* If there are no NaNs, the first comparison should always fall
1119              through.  */
1120           if (!HONOR_NANS (mode))
1121             gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1122
1123           else if ((orig_code == EQ || orig_code == NE)
1124                    && rtx_equal_p (op0, op1))
1125             /* Self-comparisons x == x or x != x can be optimized into
1126                just x ord x or x nord x.  */
1127             code = orig_code == EQ ? ORDERED : UNORDERED;
1128
1129           else
1130             {
1131               profile_probability cprob
1132                 = profile_probability::guessed_always ();
1133               if (first_code == UNORDERED)
1134                 cprob /= 100;
1135               else if (first_code == ORDERED)
1136                 cprob = cprob.apply_scale (99, 100);
1137               else
1138                 cprob = profile_probability::even ();
1139               /* For and_them we want to split:
1140                  if (x) goto t; // prob;
1141                  goto f;
1142                  into
1143                  if (a) ; else goto f; // first_prob for ;
1144                                        // 1 - first_prob for goto f;
1145                  if (b) goto t; // adjusted prob;
1146                  goto f;
1147                  such that the overall probability of jumping to t
1148                  remains the same.  The and_them case should be
1149                  probability-wise equivalent to the !and_them case with
1150                  f and t swapped and also the conditions inverted, i.e.
1151                  if (!a) goto f;
1152                  if (!b) goto f;
1153                  goto t;
1154                  where the overall probability of jumping to f is
1155                  1 - prob (thus the first prob.invert () below).
1156                  cprob.invert () is because the a condition is inverted,
1157                  so if it was originally ORDERED, !a is UNORDERED and
1158                  thus should be relative 1% rather than 99%.
1159                  The invert () on assignment to first_prob is because
1160                  first_prob represents the probability of fallthru,
1161                  rather than goto f.  And the last prob.invert () is
1162                  because the adjusted prob represents the probability of
1163                  jumping to t rather than to f.  */
1164               if (and_them)
1165                 {
1166                   rtx_code_label *dest_label;
1167                   prob = prob.invert ();
1168                   profile_probability first_prob
1169                     = prob.split (cprob.invert ()).invert ();
1170                   prob = prob.invert ();
1171                   /* If we only jump if true, just bypass the second jump.  */
1172                   if (! if_false_label)
1173                     {
1174                       if (! dummy_label)
1175                         dummy_label = gen_label_rtx ();
1176                       dest_label = dummy_label;
1177                     }
1178                   else
1179                     dest_label = if_false_label;
1180                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1181                                            size, dest_label, NULL, first_prob);
1182                 }
1183               /* For !and_them we want to split:
1184                  if (x) goto t; // prob;
1185                  goto f;
1186                  into
1187                  if (a) goto t; // first_prob;
1188                  if (b) goto t; // adjusted prob;
1189                  goto f;
1190                  such that the overall probability of jumping to t
1191                  remains the same and first_prob is prob * cprob.  */
1192               else
1193                 {
1194                   profile_probability first_prob = prob.split (cprob);
1195                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1196                                            size, NULL, if_true_label, first_prob);
1197                   if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump))
1198                     {
1199                       /* x != y can be split into x unord y || x ltgt y
1200                          or x unord y || !(x uneq y).  The latter has the
1201                          advantage that both comparisons are non-signalling and
1202                          so there is a higher chance that the RTL optimizations
1203                          merge the two comparisons into just one.  */
1204                       code = UNEQ;
1205                       prob = prob.invert ();
1206                       if (! if_false_label)
1207                         {
1208                           if (! dummy_label)
1209                             dummy_label = gen_label_rtx ();
1210                           if_false_label = dummy_label;
1211                         }
1212                       std::swap (if_false_label, if_true_label);
1213                     }
1214                 }
1215             }
1216         }
1217
1218       emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1219                                if_true_label, prob);
1220     }
1221
1222   if (if_false_label)
1223     emit_jump (if_false_label);
1224   if (dummy_label)
1225     emit_label (dummy_label);
1226 }
1227
1228 /* Generate code for a comparison expression EXP (including code to compute
1229    the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1230    IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
1231    generated code will drop through.
1232    SIGNED_CODE should be the rtx operation for this comparison for
1233    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1234
1235    We force a stack adjustment unless there are currently
1236    things pushed on the stack that aren't yet used.  */
1237
1238 static void
1239 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1240                      enum rtx_code unsigned_code,
1241                      rtx_code_label *if_false_label,
1242                      rtx_code_label *if_true_label, profile_probability prob)
1243 {
1244   rtx op0, op1;
1245   tree type;
1246   machine_mode mode;
1247   int unsignedp;
1248   enum rtx_code code;
1249
1250   /* Don't crash if the comparison was erroneous.  */
1251   op0 = expand_normal (treeop0);
1252   if (TREE_CODE (treeop0) == ERROR_MARK)
1253     return;
1254
1255   op1 = expand_normal (treeop1);
1256   if (TREE_CODE (treeop1) == ERROR_MARK)
1257     return;
1258
1259   type = TREE_TYPE (treeop0);
1260   if (TREE_CODE (treeop0) == INTEGER_CST
1261       && (TREE_CODE (treeop1) != INTEGER_CST
1262           || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type))
1263               > GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (treeop1))))))
1264     /* op0 might have been replaced by promoted constant, in which
1265        case the type of second argument should be used.  */
1266     type = TREE_TYPE (treeop1);
1267   mode = TYPE_MODE (type);
1268   unsignedp = TYPE_UNSIGNED (type);
1269   code = unsignedp ? unsigned_code : signed_code;
1270
1271   /* If function pointers need to be "canonicalized" before they can
1272      be reliably compared, then canonicalize them.  Canonicalize the
1273      expression when one of the operands is a function pointer.  This
1274      handles the case where the other operand is a void pointer.  See
1275      PR middle-end/17564.  */
1276   if (targetm.have_canonicalize_funcptr_for_compare ()
1277       && ((POINTER_TYPE_P (TREE_TYPE (treeop0))
1278            && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))))
1279           || (POINTER_TYPE_P (TREE_TYPE (treeop1))
1280               && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
1281     {
1282       rtx new_op0 = gen_reg_rtx (mode);
1283       rtx new_op1 = gen_reg_rtx (mode);
1284
1285       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0));
1286       op0 = new_op0;
1287
1288       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
1289       op1 = new_op1;
1290     }
1291
1292   do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1293                            ((mode == BLKmode)
1294                             ? expr_size (treeop0) : NULL_RTX),
1295                            if_false_label, if_true_label, prob);
1296 }
1297
1298 #include "gt-dojump.h"