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