Branch data Line data Source code
1 : : /* Convert tree expression to rtl instructions, for GNU compiler.
2 : : Copyright (C) 1988-2025 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 : 3118822 : discard_pending_stack_adjust (void)
67 : : {
68 : 3118822 : stack_pointer_delta -= pending_stack_adjust;
69 : 3118822 : pending_stack_adjust = 0;
70 : 3118822 : }
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 : 2236101 : clear_pending_stack_adjust (void)
80 : : {
81 : 2236101 : if (optimize > 0
82 : 1605545 : && (! flag_omit_frame_pointer || cfun->calls_alloca)
83 : : && EXIT_IGNORE_STACK)
84 : 30909 : discard_pending_stack_adjust ();
85 : 2236101 : }
86 : :
87 : : /* Pop any previously-pushed arguments that have not been popped yet. */
88 : :
89 : : void
90 : 27008595 : do_pending_stack_adjust (void)
91 : : {
92 : 27008595 : if (inhibit_defer_pop == 0)
93 : : {
94 : 26992890 : if (maybe_ne (pending_stack_adjust, 0))
95 : 745896 : adjust_stack (gen_int_mode (pending_stack_adjust, Pmode));
96 : 26992890 : pending_stack_adjust = 0;
97 : : }
98 : 27008595 : }
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 : 616920 : save_pending_stack_adjust (saved_pending_stack_adjust *save)
106 : : {
107 : 616920 : save->x_pending_stack_adjust = pending_stack_adjust;
108 : 616920 : save->x_stack_pointer_delta = stack_pointer_delta;
109 : 616920 : }
110 : :
111 : : /* Restore the saved pending_stack_adjust/stack_pointer_delta. */
112 : :
113 : : void
114 : 183695 : restore_pending_stack_adjust (saved_pending_stack_adjust *save)
115 : : {
116 : 183695 : if (inhibit_defer_pop == 0)
117 : : {
118 : 183606 : pending_stack_adjust = save->x_pending_stack_adjust;
119 : 183606 : stack_pointer_delta = save->x_stack_pointer_delta;
120 : : }
121 : 183695 : }
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 : 5309089 : 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 : 5309089 : machine_mode mode;
176 : 5309089 : rtx_code_label *drop_through_label = 0;
177 : 5309089 : scalar_int_mode int_mode;
178 : :
179 : 5309089 : switch (code)
180 : : {
181 : 1448766 : case EQ_EXPR:
182 : 1448766 : {
183 : 1448766 : tree inner_type = TREE_TYPE (op0);
184 : :
185 : 1448766 : gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
186 : : != MODE_COMPLEX_FLOAT);
187 : 1448766 : gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
188 : : != MODE_COMPLEX_INT);
189 : :
190 : 1448766 : if (integer_zerop (op1))
191 : 762254 : do_jump (op0, if_true_label, if_false_label,
192 : : prob.invert ());
193 : 686512 : else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
194 : 676779 : && !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 : 686512 : do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
199 : : prob);
200 : : break;
201 : : }
202 : :
203 : 2717166 : case NE_EXPR:
204 : 2717166 : {
205 : 2717166 : tree inner_type = TREE_TYPE (op0);
206 : :
207 : 2717166 : gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
208 : : != MODE_COMPLEX_FLOAT);
209 : 2717166 : gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
210 : : != MODE_COMPLEX_INT);
211 : :
212 : 2717166 : if (integer_zerop (op1))
213 : 1142559 : do_jump (op0, if_false_label, if_true_label, prob);
214 : 1574607 : else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
215 : 1395225 : && !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 : 1574607 : do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
220 : : prob);
221 : : break;
222 : : }
223 : :
224 : 206971 : case LT_EXPR:
225 : 206971 : mode = TYPE_MODE (TREE_TYPE (op0));
226 : 206971 : if (is_int_mode (mode, &int_mode)
227 : 192248 : && ! 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 : 206971 : do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
232 : : prob);
233 : : break;
234 : :
235 : 194666 : case LE_EXPR:
236 : 194666 : mode = TYPE_MODE (TREE_TYPE (op0));
237 : 194666 : if (is_int_mode (mode, &int_mode)
238 : 187986 : && ! 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 : 194666 : do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
243 : : prob);
244 : : break;
245 : :
246 : 485286 : case GT_EXPR:
247 : 485286 : mode = TYPE_MODE (TREE_TYPE (op0));
248 : 485286 : if (is_int_mode (mode, &int_mode)
249 : 468170 : && ! 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 : 485286 : do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
254 : : prob);
255 : : break;
256 : :
257 : 119870 : case GE_EXPR:
258 : 119870 : mode = TYPE_MODE (TREE_TYPE (op0));
259 : 119870 : if (is_int_mode (mode, &int_mode)
260 : 112174 : && ! 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 : 119870 : do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
265 : : prob);
266 : : break;
267 : :
268 : 2768 : case ORDERED_EXPR:
269 : 2768 : do_compare_and_jump (op0, op1, ORDERED, ORDERED,
270 : : if_false_label, if_true_label, prob);
271 : 2768 : break;
272 : :
273 : 3095 : case UNORDERED_EXPR:
274 : 3095 : do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
275 : : if_false_label, if_true_label, prob);
276 : 3095 : break;
277 : :
278 : 752 : case UNLT_EXPR:
279 : 752 : do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
280 : : prob);
281 : 752 : break;
282 : :
283 : 5436 : case UNLE_EXPR:
284 : 5436 : do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
285 : : prob);
286 : 5436 : break;
287 : :
288 : 3004 : case UNGT_EXPR:
289 : 3004 : do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
290 : : prob);
291 : 3004 : break;
292 : :
293 : 3333 : case UNGE_EXPR:
294 : 3333 : do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
295 : : prob);
296 : 3333 : 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 : 1 : case LTGT_EXPR:
304 : 1 : do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
305 : : prob);
306 : 1 : break;
307 : :
308 : 55608 : case TRUTH_ANDIF_EXPR:
309 : 55608 : {
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 : 55608 : profile_probability op0_prob = profile_probability::uninitialized ();
317 : 55608 : profile_probability op1_prob = profile_probability::uninitialized ();
318 : 55608 : if (prob.initialized_p ())
319 : : {
320 : 55603 : op1_prob = prob.invert ();
321 : 55603 : op0_prob = op1_prob.split (profile_probability::even ());
322 : : /* Get the probability that each jump below is true. */
323 : 55603 : op0_prob = op0_prob.invert ();
324 : 55603 : op1_prob = op1_prob.invert ();
325 : : }
326 : 55608 : if (if_false_label == NULL)
327 : : {
328 : 33220 : drop_through_label = gen_label_rtx ();
329 : 33220 : do_jump (op0, drop_through_label, NULL, op0_prob);
330 : 33220 : do_jump (op1, NULL, if_true_label, op1_prob);
331 : : }
332 : : else
333 : : {
334 : 22388 : do_jump (op0, if_false_label, NULL, op0_prob);
335 : 22388 : do_jump (op1, if_false_label, if_true_label, op1_prob);
336 : : }
337 : 33220 : break;
338 : : }
339 : :
340 : 62086 : case TRUTH_ORIF_EXPR:
341 : 62086 : {
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 : 62086 : profile_probability op0_prob = profile_probability::uninitialized ();
348 : 62086 : profile_probability op1_prob = profile_probability::uninitialized ();
349 : 62086 : if (prob.initialized_p ())
350 : : {
351 : 62065 : op1_prob = prob;
352 : 62065 : op0_prob = op1_prob.split (profile_probability::even ());
353 : : }
354 : 62086 : if (if_true_label == NULL)
355 : : {
356 : 24341 : drop_through_label = gen_label_rtx ();
357 : 24341 : do_jump (op0, NULL, drop_through_label, op0_prob);
358 : 24341 : do_jump (op1, if_false_label, NULL, op1_prob);
359 : : }
360 : : else
361 : : {
362 : 37745 : do_jump (op0, NULL, if_true_label, op0_prob);
363 : 37745 : do_jump (op1, if_false_label, if_true_label, op1_prob);
364 : : }
365 : 24341 : break;
366 : : }
367 : :
368 : 0 : default:
369 : 0 : gcc_unreachable ();
370 : : }
371 : :
372 : 5309089 : if (drop_through_label)
373 : : {
374 : 57561 : do_pending_stack_adjust ();
375 : 57561 : emit_label (drop_through_label);
376 : : }
377 : 5309089 : }
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 : 2143730 : do_jump (tree exp, rtx_code_label *if_false_label,
392 : : rtx_code_label *if_true_label, profile_probability prob)
393 : : {
394 : 2143730 : enum tree_code code = TREE_CODE (exp);
395 : 2143730 : rtx temp;
396 : 2143730 : int i;
397 : 2143730 : tree type;
398 : 2143730 : scalar_int_mode mode;
399 : 2143730 : rtx_code_label *drop_through_label = NULL;
400 : :
401 : 2143730 : switch (code)
402 : : {
403 : : case ERROR_MARK:
404 : : break;
405 : :
406 : 1 : case INTEGER_CST:
407 : 1 : {
408 : 1 : rtx_code_label *lab = integer_zerop (exp) ? if_false_label
409 : 1 : : if_true_label;
410 : 1 : if (lab)
411 : 0 : emit_jump (lab);
412 : : break;
413 : : }
414 : :
415 : : #if 0
416 : : /* This is not true with #pragma weak */
417 : : case ADDR_EXPR:
418 : : /* The address of something can never be zero. */
419 : : if (if_true_label)
420 : : emit_jump (if_true_label);
421 : : break;
422 : : #endif
423 : :
424 : 0 : CASE_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 : 2143729 : default:
607 : 2143729 : normal:
608 : 2143729 : temp = expand_normal (exp);
609 : 2143729 : do_pending_stack_adjust ();
610 : : /* The RTL optimizers prefer comparisons against pseudos. */
611 : 2143729 : if (GET_CODE (temp) == SUBREG)
612 : : {
613 : : /* Compare promoted variables in their promoted mode. */
614 : 34355 : if (SUBREG_PROMOTED_VAR_P (temp)
615 : 34355 : && REG_P (XEXP (temp, 0)))
616 : : temp = XEXP (temp, 0);
617 : : else
618 : 34355 : temp = copy_to_reg (temp);
619 : : }
620 : 4287458 : do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
621 : 2143729 : NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
622 : 2143729 : exp, GET_MODE (temp), NULL_RTX,
623 : : if_false_label, if_true_label, prob);
624 : : }
625 : :
626 : 2143729 : if (drop_through_label)
627 : : {
628 : 0 : do_pending_stack_adjust ();
629 : 0 : emit_label (drop_through_label);
630 : : }
631 : 2143730 : }
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 : 236929 : split_comparison (enum rtx_code code, machine_mode mode,
848 : : enum rtx_code *code1, enum rtx_code *code2)
849 : : {
850 : 236929 : switch (code)
851 : : {
852 : 61 : case LT:
853 : 61 : *code1 = ORDERED;
854 : 61 : *code2 = UNLT;
855 : 61 : return true;
856 : 150 : case LE:
857 : 150 : *code1 = ORDERED;
858 : 150 : *code2 = UNLE;
859 : 150 : return true;
860 : 47 : case GT:
861 : 47 : *code1 = ORDERED;
862 : 47 : *code2 = UNGT;
863 : 47 : return true;
864 : 148 : case GE:
865 : 148 : *code1 = ORDERED;
866 : 148 : *code2 = UNGE;
867 : 148 : return true;
868 : 10235 : case EQ:
869 : 10235 : *code1 = ORDERED;
870 : 10235 : *code2 = UNEQ;
871 : 10235 : return true;
872 : 219426 : case NE:
873 : 219426 : *code1 = UNORDERED;
874 : 219426 : *code2 = LTGT;
875 : 219426 : return false;
876 : 206 : case UNLT:
877 : 206 : *code1 = UNORDERED;
878 : 206 : *code2 = LT;
879 : 206 : return false;
880 : 3378 : case UNLE:
881 : 3378 : *code1 = UNORDERED;
882 : 3378 : *code2 = LE;
883 : 3378 : return false;
884 : 691 : case UNGT:
885 : 691 : *code1 = UNORDERED;
886 : 691 : *code2 = GT;
887 : 691 : 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 : 2540162 : jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
929 : : profile_probability prob)
930 : : {
931 : 2540162 : do_jump_1 (code, op0, op1, NULL, label, prob);
932 : 2540162 : }
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 : 3529 : jumpifnot (tree exp, rtx_code_label *label, profile_probability prob)
939 : : {
940 : 3529 : do_jump (exp, label, NULL, prob.invert ());
941 : 3529 : }
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 : 2768927 : jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
948 : : profile_probability prob)
949 : : {
950 : 2768927 : do_jump_1 (code, op0, op1, label, NULL, prob.invert ());
951 : 2768927 : }
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 : 215301 : 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 : 215301 : do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size,
967 : : if_false_label, if_true_label, prob);
968 : 215301 : }
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 : 5812744 : 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 : 5812744 : rtx tem;
984 : 5812744 : 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 : 5812744 : if ((! if_true_label
990 : 3160224 : || ! can_compare_p (code, mode, ccp_jump))
991 : 5953794 : && (! FLOAT_MODE_P (mode)
992 : 257611 : || code == ORDERED || code == UNORDERED
993 : 240910 : || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
994 : 240910 : || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
995 : : {
996 : 2742087 : enum rtx_code rcode;
997 : 2742087 : if (FLOAT_MODE_P (mode))
998 : 206128 : rcode = reverse_condition_maybe_unordered (code);
999 : : else
1000 : 2535959 : rcode = reverse_condition (code);
1001 : :
1002 : : /* Canonicalize to UNORDERED for the libcall. */
1003 : 2742087 : if (can_compare_p (rcode, mode, ccp_jump)
1004 : 2742087 : || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
1005 : : {
1006 : 2547720 : std::swap (if_true_label, if_false_label);
1007 : 2547720 : code = rcode;
1008 : 2547720 : 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 : 5812744 : if (swap_commutative_operands_p (op0, op1))
1016 : : {
1017 : 97880 : std::swap (op0, op1);
1018 : 97880 : code = swap_condition (code);
1019 : : }
1020 : :
1021 : 5812744 : do_pending_stack_adjust ();
1022 : :
1023 : 5812744 : code = unsignedp ? unsigned_condition (code) : code;
1024 : 5812744 : if ((tem = simplify_relational_operation (code, mode, VOIDmode,
1025 : : op0, op1)) != 0)
1026 : : {
1027 : 4013 : if (CONSTANT_P (tem))
1028 : : {
1029 : 6226 : rtx_code_label *label = (tem == const0_rtx
1030 : 940 : || tem == CONST0_RTX (mode))
1031 : 3113 : ? if_false_label : if_true_label;
1032 : 3113 : if (label)
1033 : 809 : emit_jump (label);
1034 : 3113 : return;
1035 : : }
1036 : :
1037 : 900 : code = GET_CODE (tem);
1038 : 900 : mode = GET_MODE (tem);
1039 : 900 : op0 = XEXP (tem, 0);
1040 : 900 : op1 = XEXP (tem, 1);
1041 : 900 : unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
1042 : : }
1043 : :
1044 : 5809631 : if (! if_true_label)
1045 : 105058 : dummy_label = if_true_label = gen_label_rtx ();
1046 : :
1047 : 5809631 : scalar_int_mode int_mode;
1048 : 5809631 : if (is_int_mode (mode, &int_mode)
1049 : 5376180 : && ! 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 : 5809631 : if (SCALAR_FLOAT_MODE_P (mode)
1115 : 428706 : && ! can_compare_p (code, mode, ccp_jump)
1116 : 6042617 : && can_compare_p (swap_condition (code), mode, ccp_jump))
1117 : : {
1118 : 24215 : code = swap_condition (code);
1119 : 24215 : std::swap (op0, op1);
1120 : : }
1121 : 5785416 : else if (SCALAR_FLOAT_MODE_P (mode)
1122 : 404491 : && ! can_compare_p (code, mode, ccp_jump)
1123 : : /* Never split ORDERED and UNORDERED.
1124 : : These must be implemented. */
1125 : 208771 : && (code != ORDERED && code != UNORDERED)
1126 : : /* Split a floating-point comparison if
1127 : : we can jump on other conditions... */
1128 : 5988588 : && (have_insn_for (COMPARE, mode)
1129 : : /* ... or if there is no libcall for it. */
1130 : 38420 : || code_to_optab (code) == unknown_optab))
1131 : : {
1132 : 169480 : enum rtx_code first_code, orig_code = code;
1133 : 169480 : 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 : 169480 : if (!HONOR_NANS (mode))
1138 : 1626 : gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1139 : :
1140 : 168654 : else if ((orig_code == EQ || orig_code == NE)
1141 : 168654 : && 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 : 2558 : code = orig_code == EQ ? ORDERED : UNORDERED;
1145 : :
1146 : : else
1147 : : {
1148 : 167132 : profile_probability cprob
1149 : 167132 : = profile_probability::guessed_always ();
1150 : 167132 : if (first_code == UNORDERED)
1151 : 159878 : cprob /= 100;
1152 : 7254 : else if (first_code == ORDERED)
1153 : 7253 : 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 : 167132 : if (and_them)
1182 : : {
1183 : 7253 : rtx_code_label *dest_label;
1184 : 7253 : prob = prob.invert ();
1185 : 7253 : profile_probability first_prob
1186 : 7253 : = prob.split (cprob.invert ()).invert ();
1187 : 7253 : prob = prob.invert ();
1188 : : /* If we only jump if true, just bypass the second jump. */
1189 : 7253 : if (! if_false_label)
1190 : : {
1191 : 3073 : if (! dummy_label)
1192 : 3073 : dummy_label = gen_label_rtx ();
1193 : : dest_label = dummy_label;
1194 : : }
1195 : : else
1196 : : dest_label = if_false_label;
1197 : :
1198 : 7253 : 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 : 159879 : profile_probability first_prob = prob.split (cprob);
1214 : 159879 : do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
1215 : : val, mode, size, NULL,
1216 : : if_true_label, first_prob);
1217 : 159879 : 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 : 155151 : code = UNEQ;
1225 : 155151 : prob = prob.invert ();
1226 : 155151 : if (! if_false_label)
1227 : : {
1228 : 95179 : if (! dummy_label)
1229 : 95179 : 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 : 5809631 : if (val
1241 : 5594284 : && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (val))
1242 : 5811817 : && SCALAR_INT_MODE_P (mode))
1243 : : {
1244 : 795 : auto nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (val)).to_constant ();
1245 : 795 : if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
1246 : : {
1247 : 165 : op0 = expand_binop (mode, and_optab, op0,
1248 : 165 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
1249 : : NULL_RTX, true, OPTAB_WIDEN);
1250 : 165 : 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 : 5809631 : emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val,
1257 : : if_true_label, prob);
1258 : : }
1259 : :
1260 : 5809631 : if (if_false_label)
1261 : 200237 : emit_jump (if_false_label);
1262 : 5809631 : if (dummy_label)
1263 : 203310 : 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 : 3286582 : 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 : 3286582 : rtx op0, op1;
1283 : 3286582 : tree type;
1284 : 3286582 : machine_mode mode;
1285 : 3286582 : int unsignedp;
1286 : 3286582 : enum rtx_code code;
1287 : :
1288 : : /* Don't crash if the comparison was erroneous. */
1289 : 3286582 : op0 = expand_normal (treeop0);
1290 : 3286582 : if (TREE_CODE (treeop0) == ERROR_MARK)
1291 : : return;
1292 : :
1293 : 3286582 : op1 = expand_normal (treeop1);
1294 : 3286582 : if (TREE_CODE (treeop1) == ERROR_MARK)
1295 : : return;
1296 : :
1297 : 3286582 : type = TREE_TYPE (treeop0);
1298 : 3286582 : if (TREE_CODE (treeop0) == INTEGER_CST
1299 : 3286582 : && (TREE_CODE (treeop1) != INTEGER_CST
1300 : 0 : || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type))
1301 : 3286210 : > 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 : 372 : type = TREE_TYPE (treeop1);
1305 : 3286582 : mode = TYPE_MODE (type);
1306 : 3286582 : unsignedp = TYPE_UNSIGNED (type);
1307 : 3286582 : 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 : 3286582 : if (targetm.have_canonicalize_funcptr_for_compare ()
1315 : 3286582 : && ((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 : 3286582 : 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"
|