]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dojump.cc
c++, mingw: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw on mingw...
[thirdparty/gcc.git] / gcc / dojump.cc
CommitLineData
1cff8964 1/* Convert tree expression to rtl instructions, for GNU compiler.
a945c346 2 Copyright (C) 1988-2024 Free Software Foundation, Inc.
1cff8964
AE
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1cff8964
AE
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
1cff8964
AE
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
c7131fb2 23#include "backend.h"
957060b5 24#include "target.h"
1cff8964
AE
25#include "rtl.h"
26#include "tree.h"
957060b5 27#include "predict.h"
4d0cdd0c 28#include "memmodel.h"
957060b5 29#include "tm_p.h"
957060b5
AM
30#include "optabs.h"
31#include "emit-rtl.h"
40e23961 32#include "fold-const.h"
d8a2d370 33#include "stor-layout.h"
1cff8964 34/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
36566b39
PK
35#include "dojump.h"
36#include "explow.h"
1cff8964 37#include "expr.h"
1cff8964
AE
38#include "langhooks.h"
39
095a2d76 40static bool prefer_and_bit_test (scalar_int_mode, int);
be099f37
EB
41static void do_jump (tree, rtx_code_label *, rtx_code_label *,
42 profile_probability);
d787ba56 43static void do_jump_by_parts_greater (scalar_int_mode, tree, tree, int,
357067f2
JH
44 rtx_code_label *, rtx_code_label *,
45 profile_probability);
d787ba56
RS
46static void do_jump_by_parts_equality (scalar_int_mode, tree, tree,
47 rtx_code_label *, rtx_code_label *,
48 profile_probability);
1476d1bd 49static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code,
357067f2
JH
50 rtx_code_label *, rtx_code_label *,
51 profile_probability);
1cff8964
AE
52
53/* At the start of a function, record that we have no previously-pushed
54 arguments waiting to be popped. */
55
56void
7080f735 57init_pending_stack_adjust (void)
1cff8964
AE
58{
59 pending_stack_adjust = 0;
60}
61
a494ed43
EB
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. */
83f676b3
RS
65void
66discard_pending_stack_adjust (void)
a494ed43
EB
67{
68 stack_pointer_delta -= pending_stack_adjust;
69 pending_stack_adjust = 0;
70}
71
1cff8964
AE
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
78void
7080f735 79clear_pending_stack_adjust (void)
1cff8964 80{
1cff8964 81 if (optimize > 0
e3b5732b 82 && (! flag_omit_frame_pointer || cfun->calls_alloca)
c37f4ba4 83 && EXIT_IGNORE_STACK)
a494ed43 84 discard_pending_stack_adjust ();
1cff8964
AE
85}
86
87/* Pop any previously-pushed arguments that have not been popped yet. */
88
89void
7080f735 90do_pending_stack_adjust (void)
1cff8964
AE
91{
92 if (inhibit_defer_pop == 0)
93 {
a20c5714
RS
94 if (maybe_ne (pending_stack_adjust, 0))
95 adjust_stack (gen_int_mode (pending_stack_adjust, Pmode));
1cff8964
AE
96 pending_stack_adjust = 0;
97 }
98}
7f2f0a01
JJ
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
104void
105save_pending_stack_adjust (saved_pending_stack_adjust *save)
106{
107 save->x_pending_stack_adjust = pending_stack_adjust;
108 save->x_stack_pointer_delta = stack_pointer_delta;
109}
110
111/* Restore the saved pending_stack_adjust/stack_pointer_delta. */
112
113void
114restore_pending_stack_adjust (saved_pending_stack_adjust *save)
115{
116 if (inhibit_defer_pop == 0)
117 {
118 pending_stack_adjust = save->x_pending_stack_adjust;
119 stack_pointer_delta = save->x_stack_pointer_delta;
120 }
121}
1cff8964 122\f
dbf833ee
RS
123/* Used internally by prefer_and_bit_test. */
124
125static GTY(()) rtx and_reg;
126static GTY(()) rtx and_test;
127static 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
133static bool
095a2d76 134prefer_and_bit_test (scalar_int_mode mode, int bitnum)
dbf833ee 135{
68f932c4 136 bool speed_p;
807e902e 137 wide_int mask = wi::set_bit_in_zero (bitnum, GET_MODE_PRECISION (mode));
68f932c4 138
dbf833ee
RS
139 if (and_test == 0)
140 {
141 /* Set up rtxes for the two variations. Use NULL as a placeholder
142 for the BITNUM-based constants. */
c3dc5e66 143 and_reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
dbf833ee
RS
144 and_test = gen_rtx_AND (mode, and_reg, NULL);
145 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
146 const1_rtx);
147 }
148 else
149 {
150 /* Change the mode of the previously-created rtxes. */
151 PUT_MODE (and_reg, mode);
152 PUT_MODE (and_test, mode);
153 PUT_MODE (shift_test, mode);
154 PUT_MODE (XEXP (shift_test, 0), mode);
155 }
156
157 /* Fill in the integers. */
807e902e 158 XEXP (and_test, 1) = immed_wide_int_const (mask, mode);
dbf833ee
RS
159 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
160
68f932c4 161 speed_p = optimize_insn_for_speed_p ();
e548c9df
AM
162 return (rtx_cost (and_test, mode, IF_THEN_ELSE, 0, speed_p)
163 <= rtx_cost (shift_test, mode, IF_THEN_ELSE, 0, speed_p));
dbf833ee
RS
164}
165
4df62c77 166/* Subroutine of do_jump, dealing with exploded comparisons of the type
40e90eac 167 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
357067f2 168 PROB is probability of jump to if_true_label. */
4df62c77 169
be099f37 170static void
4df62c77 171do_jump_1 (enum tree_code code, tree op0, tree op1,
1476d1bd 172 rtx_code_label *if_false_label, rtx_code_label *if_true_label,
357067f2 173 profile_probability prob)
4df62c77 174{
ef4bddc2 175 machine_mode mode;
19f8b229 176 rtx_code_label *drop_through_label = 0;
b4206259 177 scalar_int_mode int_mode;
4df62c77
MM
178
179 switch (code)
180 {
181 case EQ_EXPR:
182 {
183 tree inner_type = TREE_TYPE (op0);
184
185 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
186 != MODE_COMPLEX_FLOAT);
187 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
188 != MODE_COMPLEX_INT);
189
190 if (integer_zerop (op1))
357067f2
JH
191 do_jump (op0, if_true_label, if_false_label,
192 prob.invert ());
b4206259
RS
193 else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
194 && !can_compare_p (EQ, int_mode, ccp_jump))
d787ba56
RS
195 do_jump_by_parts_equality (int_mode, op0, op1, if_false_label,
196 if_true_label, prob);
4df62c77 197 else
40e90eac
JJ
198 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
199 prob);
4df62c77
MM
200 break;
201 }
202
203 case NE_EXPR:
204 {
205 tree inner_type = TREE_TYPE (op0);
206
207 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
208 != MODE_COMPLEX_FLOAT);
209 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
210 != MODE_COMPLEX_INT);
211
212 if (integer_zerop (op1))
40e90eac 213 do_jump (op0, if_false_label, if_true_label, prob);
b4206259
RS
214 else if (is_int_mode (TYPE_MODE (inner_type), &int_mode)
215 && !can_compare_p (NE, int_mode, ccp_jump))
d787ba56
RS
216 do_jump_by_parts_equality (int_mode, op0, op1, if_true_label,
217 if_false_label, prob.invert ());
4df62c77 218 else
40e90eac
JJ
219 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
220 prob);
4df62c77
MM
221 break;
222 }
223
224 case LT_EXPR:
225 mode = TYPE_MODE (TREE_TYPE (op0));
b4206259
RS
226 if (is_int_mode (mode, &int_mode)
227 && ! can_compare_p (LT, int_mode, ccp_jump))
d787ba56 228 do_jump_by_parts_greater (int_mode, op0, op1, 1, if_false_label,
b4206259 229 if_true_label, prob);
4df62c77 230 else
40e90eac
JJ
231 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
232 prob);
4df62c77
MM
233 break;
234
235 case LE_EXPR:
236 mode = TYPE_MODE (TREE_TYPE (op0));
b4206259
RS
237 if (is_int_mode (mode, &int_mode)
238 && ! can_compare_p (LE, int_mode, ccp_jump))
d787ba56
RS
239 do_jump_by_parts_greater (int_mode, op0, op1, 0, if_true_label,
240 if_false_label, prob.invert ());
4df62c77 241 else
40e90eac
JJ
242 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
243 prob);
4df62c77
MM
244 break;
245
246 case GT_EXPR:
247 mode = TYPE_MODE (TREE_TYPE (op0));
b4206259
RS
248 if (is_int_mode (mode, &int_mode)
249 && ! can_compare_p (GT, int_mode, ccp_jump))
d787ba56 250 do_jump_by_parts_greater (int_mode, op0, op1, 0, if_false_label,
b4206259 251 if_true_label, prob);
4df62c77 252 else
40e90eac
JJ
253 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
254 prob);
4df62c77
MM
255 break;
256
257 case GE_EXPR:
258 mode = TYPE_MODE (TREE_TYPE (op0));
b4206259
RS
259 if (is_int_mode (mode, &int_mode)
260 && ! can_compare_p (GE, int_mode, ccp_jump))
d787ba56
RS
261 do_jump_by_parts_greater (int_mode, op0, op1, 1, if_true_label,
262 if_false_label, prob.invert ());
4df62c77 263 else
40e90eac
JJ
264 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
265 prob);
4df62c77
MM
266 break;
267
268 case ORDERED_EXPR:
269 do_compare_and_jump (op0, op1, ORDERED, ORDERED,
40e90eac 270 if_false_label, if_true_label, prob);
4df62c77
MM
271 break;
272
273 case UNORDERED_EXPR:
274 do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
40e90eac 275 if_false_label, if_true_label, prob);
4df62c77
MM
276 break;
277
278 case UNLT_EXPR:
40e90eac
JJ
279 do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
280 prob);
4df62c77
MM
281 break;
282
283 case UNLE_EXPR:
40e90eac
JJ
284 do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
285 prob);
4df62c77
MM
286 break;
287
288 case UNGT_EXPR:
40e90eac
JJ
289 do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
290 prob);
4df62c77
MM
291 break;
292
293 case UNGE_EXPR:
40e90eac
JJ
294 do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
295 prob);
4df62c77
MM
296 break;
297
298 case UNEQ_EXPR:
40e90eac
JJ
299 do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
300 prob);
4df62c77
MM
301 break;
302
303 case LTGT_EXPR:
40e90eac
JJ
304 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
305 prob);
4df62c77
MM
306 break;
307
308 case TRUTH_ANDIF_EXPR:
99206ca9
TJ
309 {
310 /* Spread the probability that the expression is false evenly between
311 the two conditions. So the first condition is false half the total
312 probability of being false. The second condition is false the other
313 half of the total probability of being false, so its jump has a false
314 probability of half the total, relative to the probability we
315 reached it (i.e. the first condition was true). */
357067f2
JH
316 profile_probability op0_prob = profile_probability::uninitialized ();
317 profile_probability op1_prob = profile_probability::uninitialized ();
318 if (prob.initialized_p ())
99206ca9 319 {
f5c517f0
JJ
320 op1_prob = prob.invert ();
321 op0_prob = op1_prob.split (profile_probability::even ());
99206ca9 322 /* Get the probability that each jump below is true. */
f5c517f0
JJ
323 op0_prob = op0_prob.invert ();
324 op1_prob = op1_prob.invert ();
99206ca9 325 }
1476d1bd 326 if (if_false_label == NULL)
99206ca9
TJ
327 {
328 drop_through_label = gen_label_rtx ();
1476d1bd
MM
329 do_jump (op0, drop_through_label, NULL, op0_prob);
330 do_jump (op1, NULL, if_true_label, op1_prob);
99206ca9
TJ
331 }
332 else
333 {
1476d1bd 334 do_jump (op0, if_false_label, NULL, op0_prob);
99206ca9
TJ
335 do_jump (op1, if_false_label, if_true_label, op1_prob);
336 }
337 break;
338 }
4df62c77
MM
339
340 case TRUTH_ORIF_EXPR:
99206ca9
TJ
341 {
342 /* Spread the probability evenly between the two conditions. So
343 the first condition has half the total probability of being true.
344 The second condition has the other half of the total probability,
345 so its jump has a probability of half the total, relative to
346 the probability we reached it (i.e. the first condition was false). */
357067f2
JH
347 profile_probability op0_prob = profile_probability::uninitialized ();
348 profile_probability op1_prob = profile_probability::uninitialized ();
349 if (prob.initialized_p ())
99206ca9 350 {
f5c517f0
JJ
351 op1_prob = prob;
352 op0_prob = op1_prob.split (profile_probability::even ());
1476d1bd
MM
353 }
354 if (if_true_label == NULL)
355 {
356 drop_through_label = gen_label_rtx ();
357 do_jump (op0, NULL, drop_through_label, op0_prob);
358 do_jump (op1, if_false_label, NULL, op1_prob);
359 }
360 else
361 {
362 do_jump (op0, NULL, if_true_label, op0_prob);
363 do_jump (op1, if_false_label, if_true_label, op1_prob);
364 }
99206ca9
TJ
365 break;
366 }
4df62c77
MM
367
368 default:
369 gcc_unreachable ();
370 }
371
372 if (drop_through_label)
373 {
374 do_pending_stack_adjust ();
375 emit_label (drop_through_label);
376 }
377}
378
1cff8964
AE
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
40e90eac
JJ
386 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
387
357067f2 388 PROB is probability of jump to if_true_label. */
1cff8964 389
be099f37 390static void
1476d1bd 391do_jump (tree exp, rtx_code_label *if_false_label,
357067f2 392 rtx_code_label *if_true_label, profile_probability prob)
1cff8964
AE
393{
394 enum tree_code code = TREE_CODE (exp);
1cff8964
AE
395 rtx temp;
396 int i;
397 tree type;
095a2d76 398 scalar_int_mode mode;
1476d1bd 399 rtx_code_label *drop_through_label = NULL;
1cff8964 400
1cff8964
AE
401 switch (code)
402 {
403 case ERROR_MARK:
404 break;
405
406 case INTEGER_CST:
1476d1bd
MM
407 {
408 rtx_code_label *lab = integer_zerop (exp) ? if_false_label
409 : if_true_label;
410 if (lab)
411 emit_jump (lab);
412 break;
413 }
1cff8964
AE
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
82a344f2 424 CASE_CONVERT:
1cff8964
AE
425 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
426 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
427 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
428 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
429 goto normal;
1cff8964
AE
430 /* If we are narrowing the operand, we have to do the compare in the
431 narrower mode. */
432 if ((TYPE_PRECISION (TREE_TYPE (exp))
433 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
434 goto normal;
191816a3 435 /* FALLTHRU */
1cff8964 436 case NON_LVALUE_EXPR:
1cff8964 437 case ABS_EXPR:
e197e64e 438 case ABSU_EXPR:
1cff8964
AE
439 case NEGATE_EXPR:
440 case LROTATE_EXPR:
441 case RROTATE_EXPR:
442 /* These cannot change zero->nonzero or vice versa. */
40e90eac 443 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
1cff8964
AE
444 break;
445
1cff8964 446 case TRUTH_NOT_EXPR:
8ac074e8 447 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
357067f2 448 prob.invert ());
1cff8964
AE
449 break;
450
8ea9d0c7
PB
451 case COND_EXPR:
452 {
19f8b229 453 rtx_code_label *label1 = gen_label_rtx ();
8ea9d0c7
PB
454 if (!if_true_label || !if_false_label)
455 {
456 drop_through_label = gen_label_rtx ();
457 if (!if_true_label)
458 if_true_label = drop_through_label;
459 if (!if_false_label)
460 if_false_label = drop_through_label;
461 }
462
463 do_pending_stack_adjust ();
357067f2
JH
464 do_jump (TREE_OPERAND (exp, 0), label1, NULL,
465 profile_probability::uninitialized ());
40e90eac 466 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
8ea9d0c7 467 emit_label (label1);
40e90eac 468 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
8ea9d0c7
PB
469 break;
470 }
471
1cff8964 472 case COMPOUND_EXPR:
e53b6e56 473 /* Lowered by gimplify.cc. */
ced3f397 474 gcc_unreachable ();
1cff8964 475
0b04d281
DE
476 case MINUS_EXPR:
477 /* Nonzero iff operands of minus differ. */
4df62c77
MM
478 code = NE_EXPR;
479
0b04d281 480 /* FALLTHRU */
4df62c77 481 case EQ_EXPR:
1cff8964 482 case NE_EXPR:
1cff8964 483 case LT_EXPR:
1cff8964 484 case LE_EXPR:
1cff8964 485 case GT_EXPR:
1cff8964 486 case GE_EXPR:
1cff8964 487 case ORDERED_EXPR:
337e5d98 488 case UNORDERED_EXPR:
337e5d98 489 case UNLT_EXPR:
337e5d98 490 case UNLE_EXPR:
337e5d98 491 case UNGT_EXPR:
337e5d98 492 case UNGE_EXPR:
337e5d98 493 case UNEQ_EXPR:
337e5d98 494 case LTGT_EXPR:
4df62c77
MM
495 case TRUTH_ANDIF_EXPR:
496 case TRUTH_ORIF_EXPR:
c3223baf 497 other_code:
4df62c77 498 do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
40e90eac 499 if_false_label, if_true_label, prob);
1cff8964 500 break;
30821654
PB
501
502 case BIT_AND_EXPR:
503 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
504 See if the former is preferred for jump tests and restore it
505 if so. */
506 if (integer_onep (TREE_OPERAND (exp, 1)))
507 {
508 tree exp0 = TREE_OPERAND (exp, 0);
1476d1bd 509 rtx_code_label *set_label, *clr_label;
357067f2 510 profile_probability setclr_prob = prob;
30821654
PB
511
512 /* Strip narrowing integral type conversions. */
513 while (CONVERT_EXPR_P (exp0)
514 && TREE_OPERAND (exp0, 0) != error_mark_node
515 && TYPE_PRECISION (TREE_TYPE (exp0))
516 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
517 exp0 = TREE_OPERAND (exp0, 0);
518
519 /* "exp0 ^ 1" inverts the sense of the single bit test. */
520 if (TREE_CODE (exp0) == BIT_XOR_EXPR
521 && integer_onep (TREE_OPERAND (exp0, 1)))
522 {
523 exp0 = TREE_OPERAND (exp0, 0);
524 clr_label = if_true_label;
525 set_label = if_false_label;
357067f2 526 setclr_prob = prob.invert ();
30821654
PB
527 }
528 else
529 {
530 clr_label = if_false_label;
531 set_label = if_true_label;
532 }
533
534 if (TREE_CODE (exp0) == RSHIFT_EXPR)
535 {
536 tree arg = TREE_OPERAND (exp0, 0);
537 tree shift = TREE_OPERAND (exp0, 1);
538 tree argtype = TREE_TYPE (arg);
539 if (TREE_CODE (shift) == INTEGER_CST
540 && compare_tree_int (shift, 0) >= 0
541 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
7a504f33 542 && prefer_and_bit_test (SCALAR_INT_TYPE_MODE (argtype),
30821654
PB
543 TREE_INT_CST_LOW (shift)))
544 {
472e0df9 545 unsigned HOST_WIDE_INT mask
fecfbfa4 546 = HOST_WIDE_INT_1U << TREE_INT_CST_LOW (shift);
30821654 547 do_jump (build2 (BIT_AND_EXPR, argtype, arg,
1961ffb8 548 build_int_cstu (argtype, mask)),
40e90eac 549 clr_label, set_label, setclr_prob);
30821654
PB
550 break;
551 }
552 }
553 }
554
555 /* If we are AND'ing with a small constant, do this comparison in the
556 smallest type that fits. If the machine doesn't have comparisons
557 that small, it will be converted back to the wider comparison.
558 This helps if we are testing the sign bit of a narrower object.
559 combine can't do this for us because it can't know whether a
560 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
561
562 if (! SLOW_BYTE_ACCESS
563 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
564 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
565 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
fffbab82 566 && int_mode_for_size (i + 1, 0).exists (&mode)
30821654
PB
567 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
568 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
fedc1775 569 && have_insn_for (COMPARE, TYPE_MODE (type)))
30821654 570 {
40e90eac
JJ
571 do_jump (fold_convert (type, exp), if_false_label, if_true_label,
572 prob);
30821654
PB
573 break;
574 }
575
576 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
577 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
578 goto normal;
579
580 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
191816a3 581 /* FALLTHRU */
1cff8964 582
d1f36c51 583 case TRUTH_AND_EXPR:
97191ef9
PB
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. */
3a4fd356
JH
587 if (BRANCH_COST (optimize_insn_for_speed_p (),
588 false) >= 4
589 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 590 goto normal;
c3223baf
MM
591 code = TRUTH_ANDIF_EXPR;
592 goto other_code;
d1f36c51 593
30821654 594 case BIT_IOR_EXPR:
d1f36c51 595 case TRUTH_OR_EXPR:
97191ef9
PB
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. */
40e90eac 599 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
3a4fd356 600 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 601 goto normal;
c3223baf
MM
602 code = TRUTH_ORIF_EXPR;
603 goto other_code;
d1f36c51 604
938d968e 605 /* Fall through and generate the normal code. */
1cff8964
AE
606 default:
607 normal:
84217346 608 temp = expand_normal (exp);
1cff8964 609 do_pending_stack_adjust ();
feb04780
RS
610 /* The RTL optimizers prefer comparisons against pseudos. */
611 if (GET_CODE (temp) == SUBREG)
9311f3f6 612 {
feb04780
RS
613 /* Compare promoted variables in their promoted mode. */
614 if (SUBREG_PROMOTED_VAR_P (temp)
615 && REG_P (XEXP (temp, 0)))
616 temp = XEXP (temp, 0);
617 else
618 temp = copy_to_reg (temp);
9311f3f6 619 }
feb04780
RS
620 do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
621 NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
dc582d2e 622 exp, GET_MODE (temp), NULL_RTX,
40e90eac 623 if_false_label, if_true_label, prob);
1cff8964 624 }
8ea9d0c7
PB
625
626 if (drop_through_label)
627 {
628 do_pending_stack_adjust ();
629 emit_label (drop_through_label);
630 }
1cff8964
AE
631}
632\f
1cff8964
AE
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
3bf78d3b 637static void
d787ba56 638do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0,
1476d1bd
MM
639 rtx op1, rtx_code_label *if_false_label,
640 rtx_code_label *if_true_label,
357067f2 641 profile_probability prob)
1cff8964
AE
642{
643 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
1476d1bd 644 rtx_code_label *drop_through_label = 0;
c8679567
EB
645 bool drop_through_if_true = false, drop_through_if_false = false;
646 enum rtx_code code = GT;
1cff8964
AE
647 int i;
648
649 if (! if_true_label || ! if_false_label)
650 drop_through_label = gen_label_rtx ();
651 if (! if_true_label)
c8679567
EB
652 {
653 if_true_label = drop_through_label;
654 drop_through_if_true = true;
655 }
1cff8964 656 if (! if_false_label)
c8679567
EB
657 {
658 if_false_label = drop_through_label;
659 drop_through_if_false = true;
660 }
661
662 /* Deal with the special case 0 > x: only one comparison is necessary and
663 we reverse it to avoid jumping to the drop-through label. */
664 if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
665 {
666 code = LE;
667 if_true_label = if_false_label;
668 if_false_label = drop_through_label;
357067f2 669 prob = prob.invert ();
c8679567 670 }
1cff8964
AE
671
672 /* Compare a word at a time, high order first. */
673 for (i = 0; i < nwords; i++)
674 {
675 rtx op0_word, op1_word;
676
677 if (WORDS_BIG_ENDIAN)
678 {
679 op0_word = operand_subword_force (op0, i, mode);
680 op1_word = operand_subword_force (op1, i, mode);
681 }
682 else
683 {
684 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
685 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
686 }
687
688 /* All but high-order word must be compared as unsigned. */
c8679567 689 do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
dc582d2e 690 NULL, word_mode, NULL_RTX, NULL, if_true_label,
c8679567
EB
691 prob);
692
693 /* Emit only one comparison for 0. Do not emit the last cond jump. */
694 if (op0 == const0_rtx || i == nwords - 1)
695 break;
1cff8964
AE
696
697 /* Consider lower words only if these are equal. */
dc582d2e
TC
698 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, NULL,
699 word_mode, NULL_RTX, NULL, if_false_label,
357067f2 700 prob.invert ());
1cff8964
AE
701 }
702
c8679567 703 if (!drop_through_if_false)
1cff8964
AE
704 emit_jump (if_false_label);
705 if (drop_through_label)
706 emit_label (drop_through_label);
707}
3bf78d3b
RS
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,
d787ba56 712 and LT if SWAP is 1. MODE is the mode of the two operands. */
3bf78d3b
RS
713
714static void
d787ba56
RS
715do_jump_by_parts_greater (scalar_int_mode mode, tree treeop0, tree treeop1,
716 int swap, rtx_code_label *if_false_label,
357067f2
JH
717 rtx_code_label *if_true_label,
718 profile_probability prob)
3bf78d3b 719{
4df62c77
MM
720 rtx op0 = expand_normal (swap ? treeop1 : treeop0);
721 rtx op1 = expand_normal (swap ? treeop0 : treeop1);
4df62c77 722 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
3bf78d3b
RS
723
724 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
40e90eac 725 if_true_label, prob);
3bf78d3b 726}
1cff8964 727\f
feb04780
RS
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
1476d1bd 730 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL
feb04780 731 to indicate drop through. */
1cff8964 732
feb04780 733static void
d787ba56 734do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0,
1476d1bd 735 rtx_code_label *if_false_label,
357067f2
JH
736 rtx_code_label *if_true_label,
737 profile_probability prob)
1cff8964 738{
feb04780 739 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
1cff8964
AE
740 rtx part;
741 int i;
1476d1bd 742 rtx_code_label *drop_through_label = NULL;
1cff8964
AE
743
744 /* The fastest way of doing this comparison on almost any machine is to
745 "or" all the words and compare the result. If all have to be loaded
746 from memory and this is a very wide item, it's possible this may
747 be slower, but that's highly unlikely. */
748
749 part = gen_reg_rtx (word_mode);
0a49e5c2 750 emit_move_insn (part, operand_subword_force (op0, 0, mode));
1cff8964
AE
751 for (i = 1; i < nwords && part != 0; i++)
752 part = expand_binop (word_mode, ior_optab, part,
0a49e5c2 753 operand_subword_force (op0, i, mode),
1cff8964
AE
754 part, 1, OPTAB_WIDEN);
755
756 if (part != 0)
757 {
dc582d2e 758 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, NULL, word_mode,
40e90eac 759 NULL_RTX, if_false_label, if_true_label, prob);
1cff8964
AE
760 return;
761 }
762
763 /* If we couldn't do the "or" simply, do this with a series of compares. */
764 if (! if_false_label)
1476d1bd 765 if_false_label = drop_through_label = gen_label_rtx ();
1cff8964
AE
766
767 for (i = 0; i < nwords; i++)
0a49e5c2 768 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
dc582d2e 769 const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX,
1476d1bd 770 if_false_label, NULL, prob);
1cff8964
AE
771
772 if (if_true_label)
773 emit_jump (if_true_label);
774
775 if (drop_through_label)
776 emit_label (drop_through_label);
777}
feb04780
RS
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
784static void
d787ba56 785do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1,
1476d1bd 786 rtx_code_label *if_false_label,
357067f2
JH
787 rtx_code_label *if_true_label,
788 profile_probability prob)
feb04780
RS
789{
790 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
1476d1bd 791 rtx_code_label *drop_through_label = NULL;
feb04780
RS
792 int i;
793
794 if (op1 == const0_rtx)
795 {
40e90eac
JJ
796 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
797 prob);
feb04780
RS
798 return;
799 }
800 else if (op0 == const0_rtx)
801 {
40e90eac
JJ
802 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
803 prob);
feb04780
RS
804 return;
805 }
806
807 if (! if_false_label)
808 drop_through_label = if_false_label = gen_label_rtx ();
809
810 for (i = 0; i < nwords; i++)
811 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
dc582d2e
TC
812 operand_subword_force (op1, i, mode),
813 EQ, 0, NULL, word_mode, NULL_RTX,
1476d1bd 814 if_false_label, NULL, prob);
feb04780
RS
815
816 if (if_true_label)
817 emit_jump (if_true_label);
818 if (drop_through_label)
819 emit_label (drop_through_label);
820}
821
822/* Given an EQ_EXPR expression EXP for values too wide to be compared
d787ba56
RS
823 with one insn, test the comparison and jump to the appropriate label.
824 MODE is the mode of the two operands. */
feb04780
RS
825
826static void
d787ba56 827do_jump_by_parts_equality (scalar_int_mode mode, tree treeop0, tree treeop1,
1476d1bd 828 rtx_code_label *if_false_label,
357067f2
JH
829 rtx_code_label *if_true_label,
830 profile_probability prob)
feb04780 831{
4df62c77
MM
832 rtx op0 = expand_normal (treeop0);
833 rtx op1 = expand_normal (treeop1);
feb04780 834 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
40e90eac 835 if_true_label, prob);
feb04780 836}
1cff8964 837\f
337e5d98
PB
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
846bool
ef4bddc2 847split_comparison (enum rtx_code code, machine_mode mode,
337e5d98
PB
848 enum rtx_code *code1, enum rtx_code *code2)
849{
850 switch (code)
851 {
852 case LT:
853 *code1 = ORDERED;
854 *code2 = UNLT;
855 return true;
856 case LE:
857 *code1 = ORDERED;
858 *code2 = UNLE;
859 return true;
860 case GT:
861 *code1 = ORDERED;
862 *code2 = UNGT;
863 return true;
864 case GE:
865 *code1 = ORDERED;
866 *code2 = UNGE;
867 return true;
868 case EQ:
869 *code1 = ORDERED;
870 *code2 = UNEQ;
871 return true;
872 case NE:
873 *code1 = UNORDERED;
874 *code2 = LTGT;
875 return false;
876 case UNLT:
877 *code1 = UNORDERED;
878 *code2 = LT;
879 return false;
880 case UNLE:
881 *code1 = UNORDERED;
882 *code2 = LE;
883 return false;
884 case UNGT:
885 *code1 = UNORDERED;
886 *code2 = GT;
887 return false;
888 case UNGE:
889 *code1 = UNORDERED;
890 *code2 = GE;
891 return false;
892 case UNEQ:
893 *code1 = UNORDERED;
894 *code2 = EQ;
895 return false;
896 case LTGT:
897 /* Do not turn a trapping comparison into a non-trapping one. */
7974a146 898 if (HONOR_NANS (mode))
337e5d98
PB
899 {
900 *code1 = LT;
901 *code2 = GT;
902 return false;
903 }
904 else
905 {
906 *code1 = ORDERED;
907 *code2 = NE;
908 return true;
909 }
910 default:
911 gcc_unreachable ();
912 }
913}
914
be099f37
EB
915/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.
916 PROB is probability of jump to LABEL. */
917
918void
919jumpif (tree exp, rtx_code_label *label, profile_probability prob)
920{
921 do_jump (exp, NULL, label, prob);
922}
923
924/* Similar to jumpif but dealing with exploded comparisons of the type
925 OP0 CODE OP1 . LABEL and PROB are like in jumpif. */
926
927void
928jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
929 profile_probability prob)
930{
931 do_jump_1 (code, op0, op1, NULL, label, prob);
932}
933
934/* Generate code to evaluate EXP and jump to LABEL if the value is zero.
935 PROB is probability of jump to LABEL. */
936
937void
938jumpifnot (tree exp, rtx_code_label *label, profile_probability prob)
939{
940 do_jump (exp, label, NULL, prob.invert ());
941}
942
943/* Similar to jumpifnot but dealing with exploded comparisons of the type
944 OP0 CODE OP1 . LABEL and PROB are like in jumpifnot. */
945
946void
947jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
948 profile_probability prob)
949{
950 do_jump_1 (code, op0, op1, label, NULL, prob.invert ());
951}
337e5d98 952
1cff8964
AE
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
959void
7080f735 960do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
1476d1bd
MM
961 machine_mode mode, rtx size,
962 rtx_code_label *if_false_label,
357067f2
JH
963 rtx_code_label *if_true_label,
964 profile_probability prob)
dc582d2e
TC
965{
966 do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size,
967 if_false_label, if_true_label, prob);
968}
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
976void
977do_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)
1cff8964 982{
1cff8964 983 rtx tem;
1476d1bd 984 rtx_code_label *dummy_label = NULL;
1cff8964
AE
985
986 /* Reverse the comparison if that is safe and we want to jump if it is
337e5d98
PB
987 false. Also convert to the reverse comparison if the target can
988 implement it. */
989 if ((! if_true_label
990 || ! can_compare_p (code, mode, ccp_jump))
991 && (! FLOAT_MODE_P (mode)
992 || code == ORDERED || code == UNORDERED
993 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
994 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
1cff8964 995 {
337e5d98
PB
996 enum rtx_code rcode;
997 if (FLOAT_MODE_P (mode))
998 rcode = reverse_condition_maybe_unordered (code);
999 else
1000 rcode = reverse_condition (code);
1001
1002 /* Canonicalize to UNORDERED for the libcall. */
1003 if (can_compare_p (rcode, mode, ccp_jump)
1004 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
1005 {
00c1cf38 1006 std::swap (if_true_label, if_false_label);
337e5d98 1007 code = rcode;
357067f2 1008 prob = prob.invert ();
337e5d98 1009 }
1cff8964
AE
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 if (swap_commutative_operands_p (op0, op1))
1016 {
00c1cf38 1017 std::swap (op0, op1);
1cff8964
AE
1018 code = swap_condition (code);
1019 }
1020
1cff8964
AE
1021 do_pending_stack_adjust ();
1022
c6fb08ad 1023 code = unsignedp ? unsigned_condition (code) : code;
01512446
JJ
1024 if ((tem = simplify_relational_operation (code, mode, VOIDmode,
1025 op0, op1)) != 0)
1cff8964 1026 {
c6fb08ad
PB
1027 if (CONSTANT_P (tem))
1028 {
1476d1bd
MM
1029 rtx_code_label *label = (tem == const0_rtx
1030 || tem == CONST0_RTX (mode))
1031 ? if_false_label : if_true_label;
c6fb08ad
PB
1032 if (label)
1033 emit_jump (label);
1034 return;
1035 }
1cff8964 1036
c6fb08ad
PB
1037 code = GET_CODE (tem);
1038 mode = GET_MODE (tem);
1039 op0 = XEXP (tem, 0);
1040 op1 = XEXP (tem, 1);
1041 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
1cff8964 1042 }
1cff8964
AE
1043
1044 if (! if_true_label)
337e5d98 1045 dummy_label = if_true_label = gen_label_rtx ();
1cff8964 1046
b4206259
RS
1047 scalar_int_mode int_mode;
1048 if (is_int_mode (mode, &int_mode)
1049 && ! can_compare_p (code, int_mode, ccp_jump))
feb04780
RS
1050 {
1051 switch (code)
1052 {
1053 case LTU:
b4206259 1054 do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
40e90eac 1055 if_false_label, if_true_label, prob);
feb04780
RS
1056 break;
1057
1058 case LEU:
b4206259 1059 do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
40e90eac 1060 if_true_label, if_false_label,
357067f2 1061 prob.invert ());
feb04780
RS
1062 break;
1063
fb9c6d49 1064 case GTU:
b4206259 1065 do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1,
40e90eac 1066 if_false_label, if_true_label, prob);
fb9c6d49
RS
1067 break;
1068
1069 case GEU:
b4206259 1070 do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0,
40e90eac 1071 if_true_label, if_false_label,
357067f2 1072 prob.invert ());
fb9c6d49
RS
1073 break;
1074
feb04780 1075 case LT:
b4206259 1076 do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
40e90eac 1077 if_false_label, if_true_label, prob);
feb04780
RS
1078 break;
1079
1dc5d842 1080 case LE:
b4206259 1081 do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
40e90eac 1082 if_true_label, if_false_label,
357067f2 1083 prob.invert ());
1dc5d842
RS
1084 break;
1085
feb04780 1086 case GT:
b4206259 1087 do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1,
40e90eac 1088 if_false_label, if_true_label, prob);
feb04780
RS
1089 break;
1090
1091 case GE:
b4206259 1092 do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0,
40e90eac 1093 if_true_label, if_false_label,
357067f2 1094 prob.invert ());
feb04780
RS
1095 break;
1096
1097 case EQ:
b4206259 1098 do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_false_label,
40e90eac 1099 if_true_label, prob);
feb04780
RS
1100 break;
1101
1102 case NE:
b4206259 1103 do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_true_label,
357067f2
JH
1104 if_false_label,
1105 prob.invert ());
feb04780
RS
1106 break;
1107
1108 default:
1109 gcc_unreachable ();
1110 }
1111 }
1112 else
337e5d98 1113 {
16e0be9b 1114 if (SCALAR_FLOAT_MODE_P (mode)
337e5d98 1115 && ! can_compare_p (code, mode, ccp_jump)
45475a3f
PB
1116 && can_compare_p (swap_condition (code), mode, ccp_jump))
1117 {
45475a3f 1118 code = swap_condition (code);
fab27f52 1119 std::swap (op0, op1);
45475a3f 1120 }
16e0be9b 1121 else if (SCALAR_FLOAT_MODE_P (mode)
45475a3f 1122 && ! can_compare_p (code, mode, ccp_jump)
2225b9f2
RH
1123 /* Never split ORDERED and UNORDERED.
1124 These must be implemented. */
45475a3f 1125 && (code != ORDERED && code != UNORDERED)
2225b9f2
RH
1126 /* Split a floating-point comparison if
1127 we can jump on other conditions... */
45475a3f 1128 && (have_insn_for (COMPARE, mode)
45475a3f 1129 /* ... or if there is no libcall for it. */
19b5fafb 1130 || code_to_optab (code) == unknown_optab))
337e5d98 1131 {
66dea889 1132 enum rtx_code first_code, orig_code = code;
337e5d98
PB
1133 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 if (!HONOR_NANS (mode))
1138 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1139
66dea889
JJ
1140 else if ((orig_code == EQ || orig_code == NE)
1141 && 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 code = orig_code == EQ ? ORDERED : UNORDERED;
1145
337e5d98
PB
1146 else
1147 {
f5c517f0
JJ
1148 profile_probability cprob
1149 = profile_probability::guessed_always ();
a0dbf285 1150 if (first_code == UNORDERED)
9f55aee9 1151 cprob /= 100;
a0dbf285 1152 else if (first_code == ORDERED)
f5c517f0
JJ
1153 cprob = cprob.apply_scale (99, 100);
1154 else
1155 cprob = profile_probability::even ();
a5c05005 1156 /* For and_them we want to split:
f5c517f0 1157 if (x) goto t; // prob;
a5c05005 1158 goto f;
f5c517f0 1159 into
a5c05005
JJ
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;
f5c517f0 1164 such that the overall probability of jumping to t
a5c05005
JJ
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. */
337e5d98
PB
1181 if (and_them)
1182 {
1476d1bd 1183 rtx_code_label *dest_label;
f5c517f0 1184 prob = prob.invert ();
a5c05005
JJ
1185 profile_probability first_prob
1186 = prob.split (cprob.invert ()).invert ();
f5c517f0 1187 prob = prob.invert ();
337e5d98
PB
1188 /* If we only jump if true, just bypass the second jump. */
1189 if (! if_false_label)
1190 {
1191 if (! dummy_label)
1192 dummy_label = gen_label_rtx ();
1193 dest_label = dummy_label;
1194 }
1195 else
1196 dest_label = if_false_label;
dc582d2e
TC
1197
1198 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
1199 val, mode, size, dest_label, NULL,
1200 first_prob);
337e5d98 1201 }
a5c05005
JJ
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. */
337e5d98 1211 else
f5c517f0
JJ
1212 {
1213 profile_probability first_prob = prob.split (cprob);
dc582d2e
TC
1214 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
1215 val, mode, size, NULL,
1216 if_true_label, first_prob);
680e4202
JJ
1217 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 code = UNEQ;
1225 prob = prob.invert ();
1226 if (! if_false_label)
1227 {
1228 if (! dummy_label)
1229 dummy_label = gen_label_rtx ();
1230 if_false_label = dummy_label;
1231 }
1232 std::swap (if_false_label, if_true_label);
1233 }
f5c517f0 1234 }
337e5d98
PB
1235 }
1236 }
1237
e4e02c07
AS
1238 /* For boolean vectors with less than mode precision
1239 make sure to fill padding with consistent values. */
1240 if (val
1241 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (val))
1242 && SCALAR_INT_MODE_P (mode))
1243 {
1244 auto nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (val)).to_constant ();
1245 if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
1246 {
1247 op0 = expand_binop (mode, and_optab, op0,
1248 GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
1249 NULL_RTX, true, OPTAB_WIDEN);
1250 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
dc582d2e 1256 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val,
a4da41e1 1257 if_true_label, prob);
337e5d98 1258 }
1cff8964
AE
1259
1260 if (if_false_label)
1261 emit_jump (if_false_label);
337e5d98
PB
1262 if (dummy_label)
1263 emit_label (dummy_label);
1cff8964
AE
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
1276static void
4df62c77 1277do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1476d1bd
MM
1278 enum rtx_code unsigned_code,
1279 rtx_code_label *if_false_label,
357067f2 1280 rtx_code_label *if_true_label, profile_probability prob)
1cff8964
AE
1281{
1282 rtx op0, op1;
1283 tree type;
ef4bddc2 1284 machine_mode mode;
1cff8964
AE
1285 int unsignedp;
1286 enum rtx_code code;
1287
1288 /* Don't crash if the comparison was erroneous. */
4df62c77
MM
1289 op0 = expand_normal (treeop0);
1290 if (TREE_CODE (treeop0) == ERROR_MARK)
1cff8964
AE
1291 return;
1292
4df62c77
MM
1293 op1 = expand_normal (treeop1);
1294 if (TREE_CODE (treeop1) == ERROR_MARK)
1cff8964
AE
1295 return;
1296
4df62c77 1297 type = TREE_TYPE (treeop0);
4df62c77
MM
1298 if (TREE_CODE (treeop0) == INTEGER_CST
1299 && (TREE_CODE (treeop1) != INTEGER_CST
7a504f33
RS
1300 || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type))
1301 > 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 type = TREE_TYPE (treeop1);
1305 mode = TYPE_MODE (type);
8df83eae 1306 unsignedp = TYPE_UNSIGNED (type);
1cff8964
AE
1307 code = unsignedp ? unsigned_code : signed_code;
1308
1cff8964 1309 /* If function pointers need to be "canonicalized" before they can
f3743e2e
JDA
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. */
582554e3 1314 if (targetm.have_canonicalize_funcptr_for_compare ()
f3743e2e
JDA
1315 && ((POINTER_TYPE_P (TREE_TYPE (treeop0))
1316 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))))
1317 || (POINTER_TYPE_P (TREE_TYPE (treeop1))
1318 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
1cff8964
AE
1319 {
1320 rtx new_op0 = gen_reg_rtx (mode);
b8c26d70 1321 rtx new_op1 = gen_reg_rtx (mode);
1cff8964 1322
582554e3 1323 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0));
1cff8964 1324 op0 = new_op0;
1cff8964 1325
582554e3 1326 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
1cff8964
AE
1327 op1 = new_op1;
1328 }
1cff8964 1329
dc582d2e
TC
1330 do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode,
1331 ((mode == BLKmode)
1332 ? expr_size (treeop0) : NULL_RTX),
40e90eac 1333 if_false_label, if_true_label, prob);
1cff8964 1334}
dbf833ee
RS
1335
1336#include "gt-dojump.h"