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