]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gimple-fold.c
re PR middle-end/42834 (memcpy folding overeager)
[thirdparty/gcc.git] / gcc / gimple-fold.c
CommitLineData
cbdd87d4
RG
1/* Statement simplification on GIMPLE.
2 Copyright (C) 2010 Free Software Foundation, Inc.
3 Split out from tree-ssa-ccp.c.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3, or (at your option) any
10later version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "tree.h"
26#include "flags.h"
cbdd87d4 27#include "function.h"
cbdd87d4
RG
28#include "tree-dump.h"
29#include "tree-flow.h"
30#include "tree-pass.h"
31#include "tree-ssa-propagate.h"
cbdd87d4
RG
32#include "target.h"
33
34
35/* If SYM is a constant variable with known value, return the value.
36 NULL_TREE is returned otherwise. */
37
38tree
39get_symbol_constant_value (tree sym)
40{
41 if (TREE_STATIC (sym)
42 && (TREE_READONLY (sym)
43 || TREE_CODE (sym) == CONST_DECL))
44 {
45 tree val = DECL_INITIAL (sym);
46 if (val)
47 {
48 STRIP_NOPS (val);
49 if (is_gimple_min_invariant (val))
50 {
51 if (TREE_CODE (val) == ADDR_EXPR)
52 {
53 tree base = get_base_address (TREE_OPERAND (val, 0));
54 if (base && TREE_CODE (base) == VAR_DECL)
55 {
56 TREE_ADDRESSABLE (base) = 1;
57 if (gimple_referenced_vars (cfun))
58 add_referenced_var (base);
59 }
60 }
61 return val;
62 }
63 }
64 /* Variables declared 'const' without an initializer
65 have zero as the initializer if they may not be
66 overridden at link or run time. */
67 if (!val
68 && !DECL_EXTERNAL (sym)
69 && targetm.binds_local_p (sym)
70 && (INTEGRAL_TYPE_P (TREE_TYPE (sym))
71 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (sym))))
72 return fold_convert (TREE_TYPE (sym), integer_zero_node);
73 }
74
75 return NULL_TREE;
76}
77
78
79/* Return true if we may propagate the address expression ADDR into the
80 dereference DEREF and cancel them. */
81
82bool
83may_propagate_address_into_dereference (tree addr, tree deref)
84{
70f34814 85 gcc_assert (TREE_CODE (deref) == MEM_REF
cbdd87d4
RG
86 && TREE_CODE (addr) == ADDR_EXPR);
87
88 /* Don't propagate if ADDR's operand has incomplete type. */
89 if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_OPERAND (addr, 0))))
90 return false;
91
92 /* If the address is invariant then we do not need to preserve restrict
93 qualifications. But we do need to preserve volatile qualifiers until
94 we can annotate the folded dereference itself properly. */
95 if (is_gimple_min_invariant (addr)
96 && (!TREE_THIS_VOLATILE (deref)
97 || TYPE_VOLATILE (TREE_TYPE (addr))))
98 return useless_type_conversion_p (TREE_TYPE (deref),
99 TREE_TYPE (TREE_OPERAND (addr, 0)));
100
101 /* Else both the address substitution and the folding must result in
102 a valid useless type conversion sequence. */
103 return (useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (deref, 0)),
104 TREE_TYPE (addr))
105 && useless_type_conversion_p (TREE_TYPE (deref),
106 TREE_TYPE (TREE_OPERAND (addr, 0))));
107}
108
109
110/* A subroutine of fold_stmt. Attempts to fold *(A+O) to A[X].
70f34814 111 BASE is an array type. OFFSET is a byte displacement.
cbdd87d4
RG
112
113 LOC is the location of the original expression. */
114
115static tree
70f34814 116maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset)
cbdd87d4
RG
117{
118 tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
119 tree array_type, elt_type, elt_size;
120 tree domain_type;
121
122 /* If BASE is an ARRAY_REF, we can pick up another offset (this time
123 measured in units of the size of elements type) from that ARRAY_REF).
124 We can't do anything if either is variable.
125
126 The case we handle here is *(&A[N]+O). */
127 if (TREE_CODE (base) == ARRAY_REF)
128 {
129 tree low_bound = array_ref_low_bound (base);
130
131 elt_offset = TREE_OPERAND (base, 1);
132 if (TREE_CODE (low_bound) != INTEGER_CST
133 || TREE_CODE (elt_offset) != INTEGER_CST)
134 return NULL_TREE;
135
136 elt_offset = int_const_binop (MINUS_EXPR, elt_offset, low_bound, 0);
137 base = TREE_OPERAND (base, 0);
138 }
139
140 /* Ignore stupid user tricks of indexing non-array variables. */
141 array_type = TREE_TYPE (base);
142 if (TREE_CODE (array_type) != ARRAY_TYPE)
143 return NULL_TREE;
144 elt_type = TREE_TYPE (array_type);
cbdd87d4
RG
145
146 /* Use signed size type for intermediate computation on the index. */
3b9e5d95 147 idx_type = ssizetype;
cbdd87d4
RG
148
149 /* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the
150 element type (so we can use the alignment if it's not constant).
151 Otherwise, compute the offset as an index by using a division. If the
152 division isn't exact, then don't do anything. */
153 elt_size = TYPE_SIZE_UNIT (elt_type);
154 if (!elt_size)
155 return NULL;
156 if (integer_zerop (offset))
157 {
158 if (TREE_CODE (elt_size) != INTEGER_CST)
159 elt_size = size_int (TYPE_ALIGN (elt_type));
160
161 idx = build_int_cst (idx_type, 0);
162 }
163 else
164 {
165 unsigned HOST_WIDE_INT lquo, lrem;
166 HOST_WIDE_INT hquo, hrem;
167 double_int soffset;
168
169 /* The final array offset should be signed, so we need
170 to sign-extend the (possibly pointer) offset here
171 and use signed division. */
172 soffset = double_int_sext (tree_to_double_int (offset),
173 TYPE_PRECISION (TREE_TYPE (offset)));
174 if (TREE_CODE (elt_size) != INTEGER_CST
175 || div_and_round_double (TRUNC_DIV_EXPR, 0,
176 soffset.low, soffset.high,
177 TREE_INT_CST_LOW (elt_size),
178 TREE_INT_CST_HIGH (elt_size),
179 &lquo, &hquo, &lrem, &hrem)
180 || lrem || hrem)
181 return NULL_TREE;
182
183 idx = build_int_cst_wide (idx_type, lquo, hquo);
184 }
185
186 /* Assume the low bound is zero. If there is a domain type, get the
187 low bound, if any, convert the index into that type, and add the
188 low bound. */
189 min_idx = build_int_cst (idx_type, 0);
190 domain_type = TYPE_DOMAIN (array_type);
191 if (domain_type)
192 {
193 idx_type = domain_type;
194 if (TYPE_MIN_VALUE (idx_type))
195 min_idx = TYPE_MIN_VALUE (idx_type);
196 else
197 min_idx = fold_convert (idx_type, min_idx);
198
199 if (TREE_CODE (min_idx) != INTEGER_CST)
200 return NULL_TREE;
201
202 elt_offset = fold_convert (idx_type, elt_offset);
203 }
204
205 if (!integer_zerop (min_idx))
206 idx = int_const_binop (PLUS_EXPR, idx, min_idx, 0);
207 if (!integer_zerop (elt_offset))
208 idx = int_const_binop (PLUS_EXPR, idx, elt_offset, 0);
209
210 /* Make sure to possibly truncate late after offsetting. */
211 idx = fold_convert (idx_type, idx);
212
213 /* We don't want to construct access past array bounds. For example
214 char *(c[4]);
215 c[3][2];
216 should not be simplified into (*c)[14] or tree-vrp will
70f34814
RG
217 give false warnings.
218 This is only an issue for multi-dimensional arrays. */
219 if (TREE_CODE (elt_type) == ARRAY_TYPE
220 && domain_type)
cbdd87d4 221 {
70f34814
RG
222 if (TYPE_MAX_VALUE (domain_type)
223 && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST
224 && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type), idx))
cbdd87d4 225 return NULL_TREE;
70f34814
RG
226 else if (TYPE_MIN_VALUE (domain_type)
227 && TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST
228 && tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type)))
229 return NULL_TREE;
230 else if (compare_tree_int (idx, 0) < 0)
cbdd87d4
RG
231 return NULL_TREE;
232 }
cbdd87d4
RG
233
234 {
235 tree t = build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
236 SET_EXPR_LOCATION (t, loc);
237 return t;
238 }
239}
240
241
70f34814 242/* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE[index].
cbdd87d4
RG
243 LOC is the location of original expression.
244
70f34814 245 Before attempting the conversion strip off existing ADDR_EXPRs. */
cbdd87d4
RG
246
247tree
248maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
249 tree orig_type)
250{
251 tree ret;
cbdd87d4
RG
252
253 STRIP_NOPS (base);
254 if (TREE_CODE (base) != ADDR_EXPR)
255 return NULL_TREE;
256
257 base = TREE_OPERAND (base, 0);
70f34814 258 if (types_compatible_p (orig_type, TREE_TYPE (base))
cbdd87d4
RG
259 && integer_zerop (offset))
260 return base;
cbdd87d4 261
70f34814
RG
262 ret = maybe_fold_offset_to_array_ref (loc, base, offset);
263 if (ret && types_compatible_p (orig_type, TREE_TYPE (ret)))
264 return ret;
265 return NULL_TREE;
cbdd87d4
RG
266}
267
70f34814
RG
268/* Attempt to express (ORIG_TYPE)ADDR+OFFSET as (*ADDR)[index].
269 LOC is the location of the original expression. */
cbdd87d4
RG
270
271tree
272maybe_fold_offset_to_address (location_t loc, tree addr, tree offset,
273 tree orig_type)
274{
70f34814 275 tree base, ret;
cbdd87d4 276
70f34814
RG
277 STRIP_NOPS (addr);
278 if (TREE_CODE (addr) != ADDR_EXPR)
279 return NULL_TREE;
280 base = TREE_OPERAND (addr, 0);
281 ret = maybe_fold_offset_to_array_ref (loc, base, offset);
282 if (ret)
cbdd87d4 283 {
70f34814
RG
284 ret = build_fold_addr_expr (ret);
285 if (!useless_type_conversion_p (orig_type, TREE_TYPE (ret)))
cbdd87d4 286 return NULL_TREE;
70f34814 287 SET_EXPR_LOCATION (ret, loc);
cbdd87d4
RG
288 }
289
70f34814 290 return ret;
cbdd87d4
RG
291}
292
293
294/* A quaint feature extant in our address arithmetic is that there
295 can be hidden type changes here. The type of the result need
296 not be the same as the type of the input pointer.
297
298 What we're after here is an expression of the form
299 (T *)(&array + const)
300 where array is OP0, const is OP1, RES_TYPE is T and
301 the cast doesn't actually exist, but is implicit in the
302 type of the POINTER_PLUS_EXPR. We'd like to turn this into
303 &array[x]
304 which may be able to propagate further. */
305
306tree
307maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1)
308{
309 tree ptd_type;
310 tree t;
311
312 /* The first operand should be an ADDR_EXPR. */
313 if (TREE_CODE (op0) != ADDR_EXPR)
314 return NULL_TREE;
315 op0 = TREE_OPERAND (op0, 0);
316
317 /* It had better be a constant. */
318 if (TREE_CODE (op1) != INTEGER_CST)
319 {
320 /* Or op0 should now be A[0] and the non-constant offset defined
321 via a multiplication by the array element size. */
322 if (TREE_CODE (op0) == ARRAY_REF
c946a318
RG
323 /* As we will end up creating a variable index array access
324 in the outermost array dimension make sure there isn't
325 a more inner array that the index could overflow to. */
70f34814
RG
326 && TREE_CODE (TREE_OPERAND (op0, 0)) != ARRAY_REF
327 && integer_zerop (TREE_OPERAND (op0, 1))
328 && TREE_CODE (op1) == SSA_NAME)
329 {
330 gimple offset_def = SSA_NAME_DEF_STMT (op1);
331 tree elsz = TYPE_SIZE_UNIT (TREE_TYPE (op0));
332 if (!host_integerp (elsz, 1)
333 || !is_gimple_assign (offset_def))
c946a318
RG
334 return NULL_TREE;
335
336 /* Do not build array references of something that we can't
337 see the true number of array dimensions for. */
338 if (!DECL_P (TREE_OPERAND (op0, 0))
339 && !handled_component_p (TREE_OPERAND (op0, 0)))
340 return NULL_TREE;
341
cbdd87d4
RG
342 if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
343 && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
70f34814 344 && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), elsz))
cbdd87d4
RG
345 return build_fold_addr_expr
346 (build4 (ARRAY_REF, TREE_TYPE (op0),
347 TREE_OPERAND (op0, 0),
348 gimple_assign_rhs1 (offset_def),
349 TREE_OPERAND (op0, 2),
350 TREE_OPERAND (op0, 3)));
70f34814 351 else if (integer_onep (elsz)
cbdd87d4
RG
352 && gimple_assign_rhs_code (offset_def) != MULT_EXPR)
353 return build_fold_addr_expr
354 (build4 (ARRAY_REF, TREE_TYPE (op0),
355 TREE_OPERAND (op0, 0),
356 op1,
357 TREE_OPERAND (op0, 2),
358 TREE_OPERAND (op0, 3)));
359 }
70f34814
RG
360 else if (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
361 /* Dto. */
362 && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) != ARRAY_TYPE
363 && TREE_CODE (op1) == SSA_NAME)
364 {
365 gimple offset_def = SSA_NAME_DEF_STMT (op1);
366 tree elsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (op0)));
367 if (!host_integerp (elsz, 1)
368 || !is_gimple_assign (offset_def))
369 return NULL_TREE;
370
371 /* Do not build array references of something that we can't
372 see the true number of array dimensions for. */
373 if (!DECL_P (op0)
374 && !handled_component_p (op0))
375 return NULL_TREE;
376
377 if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
378 && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
379 && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), elsz))
380 return build_fold_addr_expr
381 (build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (op0)),
382 op0, gimple_assign_rhs1 (offset_def),
383 integer_zero_node, NULL_TREE));
384 else if (integer_onep (elsz)
385 && gimple_assign_rhs_code (offset_def) != MULT_EXPR)
386 return build_fold_addr_expr
387 (build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (op0)),
388 op0, op1,
389 integer_zero_node, NULL_TREE));
390 }
391
cbdd87d4
RG
392 return NULL_TREE;
393 }
394
395 /* If the first operand is an ARRAY_REF, expand it so that we can fold
396 the offset into it. */
397 while (TREE_CODE (op0) == ARRAY_REF)
398 {
399 tree array_obj = TREE_OPERAND (op0, 0);
400 tree array_idx = TREE_OPERAND (op0, 1);
401 tree elt_type = TREE_TYPE (op0);
402 tree elt_size = TYPE_SIZE_UNIT (elt_type);
403 tree min_idx;
404
405 if (TREE_CODE (array_idx) != INTEGER_CST)
406 break;
407 if (TREE_CODE (elt_size) != INTEGER_CST)
408 break;
409
410 /* Un-bias the index by the min index of the array type. */
411 min_idx = TYPE_DOMAIN (TREE_TYPE (array_obj));
412 if (min_idx)
413 {
414 min_idx = TYPE_MIN_VALUE (min_idx);
415 if (min_idx)
416 {
417 if (TREE_CODE (min_idx) != INTEGER_CST)
418 break;
419
420 array_idx = fold_convert (TREE_TYPE (min_idx), array_idx);
421 if (!integer_zerop (min_idx))
422 array_idx = int_const_binop (MINUS_EXPR, array_idx,
423 min_idx, 0);
424 }
425 }
426
427 /* Convert the index to a byte offset. */
428 array_idx = fold_convert (sizetype, array_idx);
429 array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
430
431 /* Update the operands for the next round, or for folding. */
432 op1 = int_const_binop (PLUS_EXPR,
433 array_idx, op1, 0);
434 op0 = array_obj;
435 }
436
437 ptd_type = TREE_TYPE (res_type);
438 /* If we want a pointer to void, reconstruct the reference from the
439 array element type. A pointer to that can be trivially converted
440 to void *. This happens as we fold (void *)(ptr p+ off). */
441 if (VOID_TYPE_P (ptd_type)
442 && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
443 ptd_type = TREE_TYPE (TREE_TYPE (op0));
444
445 /* At which point we can try some of the same things as for indirects. */
70f34814 446 t = maybe_fold_offset_to_array_ref (loc, op0, op1);
cbdd87d4
RG
447 if (t)
448 {
70f34814
RG
449 t = build_fold_addr_expr (t);
450 if (!useless_type_conversion_p (res_type, TREE_TYPE (t)))
451 return NULL_TREE;
cbdd87d4
RG
452 SET_EXPR_LOCATION (t, loc);
453 }
454
455 return t;
456}
457
458/* Subroutine of fold_stmt. We perform several simplifications of the
459 memory reference tree EXPR and make sure to re-gimplify them properly
460 after propagation of constant addresses. IS_LHS is true if the
461 reference is supposed to be an lvalue. */
462
463static tree
464maybe_fold_reference (tree expr, bool is_lhs)
465{
466 tree *t = &expr;
467
468 if (TREE_CODE (expr) == ARRAY_REF
469 && !is_lhs)
470 {
471 tree tem = fold_read_from_constant_string (expr);
472 if (tem)
473 return tem;
474 }
475
476 /* ??? We might want to open-code the relevant remaining cases
477 to avoid using the generic fold. */
478 if (handled_component_p (*t)
479 && CONSTANT_CLASS_P (TREE_OPERAND (*t, 0)))
480 {
481 tree tem = fold (*t);
482 if (tem != *t)
483 return tem;
484 }
485
486 while (handled_component_p (*t))
487 t = &TREE_OPERAND (*t, 0);
488
70f34814
RG
489 /* Fold back MEM_REFs to reference trees. */
490 if (TREE_CODE (*t) == MEM_REF
491 && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
492 && integer_zerop (TREE_OPERAND (*t, 1))
493 && (TREE_THIS_VOLATILE (*t)
494 == TREE_THIS_VOLATILE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0)))
495 && !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*t, 1)))
496 && (TYPE_MAIN_VARIANT (TREE_TYPE (*t))
497 == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (*t, 1)))))
498 /* We have to look out here to not drop a required conversion
499 from the rhs to the lhs if is_lhs, but we don't have the
500 rhs here to verify that. Thus require strict type
501 compatibility. */
502 && types_compatible_p (TREE_TYPE (*t),
503 TREE_TYPE (TREE_OPERAND
504 (TREE_OPERAND (*t, 0), 0))))
cbdd87d4 505 {
70f34814
RG
506 tree tem;
507 *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
508 tem = maybe_fold_reference (expr, is_lhs);
509 if (tem)
510 return tem;
511 return expr;
512 }
513 /* Canonicalize MEM_REFs invariant address operand. */
514 else if (TREE_CODE (*t) == MEM_REF
515 && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
516 && !DECL_P (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))
517 && !CONSTANT_CLASS_P (TREE_OPERAND (TREE_OPERAND (*t, 0), 0)))
518 {
519 tree tem = fold_binary (MEM_REF, TREE_TYPE (*t),
520 TREE_OPERAND (*t, 0),
521 TREE_OPERAND (*t, 1));
cbdd87d4
RG
522 if (tem)
523 {
524 *t = tem;
525 tem = maybe_fold_reference (expr, is_lhs);
526 if (tem)
527 return tem;
528 return expr;
529 }
530 }
531 else if (!is_lhs
532 && DECL_P (*t))
533 {
534 tree tem = get_symbol_constant_value (*t);
535 if (tem
536 && useless_type_conversion_p (TREE_TYPE (*t), TREE_TYPE (tem)))
537 {
538 *t = unshare_expr (tem);
539 tem = maybe_fold_reference (expr, is_lhs);
540 if (tem)
541 return tem;
542 return expr;
543 }
544 }
545
546 return NULL_TREE;
547}
548
549
550/* Attempt to fold an assignment statement pointed-to by SI. Returns a
551 replacement rhs for the statement or NULL_TREE if no simplification
552 could be made. It is assumed that the operands have been previously
553 folded. */
554
555static tree
556fold_gimple_assign (gimple_stmt_iterator *si)
557{
558 gimple stmt = gsi_stmt (*si);
559 enum tree_code subcode = gimple_assign_rhs_code (stmt);
560 location_t loc = gimple_location (stmt);
561
562 tree result = NULL_TREE;
563
564 switch (get_gimple_rhs_class (subcode))
565 {
566 case GIMPLE_SINGLE_RHS:
567 {
568 tree rhs = gimple_assign_rhs1 (stmt);
569
570 /* Try to fold a conditional expression. */
571 if (TREE_CODE (rhs) == COND_EXPR)
572 {
573 tree op0 = COND_EXPR_COND (rhs);
574 tree tem;
575 bool set = false;
576 location_t cond_loc = EXPR_LOCATION (rhs);
577
578 if (COMPARISON_CLASS_P (op0))
579 {
580 fold_defer_overflow_warnings ();
581 tem = fold_binary_loc (cond_loc,
582 TREE_CODE (op0), TREE_TYPE (op0),
583 TREE_OPERAND (op0, 0),
584 TREE_OPERAND (op0, 1));
585 /* This is actually a conditional expression, not a GIMPLE
586 conditional statement, however, the valid_gimple_rhs_p
587 test still applies. */
588 set = (tem && is_gimple_condexpr (tem)
589 && valid_gimple_rhs_p (tem));
590 fold_undefer_overflow_warnings (set, stmt, 0);
591 }
592 else if (is_gimple_min_invariant (op0))
593 {
594 tem = op0;
595 set = true;
596 }
597 else
598 return NULL_TREE;
599
600 if (set)
601 result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), tem,
602 COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
603 }
604
605 else if (TREE_CODE (rhs) == TARGET_MEM_REF)
606 return maybe_fold_tmr (rhs);
607
608 else if (REFERENCE_CLASS_P (rhs))
609 return maybe_fold_reference (rhs, false);
610
611 else if (TREE_CODE (rhs) == ADDR_EXPR)
612 {
70f34814
RG
613 tree ref = TREE_OPERAND (rhs, 0);
614 tree tem = maybe_fold_reference (ref, true);
615 if (tem
616 && TREE_CODE (tem) == MEM_REF
617 && integer_zerop (TREE_OPERAND (tem, 1)))
618 result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (tem, 0));
619 else if (tem)
cbdd87d4
RG
620 result = fold_convert (TREE_TYPE (rhs),
621 build_fold_addr_expr_loc (loc, tem));
70f34814
RG
622 else if (TREE_CODE (ref) == MEM_REF
623 && integer_zerop (TREE_OPERAND (ref, 1)))
624 result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0));
cbdd87d4
RG
625 }
626
627 else if (TREE_CODE (rhs) == CONSTRUCTOR
628 && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
629 && (CONSTRUCTOR_NELTS (rhs)
630 == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
631 {
632 /* Fold a constant vector CONSTRUCTOR to VECTOR_CST. */
633 unsigned i;
634 tree val;
635
636 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
637 if (TREE_CODE (val) != INTEGER_CST
638 && TREE_CODE (val) != REAL_CST
639 && TREE_CODE (val) != FIXED_CST)
640 return NULL_TREE;
641
642 return build_vector_from_ctor (TREE_TYPE (rhs),
643 CONSTRUCTOR_ELTS (rhs));
644 }
645
646 else if (DECL_P (rhs))
647 return unshare_expr (get_symbol_constant_value (rhs));
648
649 /* If we couldn't fold the RHS, hand over to the generic
650 fold routines. */
651 if (result == NULL_TREE)
652 result = fold (rhs);
653
654 /* Strip away useless type conversions. Both the NON_LVALUE_EXPR
655 that may have been added by fold, and "useless" type
656 conversions that might now be apparent due to propagation. */
657 STRIP_USELESS_TYPE_CONVERSION (result);
658
659 if (result != rhs && valid_gimple_rhs_p (result))
660 return result;
661
662 return NULL_TREE;
663 }
664 break;
665
666 case GIMPLE_UNARY_RHS:
667 {
668 tree rhs = gimple_assign_rhs1 (stmt);
669
670 result = fold_unary_loc (loc, subcode, gimple_expr_type (stmt), rhs);
671 if (result)
672 {
673 /* If the operation was a conversion do _not_ mark a
674 resulting constant with TREE_OVERFLOW if the original
675 constant was not. These conversions have implementation
676 defined behavior and retaining the TREE_OVERFLOW flag
677 here would confuse later passes such as VRP. */
678 if (CONVERT_EXPR_CODE_P (subcode)
679 && TREE_CODE (result) == INTEGER_CST
680 && TREE_CODE (rhs) == INTEGER_CST)
681 TREE_OVERFLOW (result) = TREE_OVERFLOW (rhs);
682
683 STRIP_USELESS_TYPE_CONVERSION (result);
684 if (valid_gimple_rhs_p (result))
685 return result;
686 }
687 else if (CONVERT_EXPR_CODE_P (subcode)
688 && POINTER_TYPE_P (gimple_expr_type (stmt))
689 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
690 {
691 tree type = gimple_expr_type (stmt);
692 tree t = maybe_fold_offset_to_address (loc,
693 gimple_assign_rhs1 (stmt),
694 integer_zero_node, type);
695 if (t)
696 return t;
697 }
698 }
699 break;
700
701 case GIMPLE_BINARY_RHS:
702 /* Try to fold pointer addition. */
703 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
704 {
705 tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
706 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
707 {
708 type = build_pointer_type (TREE_TYPE (TREE_TYPE (type)));
709 if (!useless_type_conversion_p
710 (TREE_TYPE (gimple_assign_lhs (stmt)), type))
711 type = TREE_TYPE (gimple_assign_rhs1 (stmt));
712 }
713 result = maybe_fold_stmt_addition (gimple_location (stmt),
714 type,
715 gimple_assign_rhs1 (stmt),
716 gimple_assign_rhs2 (stmt));
717 }
718
719 if (!result)
720 result = fold_binary_loc (loc, subcode,
721 TREE_TYPE (gimple_assign_lhs (stmt)),
722 gimple_assign_rhs1 (stmt),
723 gimple_assign_rhs2 (stmt));
724
725 if (result)
726 {
727 STRIP_USELESS_TYPE_CONVERSION (result);
728 if (valid_gimple_rhs_p (result))
729 return result;
730
731 /* Fold might have produced non-GIMPLE, so if we trust it blindly
732 we lose canonicalization opportunities. Do not go again
733 through fold here though, or the same non-GIMPLE will be
734 produced. */
735 if (commutative_tree_code (subcode)
736 && tree_swap_operands_p (gimple_assign_rhs1 (stmt),
737 gimple_assign_rhs2 (stmt), false))
738 return build2 (subcode, TREE_TYPE (gimple_assign_lhs (stmt)),
739 gimple_assign_rhs2 (stmt),
740 gimple_assign_rhs1 (stmt));
741 }
742 break;
743
0354c0c7
BS
744 case GIMPLE_TERNARY_RHS:
745 result = fold_ternary_loc (loc, subcode,
746 TREE_TYPE (gimple_assign_lhs (stmt)),
747 gimple_assign_rhs1 (stmt),
748 gimple_assign_rhs2 (stmt),
749 gimple_assign_rhs3 (stmt));
750
751 if (result)
752 {
753 STRIP_USELESS_TYPE_CONVERSION (result);
754 if (valid_gimple_rhs_p (result))
755 return result;
756
757 /* Fold might have produced non-GIMPLE, so if we trust it blindly
758 we lose canonicalization opportunities. Do not go again
759 through fold here though, or the same non-GIMPLE will be
760 produced. */
761 if (commutative_ternary_tree_code (subcode)
762 && tree_swap_operands_p (gimple_assign_rhs1 (stmt),
763 gimple_assign_rhs2 (stmt), false))
764 return build3 (subcode, TREE_TYPE (gimple_assign_lhs (stmt)),
765 gimple_assign_rhs2 (stmt),
766 gimple_assign_rhs1 (stmt),
767 gimple_assign_rhs3 (stmt));
768 }
769 break;
770
cbdd87d4
RG
771 case GIMPLE_INVALID_RHS:
772 gcc_unreachable ();
773 }
774
775 return NULL_TREE;
776}
777
778/* Attempt to fold a conditional statement. Return true if any changes were
779 made. We only attempt to fold the condition expression, and do not perform
780 any transformation that would require alteration of the cfg. It is
781 assumed that the operands have been previously folded. */
782
783static bool
784fold_gimple_cond (gimple stmt)
785{
786 tree result = fold_binary_loc (gimple_location (stmt),
787 gimple_cond_code (stmt),
788 boolean_type_node,
789 gimple_cond_lhs (stmt),
790 gimple_cond_rhs (stmt));
791
792 if (result)
793 {
794 STRIP_USELESS_TYPE_CONVERSION (result);
795 if (is_gimple_condexpr (result) && valid_gimple_rhs_p (result))
796 {
797 gimple_cond_set_condition_from_tree (stmt, result);
798 return true;
799 }
800 }
801
802 return false;
803}
804
805/* Convert EXPR into a GIMPLE value suitable for substitution on the
806 RHS of an assignment. Insert the necessary statements before
807 iterator *SI_P. The statement at *SI_P, which must be a GIMPLE_CALL
808 is replaced. If the call is expected to produces a result, then it
809 is replaced by an assignment of the new RHS to the result variable.
810 If the result is to be ignored, then the call is replaced by a
fe2ef088
MM
811 GIMPLE_NOP. A proper VDEF chain is retained by making the first
812 VUSE and the last VDEF of the whole sequence be the same as the replaced
813 statement and using new SSA names for stores in between. */
cbdd87d4
RG
814
815void
816gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
817{
818 tree lhs;
819 tree tmp = NULL_TREE; /* Silence warning. */
820 gimple stmt, new_stmt;
821 gimple_stmt_iterator i;
822 gimple_seq stmts = gimple_seq_alloc();
823 struct gimplify_ctx gctx;
824 gimple last = NULL;
fe2ef088
MM
825 gimple laststore = NULL;
826 tree reaching_vuse;
cbdd87d4
RG
827
828 stmt = gsi_stmt (*si_p);
829
830 gcc_assert (is_gimple_call (stmt));
831
832 lhs = gimple_call_lhs (stmt);
fe2ef088 833 reaching_vuse = gimple_vuse (stmt);
cbdd87d4
RG
834
835 push_gimplify_context (&gctx);
836
837 if (lhs == NULL_TREE)
838 gimplify_and_add (expr, &stmts);
839 else
840 tmp = get_initialized_tmp_var (expr, &stmts, NULL);
841
842 pop_gimplify_context (NULL);
843
844 if (gimple_has_location (stmt))
845 annotate_all_with_location (stmts, gimple_location (stmt));
846
847 /* The replacement can expose previously unreferenced variables. */
848 for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
849 {
850 if (last)
851 {
852 gsi_insert_before (si_p, last, GSI_NEW_STMT);
853 gsi_next (si_p);
854 }
855 new_stmt = gsi_stmt (i);
856 find_new_referenced_vars (new_stmt);
857 mark_symbols_for_renaming (new_stmt);
fe2ef088
MM
858 /* If the new statement has a VUSE, update it with exact SSA name we
859 know will reach this one. */
860 if (gimple_vuse (new_stmt))
861 {
862 /* If we've also seen a previous store create a new VDEF for
863 the latter one, and make that the new reaching VUSE. */
864 if (laststore)
865 {
866 reaching_vuse = make_ssa_name (gimple_vop (cfun), laststore);
867 gimple_set_vdef (laststore, reaching_vuse);
868 update_stmt (laststore);
869 laststore = NULL;
870 }
871 gimple_set_vuse (new_stmt, reaching_vuse);
872 gimple_set_modified (new_stmt, true);
873 }
874 if (gimple_assign_single_p (new_stmt)
875 && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
876 {
877 laststore = new_stmt;
878 }
cbdd87d4
RG
879 last = new_stmt;
880 }
881
882 if (lhs == NULL_TREE)
883 {
fe2ef088
MM
884 /* If we replace a call without LHS that has a VDEF and our new
885 sequence ends with a store we must make that store have the same
886 vdef in order not to break the sequencing. This can happen
887 for instance when folding memcpy calls into assignments. */
888 if (gimple_vdef (stmt) && laststore)
889 {
890 gimple_set_vdef (laststore, gimple_vdef (stmt));
8a1561bc
MM
891 if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
892 SSA_NAME_DEF_STMT (gimple_vdef (stmt)) = laststore;
fe2ef088
MM
893 update_stmt (laststore);
894 }
895 else
896 {
897 unlink_stmt_vdef (stmt);
898 release_defs (stmt);
899 }
cbdd87d4
RG
900 new_stmt = last;
901 }
902 else
903 {
904 if (last)
905 {
906 gsi_insert_before (si_p, last, GSI_NEW_STMT);
907 gsi_next (si_p);
908 }
8a1561bc
MM
909 if (laststore && is_gimple_reg (lhs))
910 {
911 gimple_set_vdef (laststore, gimple_vdef (stmt));
912 update_stmt (laststore);
913 if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
914 SSA_NAME_DEF_STMT (gimple_vdef (stmt)) = laststore;
915 laststore = NULL;
916 }
917 else if (laststore)
fe2ef088
MM
918 {
919 reaching_vuse = make_ssa_name (gimple_vop (cfun), laststore);
920 gimple_set_vdef (laststore, reaching_vuse);
921 update_stmt (laststore);
922 laststore = NULL;
923 }
cbdd87d4 924 new_stmt = gimple_build_assign (lhs, tmp);
8a1561bc
MM
925 if (!is_gimple_reg (tmp))
926 gimple_set_vuse (new_stmt, reaching_vuse);
927 if (!is_gimple_reg (lhs))
928 {
929 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
930 if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
931 SSA_NAME_DEF_STMT (gimple_vdef (stmt)) = new_stmt;
932 }
cbdd87d4
RG
933 }
934
935 gimple_set_location (new_stmt, gimple_location (stmt));
936 gsi_replace (si_p, new_stmt, false);
937}
938
939/* Return the string length, maximum string length or maximum value of
940 ARG in LENGTH.
941 If ARG is an SSA name variable, follow its use-def chains. If LENGTH
942 is not NULL and, for TYPE == 0, its value is not equal to the length
943 we determine or if we are unable to determine the length or value,
944 return false. VISITED is a bitmap of visited variables.
945 TYPE is 0 if string length should be returned, 1 for maximum string
946 length and 2 for maximum value ARG can have. */
947
948static bool
949get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
950{
951 tree var, val;
952 gimple def_stmt;
953
954 if (TREE_CODE (arg) != SSA_NAME)
955 {
956 if (TREE_CODE (arg) == COND_EXPR)
957 return get_maxval_strlen (COND_EXPR_THEN (arg), length, visited, type)
958 && get_maxval_strlen (COND_EXPR_ELSE (arg), length, visited, type);
959 /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
960 else if (TREE_CODE (arg) == ADDR_EXPR
961 && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF
962 && integer_zerop (TREE_OPERAND (TREE_OPERAND (arg, 0), 1)))
963 {
964 tree aop0 = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
965 if (TREE_CODE (aop0) == INDIRECT_REF
966 && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
967 return get_maxval_strlen (TREE_OPERAND (aop0, 0),
968 length, visited, type);
969 }
970
971 if (type == 2)
972 {
973 val = arg;
974 if (TREE_CODE (val) != INTEGER_CST
975 || tree_int_cst_sgn (val) < 0)
976 return false;
977 }
978 else
979 val = c_strlen (arg, 1);
980 if (!val)
981 return false;
982
983 if (*length)
984 {
985 if (type > 0)
986 {
987 if (TREE_CODE (*length) != INTEGER_CST
988 || TREE_CODE (val) != INTEGER_CST)
989 return false;
990
991 if (tree_int_cst_lt (*length, val))
992 *length = val;
993 return true;
994 }
995 else if (simple_cst_equal (val, *length) != 1)
996 return false;
997 }
998
999 *length = val;
1000 return true;
1001 }
1002
1003 /* If we were already here, break the infinite cycle. */
1004 if (bitmap_bit_p (visited, SSA_NAME_VERSION (arg)))
1005 return true;
1006 bitmap_set_bit (visited, SSA_NAME_VERSION (arg));
1007
1008 var = arg;
1009 def_stmt = SSA_NAME_DEF_STMT (var);
1010
1011 switch (gimple_code (def_stmt))
1012 {
1013 case GIMPLE_ASSIGN:
1014 /* The RHS of the statement defining VAR must either have a
1015 constant length or come from another SSA_NAME with a constant
1016 length. */
1017 if (gimple_assign_single_p (def_stmt)
1018 || gimple_assign_unary_nop_p (def_stmt))
1019 {
1020 tree rhs = gimple_assign_rhs1 (def_stmt);
1021 return get_maxval_strlen (rhs, length, visited, type);
1022 }
1023 return false;
1024
1025 case GIMPLE_PHI:
1026 {
1027 /* All the arguments of the PHI node must have the same constant
1028 length. */
1029 unsigned i;
1030
1031 for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
1032 {
1033 tree arg = gimple_phi_arg (def_stmt, i)->def;
1034
1035 /* If this PHI has itself as an argument, we cannot
1036 determine the string length of this argument. However,
1037 if we can find a constant string length for the other
1038 PHI args then we can still be sure that this is a
1039 constant string length. So be optimistic and just
1040 continue with the next argument. */
1041 if (arg == gimple_phi_result (def_stmt))
1042 continue;
1043
1044 if (!get_maxval_strlen (arg, length, visited, type))
1045 return false;
1046 }
1047 }
1048 return true;
1049
1050 default:
1051 return false;
1052 }
1053}
1054
1055
1056/* Fold builtin call in statement STMT. Returns a simplified tree.
1057 We may return a non-constant expression, including another call
1058 to a different function and with different arguments, e.g.,
1059 substituting memcpy for strcpy when the string length is known.
1060 Note that some builtins expand into inline code that may not
1061 be valid in GIMPLE. Callers must take care. */
1062
1063tree
1064gimple_fold_builtin (gimple stmt)
1065{
1066 tree result, val[3];
1067 tree callee, a;
1068 int arg_idx, type;
1069 bitmap visited;
1070 bool ignore;
1071 int nargs;
1072 location_t loc = gimple_location (stmt);
1073
1074 gcc_assert (is_gimple_call (stmt));
1075
1076 ignore = (gimple_call_lhs (stmt) == NULL);
1077
1078 /* First try the generic builtin folder. If that succeeds, return the
1079 result directly. */
1080 result = fold_call_stmt (stmt, ignore);
1081 if (result)
1082 {
1083 if (ignore)
1084 STRIP_NOPS (result);
1085 return result;
1086 }
1087
1088 /* Ignore MD builtins. */
1089 callee = gimple_call_fndecl (stmt);
1090 if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
1091 return NULL_TREE;
1092
1093 /* If the builtin could not be folded, and it has no argument list,
1094 we're done. */
1095 nargs = gimple_call_num_args (stmt);
1096 if (nargs == 0)
1097 return NULL_TREE;
1098
1099 /* Limit the work only for builtins we know how to simplify. */
1100 switch (DECL_FUNCTION_CODE (callee))
1101 {
1102 case BUILT_IN_STRLEN:
1103 case BUILT_IN_FPUTS:
1104 case BUILT_IN_FPUTS_UNLOCKED:
1105 arg_idx = 0;
1106 type = 0;
1107 break;
1108 case BUILT_IN_STRCPY:
1109 case BUILT_IN_STRNCPY:
1110 arg_idx = 1;
1111 type = 0;
1112 break;
1113 case BUILT_IN_MEMCPY_CHK:
1114 case BUILT_IN_MEMPCPY_CHK:
1115 case BUILT_IN_MEMMOVE_CHK:
1116 case BUILT_IN_MEMSET_CHK:
1117 case BUILT_IN_STRNCPY_CHK:
1118 arg_idx = 2;
1119 type = 2;
1120 break;
1121 case BUILT_IN_STRCPY_CHK:
1122 case BUILT_IN_STPCPY_CHK:
1123 arg_idx = 1;
1124 type = 1;
1125 break;
1126 case BUILT_IN_SNPRINTF_CHK:
1127 case BUILT_IN_VSNPRINTF_CHK:
1128 arg_idx = 1;
1129 type = 2;
1130 break;
1131 default:
1132 return NULL_TREE;
1133 }
1134
1135 if (arg_idx >= nargs)
1136 return NULL_TREE;
1137
1138 /* Try to use the dataflow information gathered by the CCP process. */
1139 visited = BITMAP_ALLOC (NULL);
1140 bitmap_clear (visited);
1141
1142 memset (val, 0, sizeof (val));
1143 a = gimple_call_arg (stmt, arg_idx);
1144 if (!get_maxval_strlen (a, &val[arg_idx], visited, type))
1145 val[arg_idx] = NULL_TREE;
1146
1147 BITMAP_FREE (visited);
1148
1149 result = NULL_TREE;
1150 switch (DECL_FUNCTION_CODE (callee))
1151 {
1152 case BUILT_IN_STRLEN:
1153 if (val[0] && nargs == 1)
1154 {
1155 tree new_val =
1156 fold_convert (TREE_TYPE (gimple_call_lhs (stmt)), val[0]);
1157
1158 /* If the result is not a valid gimple value, or not a cast
1159 of a valid gimple value, then we can not use the result. */
1160 if (is_gimple_val (new_val)
1161 || (is_gimple_cast (new_val)
1162 && is_gimple_val (TREE_OPERAND (new_val, 0))))
1163 return new_val;
1164 }
1165 break;
1166
1167 case BUILT_IN_STRCPY:
1168 if (val[1] && is_gimple_val (val[1]) && nargs == 2)
1169 result = fold_builtin_strcpy (loc, callee,
1170 gimple_call_arg (stmt, 0),
1171 gimple_call_arg (stmt, 1),
1172 val[1]);
1173 break;
1174
1175 case BUILT_IN_STRNCPY:
1176 if (val[1] && is_gimple_val (val[1]) && nargs == 3)
1177 result = fold_builtin_strncpy (loc, callee,
1178 gimple_call_arg (stmt, 0),
1179 gimple_call_arg (stmt, 1),
1180 gimple_call_arg (stmt, 2),
1181 val[1]);
1182 break;
1183
1184 case BUILT_IN_FPUTS:
1185 if (nargs == 2)
1186 result = fold_builtin_fputs (loc, gimple_call_arg (stmt, 0),
1187 gimple_call_arg (stmt, 1),
1188 ignore, false, val[0]);
1189 break;
1190
1191 case BUILT_IN_FPUTS_UNLOCKED:
1192 if (nargs == 2)
1193 result = fold_builtin_fputs (loc, gimple_call_arg (stmt, 0),
1194 gimple_call_arg (stmt, 1),
1195 ignore, true, val[0]);
1196 break;
1197
1198 case BUILT_IN_MEMCPY_CHK:
1199 case BUILT_IN_MEMPCPY_CHK:
1200 case BUILT_IN_MEMMOVE_CHK:
1201 case BUILT_IN_MEMSET_CHK:
1202 if (val[2] && is_gimple_val (val[2]) && nargs == 4)
1203 result = fold_builtin_memory_chk (loc, callee,
1204 gimple_call_arg (stmt, 0),
1205 gimple_call_arg (stmt, 1),
1206 gimple_call_arg (stmt, 2),
1207 gimple_call_arg (stmt, 3),
1208 val[2], ignore,
1209 DECL_FUNCTION_CODE (callee));
1210 break;
1211
1212 case BUILT_IN_STRCPY_CHK:
1213 case BUILT_IN_STPCPY_CHK:
1214 if (val[1] && is_gimple_val (val[1]) && nargs == 3)
1215 result = fold_builtin_stxcpy_chk (loc, callee,
1216 gimple_call_arg (stmt, 0),
1217 gimple_call_arg (stmt, 1),
1218 gimple_call_arg (stmt, 2),
1219 val[1], ignore,
1220 DECL_FUNCTION_CODE (callee));
1221 break;
1222
1223 case BUILT_IN_STRNCPY_CHK:
1224 if (val[2] && is_gimple_val (val[2]) && nargs == 4)
1225 result = fold_builtin_strncpy_chk (loc, gimple_call_arg (stmt, 0),
1226 gimple_call_arg (stmt, 1),
1227 gimple_call_arg (stmt, 2),
1228 gimple_call_arg (stmt, 3),
1229 val[2]);
1230 break;
1231
1232 case BUILT_IN_SNPRINTF_CHK:
1233 case BUILT_IN_VSNPRINTF_CHK:
1234 if (val[1] && is_gimple_val (val[1]))
1235 result = gimple_fold_builtin_snprintf_chk (stmt, val[1],
1236 DECL_FUNCTION_CODE (callee));
1237 break;
1238
1239 default:
1240 gcc_unreachable ();
1241 }
1242
1243 if (result && ignore)
1244 result = fold_ignored_result (result);
1245 return result;
1246}
1247
621f4189
MJ
1248/* Return the first of the base binfos of BINFO that has virtual functions. */
1249
1250static tree
1251get_first_base_binfo_with_virtuals (tree binfo)
1252{
1253 int i;
1254 tree base_binfo;
1255
1256 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
1257 if (BINFO_VIRTUALS (base_binfo))
1258 return base_binfo;
1259
1260 return NULL_TREE;
1261}
1262
1263
1ae6fe9b
MJ
1264/* Search for a base binfo of BINFO that corresponds to TYPE and return it if
1265 it is found or NULL_TREE if it is not. */
1266
1267static tree
1268get_base_binfo_for_type (tree binfo, tree type)
1269{
1270 int i;
1271 tree base_binfo;
1272 tree res = NULL_TREE;
1273
1274 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
1275 if (TREE_TYPE (base_binfo) == type)
1276 {
1277 gcc_assert (!res);
1278 res = base_binfo;
1279 }
1280
1281 return res;
1282}
1283
1284/* Return a binfo describing the part of object referenced by expression REF.
1285 Return NULL_TREE if it cannot be determined. REF can consist of a series of
1286 COMPONENT_REFs of a declaration or of an INDIRECT_REF or it can also be just
1287 a simple declaration, indirect reference or an SSA_NAME. If the function
1288 discovers an INDIRECT_REF or an SSA_NAME, it will assume that the
1289 encapsulating type is described by KNOWN_BINFO, if it is not NULL_TREE.
1290 Otherwise the first non-artificial field declaration or the base declaration
1291 will be examined to get the encapsulating type. */
1292
1293tree
1294gimple_get_relevant_ref_binfo (tree ref, tree known_binfo)
1295{
1296 while (true)
1297 {
1298 if (TREE_CODE (ref) == COMPONENT_REF)
1299 {
1300 tree par_type;
1301 tree binfo, base_binfo;
1302 tree field = TREE_OPERAND (ref, 1);
1303
1304 if (!DECL_ARTIFICIAL (field))
1305 {
1306 tree type = TREE_TYPE (field);
1307 if (TREE_CODE (type) == RECORD_TYPE)
1308 return TYPE_BINFO (type);
1309 else
1310 return NULL_TREE;
1311 }
1312
1313 par_type = TREE_TYPE (TREE_OPERAND (ref, 0));
1314 binfo = TYPE_BINFO (par_type);
1315 if (!binfo
1316 || BINFO_N_BASE_BINFOS (binfo) == 0)
1317 return NULL_TREE;
1318
621f4189
MJ
1319 base_binfo = get_first_base_binfo_with_virtuals (binfo);
1320 if (base_binfo && BINFO_TYPE (base_binfo) != TREE_TYPE (field))
1ae6fe9b
MJ
1321 {
1322 tree d_binfo;
1323
1324 d_binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (ref, 0),
1325 known_binfo);
1326 /* Get descendant binfo. */
1327 if (!d_binfo)
1328 return NULL_TREE;
1329 return get_base_binfo_for_type (d_binfo, TREE_TYPE (field));
1330 }
1331
1332 ref = TREE_OPERAND (ref, 0);
1333 }
1334 else if (DECL_P (ref) && TREE_CODE (TREE_TYPE (ref)) == RECORD_TYPE)
1335 return TYPE_BINFO (TREE_TYPE (ref));
1336 else if (known_binfo
1337 && (TREE_CODE (ref) == SSA_NAME
70f34814 1338 || TREE_CODE (ref) == MEM_REF))
1ae6fe9b
MJ
1339 return known_binfo;
1340 else
1341 return NULL_TREE;
1342 }
1343}
1344
1345/* Fold a OBJ_TYPE_REF expression to the address of a function. TOKEN is
1346 integer form of OBJ_TYPE_REF_TOKEN of the reference expression. KNOWN_BINFO
1347 carries the binfo describing the true type of OBJ_TYPE_REF_OBJECT(REF). */
1348
1349tree
1350gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
1351{
1352 HOST_WIDE_INT i;
1353 tree v, fndecl;
1354
1355 v = BINFO_VIRTUALS (known_binfo);
1356 i = 0;
1357 while (i != token)
1358 {
1359 i += (TARGET_VTABLE_USES_DESCRIPTORS
1360 ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
1361 v = TREE_CHAIN (v);
1362 }
1363
1364 fndecl = TREE_VALUE (v);
1365 return build_fold_addr_expr (fndecl);
1366}
1367
1368
1369/* Fold a OBJ_TYPE_REF expression to the address of a function. If KNOWN_TYPE
1370 is not NULL_TREE, it is the true type of the outmost encapsulating object if
1371 that comes from a pointer SSA_NAME. If the true outmost encapsulating type
1372 can be determined from a declaration OBJ_TYPE_REF_OBJECT(REF), it is used
1373 regardless of KNOWN_TYPE (which thus can be NULL_TREE). */
1374
1375tree
1376gimple_fold_obj_type_ref (tree ref, tree known_type)
1377{
1378 tree obj = OBJ_TYPE_REF_OBJECT (ref);
1379 tree known_binfo = known_type ? TYPE_BINFO (known_type) : NULL_TREE;
1380 tree binfo;
1381
1382 if (TREE_CODE (obj) == ADDR_EXPR)
1383 obj = TREE_OPERAND (obj, 0);
1384
1385 binfo = gimple_get_relevant_ref_binfo (obj, known_binfo);
1386 if (binfo)
1387 {
1388 HOST_WIDE_INT token = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
1389 return gimple_fold_obj_type_ref_known_binfo (token, binfo);
1390 }
1391 else
1392 return NULL_TREE;
1393}
1394
cbdd87d4
RG
1395/* Attempt to fold a call statement referenced by the statement iterator GSI.
1396 The statement may be replaced by another statement, e.g., if the call
1397 simplifies to a constant value. Return true if any changes were made.
1398 It is assumed that the operands have been previously folded. */
1399
1400static bool
1401fold_gimple_call (gimple_stmt_iterator *gsi)
1402{
1403 gimple stmt = gsi_stmt (*gsi);
1404
1405 tree callee = gimple_call_fndecl (stmt);
1406
1407 /* Check for builtins that CCP can handle using information not
1408 available in the generic fold routines. */
1409 if (callee && DECL_BUILT_IN (callee))
1410 {
1411 tree result = gimple_fold_builtin (stmt);
1412
1413 if (result)
1414 {
1415 if (!update_call_from_tree (gsi, result))
1416 gimplify_and_update_call_from_tree (gsi, result);
1417 return true;
1418 }
1419 }
1420 else
1421 {
cbdd87d4
RG
1422 /* ??? Should perhaps do this in fold proper. However, doing it
1423 there requires that we create a new CALL_EXPR, and that requires
1424 copying EH region info to the new node. Easier to just do it
1425 here where we can just smash the call operand. */
1426 /* ??? Is there a good reason not to do this in fold_stmt_inplace? */
1427 callee = gimple_call_fn (stmt);
1428 if (TREE_CODE (callee) == OBJ_TYPE_REF
1ae6fe9b 1429 && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR)
cbdd87d4
RG
1430 {
1431 tree t;
1432
1ae6fe9b 1433 t = gimple_fold_obj_type_ref (callee, NULL_TREE);
cbdd87d4
RG
1434 if (t)
1435 {
1436 gimple_call_set_fn (stmt, t);
1437 return true;
1438 }
1439 }
1440 }
1441
1442 return false;
1443}
1444
1445/* Worker for both fold_stmt and fold_stmt_inplace. The INPLACE argument
1446 distinguishes both cases. */
1447
1448static bool
1449fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
1450{
1451 bool changed = false;
1452 gimple stmt = gsi_stmt (*gsi);
1453 unsigned i;
1454
1455 /* Fold the main computation performed by the statement. */
1456 switch (gimple_code (stmt))
1457 {
1458 case GIMPLE_ASSIGN:
1459 {
1460 unsigned old_num_ops = gimple_num_ops (stmt);
1461 tree new_rhs = fold_gimple_assign (gsi);
1462 tree lhs = gimple_assign_lhs (stmt);
1463 if (new_rhs
1464 && !useless_type_conversion_p (TREE_TYPE (lhs),
1465 TREE_TYPE (new_rhs)))
1466 new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
1467 if (new_rhs
1468 && (!inplace
1469 || get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
1470 {
1471 gimple_assign_set_rhs_from_tree (gsi, new_rhs);
1472 changed = true;
1473 }
1474 break;
1475 }
1476
1477 case GIMPLE_COND:
1478 changed |= fold_gimple_cond (stmt);
1479 break;
1480
1481 case GIMPLE_CALL:
1482 /* Fold *& in call arguments. */
1483 for (i = 0; i < gimple_call_num_args (stmt); ++i)
1484 if (REFERENCE_CLASS_P (gimple_call_arg (stmt, i)))
1485 {
1486 tree tmp = maybe_fold_reference (gimple_call_arg (stmt, i), false);
1487 if (tmp)
1488 {
1489 gimple_call_set_arg (stmt, i, tmp);
1490 changed = true;
1491 }
1492 }
1493 /* The entire statement may be replaced in this case. */
1494 if (!inplace)
1495 changed |= fold_gimple_call (gsi);
1496 break;
1497
1498 case GIMPLE_ASM:
1499 /* Fold *& in asm operands. */
1500 for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
1501 {
1502 tree link = gimple_asm_output_op (stmt, i);
1503 tree op = TREE_VALUE (link);
1504 if (REFERENCE_CLASS_P (op)
1505 && (op = maybe_fold_reference (op, true)) != NULL_TREE)
1506 {
1507 TREE_VALUE (link) = op;
1508 changed = true;
1509 }
1510 }
1511 for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
1512 {
1513 tree link = gimple_asm_input_op (stmt, i);
1514 tree op = TREE_VALUE (link);
1515 if (REFERENCE_CLASS_P (op)
1516 && (op = maybe_fold_reference (op, false)) != NULL_TREE)
1517 {
1518 TREE_VALUE (link) = op;
1519 changed = true;
1520 }
1521 }
1522 break;
1523
1524 default:;
1525 }
1526
1527 stmt = gsi_stmt (*gsi);
1528
1529 /* Fold *& on the lhs. */
1530 if (gimple_has_lhs (stmt))
1531 {
1532 tree lhs = gimple_get_lhs (stmt);
1533 if (lhs && REFERENCE_CLASS_P (lhs))
1534 {
1535 tree new_lhs = maybe_fold_reference (lhs, true);
1536 if (new_lhs)
1537 {
1538 gimple_set_lhs (stmt, new_lhs);
1539 changed = true;
1540 }
1541 }
1542 }
1543
1544 return changed;
1545}
1546
1547/* Fold the statement pointed to by GSI. In some cases, this function may
1548 replace the whole statement with a new one. Returns true iff folding
1549 makes any changes.
1550 The statement pointed to by GSI should be in valid gimple form but may
1551 be in unfolded state as resulting from for example constant propagation
1552 which can produce *&x = 0. */
1553
1554bool
1555fold_stmt (gimple_stmt_iterator *gsi)
1556{
1557 return fold_stmt_1 (gsi, false);
1558}
1559
1560/* Perform the minimal folding on statement STMT. Only operations like
1561 *&x created by constant propagation are handled. The statement cannot
1562 be replaced with a new one. Return true if the statement was
1563 changed, false otherwise.
1564 The statement STMT should be in valid gimple form but may
1565 be in unfolded state as resulting from for example constant propagation
1566 which can produce *&x = 0. */
1567
1568bool
1569fold_stmt_inplace (gimple stmt)
1570{
1571 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1572 bool changed = fold_stmt_1 (&gsi, true);
1573 gcc_assert (gsi_stmt (gsi) == stmt);
1574 return changed;
1575}
1576
e89065a1
SL
1577/* Canonicalize and possibly invert the boolean EXPR; return NULL_TREE
1578 if EXPR is null or we don't know how.
1579 If non-null, the result always has boolean type. */
1580
1581static tree
1582canonicalize_bool (tree expr, bool invert)
1583{
1584 if (!expr)
1585 return NULL_TREE;
1586 else if (invert)
1587 {
1588 if (integer_nonzerop (expr))
1589 return boolean_false_node;
1590 else if (integer_zerop (expr))
1591 return boolean_true_node;
1592 else if (TREE_CODE (expr) == SSA_NAME)
1593 return fold_build2 (EQ_EXPR, boolean_type_node, expr,
1594 build_int_cst (TREE_TYPE (expr), 0));
1595 else if (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_comparison)
1596 return fold_build2 (invert_tree_comparison (TREE_CODE (expr), false),
1597 boolean_type_node,
1598 TREE_OPERAND (expr, 0),
1599 TREE_OPERAND (expr, 1));
1600 else
1601 return NULL_TREE;
1602 }
1603 else
1604 {
1605 if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
1606 return expr;
1607 if (integer_nonzerop (expr))
1608 return boolean_true_node;
1609 else if (integer_zerop (expr))
1610 return boolean_false_node;
1611 else if (TREE_CODE (expr) == SSA_NAME)
1612 return fold_build2 (NE_EXPR, boolean_type_node, expr,
1613 build_int_cst (TREE_TYPE (expr), 0));
1614 else if (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_comparison)
1615 return fold_build2 (TREE_CODE (expr),
1616 boolean_type_node,
1617 TREE_OPERAND (expr, 0),
1618 TREE_OPERAND (expr, 1));
1619 else
1620 return NULL_TREE;
1621 }
1622}
1623
1624/* Check to see if a boolean expression EXPR is logically equivalent to the
1625 comparison (OP1 CODE OP2). Check for various identities involving
1626 SSA_NAMEs. */
1627
1628static bool
1629same_bool_comparison_p (const_tree expr, enum tree_code code,
1630 const_tree op1, const_tree op2)
1631{
1632 gimple s;
1633
1634 /* The obvious case. */
1635 if (TREE_CODE (expr) == code
1636 && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
1637 && operand_equal_p (TREE_OPERAND (expr, 1), op2, 0))
1638 return true;
1639
1640 /* Check for comparing (name, name != 0) and the case where expr
1641 is an SSA_NAME with a definition matching the comparison. */
1642 if (TREE_CODE (expr) == SSA_NAME
1643 && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
1644 {
1645 if (operand_equal_p (expr, op1, 0))
1646 return ((code == NE_EXPR && integer_zerop (op2))
1647 || (code == EQ_EXPR && integer_nonzerop (op2)));
1648 s = SSA_NAME_DEF_STMT (expr);
1649 if (is_gimple_assign (s)
1650 && gimple_assign_rhs_code (s) == code
1651 && operand_equal_p (gimple_assign_rhs1 (s), op1, 0)
1652 && operand_equal_p (gimple_assign_rhs2 (s), op2, 0))
1653 return true;
1654 }
1655
1656 /* If op1 is of the form (name != 0) or (name == 0), and the definition
1657 of name is a comparison, recurse. */
1658 if (TREE_CODE (op1) == SSA_NAME
1659 && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
1660 {
1661 s = SSA_NAME_DEF_STMT (op1);
1662 if (is_gimple_assign (s)
1663 && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
1664 {
1665 enum tree_code c = gimple_assign_rhs_code (s);
1666 if ((c == NE_EXPR && integer_zerop (op2))
1667 || (c == EQ_EXPR && integer_nonzerop (op2)))
1668 return same_bool_comparison_p (expr, c,
1669 gimple_assign_rhs1 (s),
1670 gimple_assign_rhs2 (s));
1671 if ((c == EQ_EXPR && integer_zerop (op2))
1672 || (c == NE_EXPR && integer_nonzerop (op2)))
1673 return same_bool_comparison_p (expr,
1674 invert_tree_comparison (c, false),
1675 gimple_assign_rhs1 (s),
1676 gimple_assign_rhs2 (s));
1677 }
1678 }
1679 return false;
1680}
1681
1682/* Check to see if two boolean expressions OP1 and OP2 are logically
1683 equivalent. */
1684
1685static bool
1686same_bool_result_p (const_tree op1, const_tree op2)
1687{
1688 /* Simple cases first. */
1689 if (operand_equal_p (op1, op2, 0))
1690 return true;
1691
1692 /* Check the cases where at least one of the operands is a comparison.
1693 These are a bit smarter than operand_equal_p in that they apply some
1694 identifies on SSA_NAMEs. */
1695 if (TREE_CODE_CLASS (TREE_CODE (op2)) == tcc_comparison
1696 && same_bool_comparison_p (op1, TREE_CODE (op2),
1697 TREE_OPERAND (op2, 0),
1698 TREE_OPERAND (op2, 1)))
1699 return true;
1700 if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_comparison
1701 && same_bool_comparison_p (op2, TREE_CODE (op1),
1702 TREE_OPERAND (op1, 0),
1703 TREE_OPERAND (op1, 1)))
1704 return true;
1705
1706 /* Default case. */
1707 return false;
1708}
1709
1710/* Forward declarations for some mutually recursive functions. */
1711
1712static tree
1713and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
1714 enum tree_code code2, tree op2a, tree op2b);
1715static tree
1716and_var_with_comparison (tree var, bool invert,
1717 enum tree_code code2, tree op2a, tree op2b);
1718static tree
1719and_var_with_comparison_1 (gimple stmt,
1720 enum tree_code code2, tree op2a, tree op2b);
1721static tree
1722or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
1723 enum tree_code code2, tree op2a, tree op2b);
1724static tree
1725or_var_with_comparison (tree var, bool invert,
1726 enum tree_code code2, tree op2a, tree op2b);
1727static tree
1728or_var_with_comparison_1 (gimple stmt,
1729 enum tree_code code2, tree op2a, tree op2b);
1730
1731/* Helper function for and_comparisons_1: try to simplify the AND of the
1732 ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
1733 If INVERT is true, invert the value of the VAR before doing the AND.
1734 Return NULL_EXPR if we can't simplify this to a single expression. */
1735
1736static tree
1737and_var_with_comparison (tree var, bool invert,
1738 enum tree_code code2, tree op2a, tree op2b)
1739{
1740 tree t;
1741 gimple stmt = SSA_NAME_DEF_STMT (var);
1742
1743 /* We can only deal with variables whose definitions are assignments. */
1744 if (!is_gimple_assign (stmt))
1745 return NULL_TREE;
1746
1747 /* If we have an inverted comparison, apply DeMorgan's law and rewrite
1748 !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
1749 Then we only have to consider the simpler non-inverted cases. */
1750 if (invert)
1751 t = or_var_with_comparison_1 (stmt,
1752 invert_tree_comparison (code2, false),
1753 op2a, op2b);
1754 else
1755 t = and_var_with_comparison_1 (stmt, code2, op2a, op2b);
1756 return canonicalize_bool (t, invert);
1757}
1758
1759/* Try to simplify the AND of the ssa variable defined by the assignment
1760 STMT with the comparison specified by (OP2A CODE2 OP2B).
1761 Return NULL_EXPR if we can't simplify this to a single expression. */
1762
1763static tree
1764and_var_with_comparison_1 (gimple stmt,
1765 enum tree_code code2, tree op2a, tree op2b)
1766{
1767 tree var = gimple_assign_lhs (stmt);
1768 tree true_test_var = NULL_TREE;
1769 tree false_test_var = NULL_TREE;
1770 enum tree_code innercode = gimple_assign_rhs_code (stmt);
1771
1772 /* Check for identities like (var AND (var == 0)) => false. */
1773 if (TREE_CODE (op2a) == SSA_NAME
1774 && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
1775 {
1776 if ((code2 == NE_EXPR && integer_zerop (op2b))
1777 || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
1778 {
1779 true_test_var = op2a;
1780 if (var == true_test_var)
1781 return var;
1782 }
1783 else if ((code2 == EQ_EXPR && integer_zerop (op2b))
1784 || (code2 == NE_EXPR && integer_nonzerop (op2b)))
1785 {
1786 false_test_var = op2a;
1787 if (var == false_test_var)
1788 return boolean_false_node;
1789 }
1790 }
1791
1792 /* If the definition is a comparison, recurse on it. */
1793 if (TREE_CODE_CLASS (innercode) == tcc_comparison)
1794 {
1795 tree t = and_comparisons_1 (innercode,
1796 gimple_assign_rhs1 (stmt),
1797 gimple_assign_rhs2 (stmt),
1798 code2,
1799 op2a,
1800 op2b);
1801 if (t)
1802 return t;
1803 }
1804
1805 /* If the definition is an AND or OR expression, we may be able to
1806 simplify by reassociating. */
1807 if (innercode == TRUTH_AND_EXPR
1808 || innercode == TRUTH_OR_EXPR
1809 || (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
1810 && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR)))
1811 {
1812 tree inner1 = gimple_assign_rhs1 (stmt);
1813 tree inner2 = gimple_assign_rhs2 (stmt);
1814 gimple s;
1815 tree t;
1816 tree partial = NULL_TREE;
1817 bool is_and = (innercode == TRUTH_AND_EXPR || innercode == BIT_AND_EXPR);
1818
1819 /* Check for boolean identities that don't require recursive examination
1820 of inner1/inner2:
1821 inner1 AND (inner1 AND inner2) => inner1 AND inner2 => var
1822 inner1 AND (inner1 OR inner2) => inner1
1823 !inner1 AND (inner1 AND inner2) => false
1824 !inner1 AND (inner1 OR inner2) => !inner1 AND inner2
1825 Likewise for similar cases involving inner2. */
1826 if (inner1 == true_test_var)
1827 return (is_and ? var : inner1);
1828 else if (inner2 == true_test_var)
1829 return (is_and ? var : inner2);
1830 else if (inner1 == false_test_var)
1831 return (is_and
1832 ? boolean_false_node
1833 : and_var_with_comparison (inner2, false, code2, op2a, op2b));
1834 else if (inner2 == false_test_var)
1835 return (is_and
1836 ? boolean_false_node
1837 : and_var_with_comparison (inner1, false, code2, op2a, op2b));
1838
1839 /* Next, redistribute/reassociate the AND across the inner tests.
1840 Compute the first partial result, (inner1 AND (op2a code op2b)) */
1841 if (TREE_CODE (inner1) == SSA_NAME
1842 && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
1843 && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
1844 && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s),
1845 gimple_assign_rhs1 (s),
1846 gimple_assign_rhs2 (s),
1847 code2, op2a, op2b)))
1848 {
1849 /* Handle the AND case, where we are reassociating:
1850 (inner1 AND inner2) AND (op2a code2 op2b)
1851 => (t AND inner2)
1852 If the partial result t is a constant, we win. Otherwise
1853 continue on to try reassociating with the other inner test. */
1854 if (is_and)
1855 {
1856 if (integer_onep (t))
1857 return inner2;
1858 else if (integer_zerop (t))
1859 return boolean_false_node;
1860 }
1861
1862 /* Handle the OR case, where we are redistributing:
1863 (inner1 OR inner2) AND (op2a code2 op2b)
1864 => (t OR (inner2 AND (op2a code2 op2b))) */
1865 else
1866 {
1867 if (integer_onep (t))
1868 return boolean_true_node;
1869 else
1870 /* Save partial result for later. */
1871 partial = t;
1872 }
1873 }
1874
1875 /* Compute the second partial result, (inner2 AND (op2a code op2b)) */
1876 if (TREE_CODE (inner2) == SSA_NAME
1877 && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
1878 && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
1879 && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s),
1880 gimple_assign_rhs1 (s),
1881 gimple_assign_rhs2 (s),
1882 code2, op2a, op2b)))
1883 {
1884 /* Handle the AND case, where we are reassociating:
1885 (inner1 AND inner2) AND (op2a code2 op2b)
1886 => (inner1 AND t) */
1887 if (is_and)
1888 {
1889 if (integer_onep (t))
1890 return inner1;
1891 else if (integer_zerop (t))
1892 return boolean_false_node;
1893 }
1894
1895 /* Handle the OR case. where we are redistributing:
1896 (inner1 OR inner2) AND (op2a code2 op2b)
1897 => (t OR (inner1 AND (op2a code2 op2b)))
1898 => (t OR partial) */
1899 else
1900 {
1901 if (integer_onep (t))
1902 return boolean_true_node;
1903 else if (partial)
1904 {
1905 /* We already got a simplification for the other
1906 operand to the redistributed OR expression. The
1907 interesting case is when at least one is false.
1908 Or, if both are the same, we can apply the identity
1909 (x OR x) == x. */
1910 if (integer_zerop (partial))
1911 return t;
1912 else if (integer_zerop (t))
1913 return partial;
1914 else if (same_bool_result_p (t, partial))
1915 return t;
1916 }
1917 }
1918 }
1919 }
1920 return NULL_TREE;
1921}
1922
1923/* Try to simplify the AND of two comparisons defined by
1924 (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
1925 If this can be done without constructing an intermediate value,
1926 return the resulting tree; otherwise NULL_TREE is returned.
1927 This function is deliberately asymmetric as it recurses on SSA_DEFs
1928 in the first comparison but not the second. */
1929
1930static tree
1931and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
1932 enum tree_code code2, tree op2a, tree op2b)
1933{
1934 /* First check for ((x CODE1 y) AND (x CODE2 y)). */
1935 if (operand_equal_p (op1a, op2a, 0)
1936 && operand_equal_p (op1b, op2b, 0))
1937 {
1938 tree t = combine_comparisons (UNKNOWN_LOCATION,
1939 TRUTH_ANDIF_EXPR, code1, code2,
1940 boolean_type_node, op1a, op1b);
1941 if (t)
1942 return t;
1943 }
1944
1945 /* Likewise the swapped case of the above. */
1946 if (operand_equal_p (op1a, op2b, 0)
1947 && operand_equal_p (op1b, op2a, 0))
1948 {
1949 tree t = combine_comparisons (UNKNOWN_LOCATION,
1950 TRUTH_ANDIF_EXPR, code1,
1951 swap_tree_comparison (code2),
1952 boolean_type_node, op1a, op1b);
1953 if (t)
1954 return t;
1955 }
1956
1957 /* If both comparisons are of the same value against constants, we might
1958 be able to merge them. */
1959 if (operand_equal_p (op1a, op2a, 0)
1960 && TREE_CODE (op1b) == INTEGER_CST
1961 && TREE_CODE (op2b) == INTEGER_CST)
1962 {
1963 int cmp = tree_int_cst_compare (op1b, op2b);
1964
1965 /* If we have (op1a == op1b), we should either be able to
1966 return that or FALSE, depending on whether the constant op1b
1967 also satisfies the other comparison against op2b. */
1968 if (code1 == EQ_EXPR)
1969 {
1970 bool done = true;
1971 bool val;
1972 switch (code2)
1973 {
1974 case EQ_EXPR: val = (cmp == 0); break;
1975 case NE_EXPR: val = (cmp != 0); break;
1976 case LT_EXPR: val = (cmp < 0); break;
1977 case GT_EXPR: val = (cmp > 0); break;
1978 case LE_EXPR: val = (cmp <= 0); break;
1979 case GE_EXPR: val = (cmp >= 0); break;
1980 default: done = false;
1981 }
1982 if (done)
1983 {
1984 if (val)
1985 return fold_build2 (code1, boolean_type_node, op1a, op1b);
1986 else
1987 return boolean_false_node;
1988 }
1989 }
1990 /* Likewise if the second comparison is an == comparison. */
1991 else if (code2 == EQ_EXPR)
1992 {
1993 bool done = true;
1994 bool val;
1995 switch (code1)
1996 {
1997 case EQ_EXPR: val = (cmp == 0); break;
1998 case NE_EXPR: val = (cmp != 0); break;
1999 case LT_EXPR: val = (cmp > 0); break;
2000 case GT_EXPR: val = (cmp < 0); break;
2001 case LE_EXPR: val = (cmp >= 0); break;
2002 case GE_EXPR: val = (cmp <= 0); break;
2003 default: done = false;
2004 }
2005 if (done)
2006 {
2007 if (val)
2008 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2009 else
2010 return boolean_false_node;
2011 }
2012 }
2013
2014 /* Same business with inequality tests. */
2015 else if (code1 == NE_EXPR)
2016 {
2017 bool val;
2018 switch (code2)
2019 {
2020 case EQ_EXPR: val = (cmp != 0); break;
2021 case NE_EXPR: val = (cmp == 0); break;
2022 case LT_EXPR: val = (cmp >= 0); break;
2023 case GT_EXPR: val = (cmp <= 0); break;
2024 case LE_EXPR: val = (cmp > 0); break;
2025 case GE_EXPR: val = (cmp < 0); break;
2026 default:
2027 val = false;
2028 }
2029 if (val)
2030 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2031 }
2032 else if (code2 == NE_EXPR)
2033 {
2034 bool val;
2035 switch (code1)
2036 {
2037 case EQ_EXPR: val = (cmp == 0); break;
2038 case NE_EXPR: val = (cmp != 0); break;
2039 case LT_EXPR: val = (cmp <= 0); break;
2040 case GT_EXPR: val = (cmp >= 0); break;
2041 case LE_EXPR: val = (cmp < 0); break;
2042 case GE_EXPR: val = (cmp > 0); break;
2043 default:
2044 val = false;
2045 }
2046 if (val)
2047 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2048 }
2049
2050 /* Chose the more restrictive of two < or <= comparisons. */
2051 else if ((code1 == LT_EXPR || code1 == LE_EXPR)
2052 && (code2 == LT_EXPR || code2 == LE_EXPR))
2053 {
2054 if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
2055 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2056 else
2057 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2058 }
2059
2060 /* Likewise chose the more restrictive of two > or >= comparisons. */
2061 else if ((code1 == GT_EXPR || code1 == GE_EXPR)
2062 && (code2 == GT_EXPR || code2 == GE_EXPR))
2063 {
2064 if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR))
2065 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2066 else
2067 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2068 }
2069
2070 /* Check for singleton ranges. */
2071 else if (cmp == 0
2072 && ((code1 == LE_EXPR && code2 == GE_EXPR)
2073 || (code1 == GE_EXPR && code2 == LE_EXPR)))
2074 return fold_build2 (EQ_EXPR, boolean_type_node, op1a, op2b);
2075
2076 /* Check for disjoint ranges. */
2077 else if (cmp <= 0
2078 && (code1 == LT_EXPR || code1 == LE_EXPR)
2079 && (code2 == GT_EXPR || code2 == GE_EXPR))
2080 return boolean_false_node;
2081 else if (cmp >= 0
2082 && (code1 == GT_EXPR || code1 == GE_EXPR)
2083 && (code2 == LT_EXPR || code2 == LE_EXPR))
2084 return boolean_false_node;
2085 }
2086
2087 /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
2088 NAME's definition is a truth value. See if there are any simplifications
2089 that can be done against the NAME's definition. */
2090 if (TREE_CODE (op1a) == SSA_NAME
2091 && (code1 == NE_EXPR || code1 == EQ_EXPR)
2092 && (integer_zerop (op1b) || integer_onep (op1b)))
2093 {
2094 bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
2095 || (code1 == NE_EXPR && integer_onep (op1b)));
2096 gimple stmt = SSA_NAME_DEF_STMT (op1a);
2097 switch (gimple_code (stmt))
2098 {
2099 case GIMPLE_ASSIGN:
2100 /* Try to simplify by copy-propagating the definition. */
2101 return and_var_with_comparison (op1a, invert, code2, op2a, op2b);
2102
2103 case GIMPLE_PHI:
2104 /* If every argument to the PHI produces the same result when
2105 ANDed with the second comparison, we win.
2106 Do not do this unless the type is bool since we need a bool
2107 result here anyway. */
2108 if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
2109 {
2110 tree result = NULL_TREE;
2111 unsigned i;
2112 for (i = 0; i < gimple_phi_num_args (stmt); i++)
2113 {
2114 tree arg = gimple_phi_arg_def (stmt, i);
2115
2116 /* If this PHI has itself as an argument, ignore it.
2117 If all the other args produce the same result,
2118 we're still OK. */
2119 if (arg == gimple_phi_result (stmt))
2120 continue;
2121 else if (TREE_CODE (arg) == INTEGER_CST)
2122 {
2123 if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
2124 {
2125 if (!result)
2126 result = boolean_false_node;
2127 else if (!integer_zerop (result))
2128 return NULL_TREE;
2129 }
2130 else if (!result)
2131 result = fold_build2 (code2, boolean_type_node,
2132 op2a, op2b);
2133 else if (!same_bool_comparison_p (result,
2134 code2, op2a, op2b))
2135 return NULL_TREE;
2136 }
2137 else if (TREE_CODE (arg) == SSA_NAME)
2138 {
2139 tree temp = and_var_with_comparison (arg, invert,
2140 code2, op2a, op2b);
2141 if (!temp)
2142 return NULL_TREE;
2143 else if (!result)
2144 result = temp;
2145 else if (!same_bool_result_p (result, temp))
2146 return NULL_TREE;
2147 }
2148 else
2149 return NULL_TREE;
2150 }
2151 return result;
2152 }
2153
2154 default:
2155 break;
2156 }
2157 }
2158 return NULL_TREE;
2159}
2160
2161/* Try to simplify the AND of two comparisons, specified by
2162 (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
2163 If this can be simplified to a single expression (without requiring
2164 introducing more SSA variables to hold intermediate values),
2165 return the resulting tree. Otherwise return NULL_TREE.
2166 If the result expression is non-null, it has boolean type. */
2167
2168tree
2169maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
2170 enum tree_code code2, tree op2a, tree op2b)
2171{
2172 tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b);
2173 if (t)
2174 return t;
2175 else
2176 return and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b);
2177}
2178
2179/* Helper function for or_comparisons_1: try to simplify the OR of the
2180 ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
2181 If INVERT is true, invert the value of VAR before doing the OR.
2182 Return NULL_EXPR if we can't simplify this to a single expression. */
2183
2184static tree
2185or_var_with_comparison (tree var, bool invert,
2186 enum tree_code code2, tree op2a, tree op2b)
2187{
2188 tree t;
2189 gimple stmt = SSA_NAME_DEF_STMT (var);
2190
2191 /* We can only deal with variables whose definitions are assignments. */
2192 if (!is_gimple_assign (stmt))
2193 return NULL_TREE;
2194
2195 /* If we have an inverted comparison, apply DeMorgan's law and rewrite
2196 !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
2197 Then we only have to consider the simpler non-inverted cases. */
2198 if (invert)
2199 t = and_var_with_comparison_1 (stmt,
2200 invert_tree_comparison (code2, false),
2201 op2a, op2b);
2202 else
2203 t = or_var_with_comparison_1 (stmt, code2, op2a, op2b);
2204 return canonicalize_bool (t, invert);
2205}
2206
2207/* Try to simplify the OR of the ssa variable defined by the assignment
2208 STMT with the comparison specified by (OP2A CODE2 OP2B).
2209 Return NULL_EXPR if we can't simplify this to a single expression. */
2210
2211static tree
2212or_var_with_comparison_1 (gimple stmt,
2213 enum tree_code code2, tree op2a, tree op2b)
2214{
2215 tree var = gimple_assign_lhs (stmt);
2216 tree true_test_var = NULL_TREE;
2217 tree false_test_var = NULL_TREE;
2218 enum tree_code innercode = gimple_assign_rhs_code (stmt);
2219
2220 /* Check for identities like (var OR (var != 0)) => true . */
2221 if (TREE_CODE (op2a) == SSA_NAME
2222 && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
2223 {
2224 if ((code2 == NE_EXPR && integer_zerop (op2b))
2225 || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
2226 {
2227 true_test_var = op2a;
2228 if (var == true_test_var)
2229 return var;
2230 }
2231 else if ((code2 == EQ_EXPR && integer_zerop (op2b))
2232 || (code2 == NE_EXPR && integer_nonzerop (op2b)))
2233 {
2234 false_test_var = op2a;
2235 if (var == false_test_var)
2236 return boolean_true_node;
2237 }
2238 }
2239
2240 /* If the definition is a comparison, recurse on it. */
2241 if (TREE_CODE_CLASS (innercode) == tcc_comparison)
2242 {
2243 tree t = or_comparisons_1 (innercode,
2244 gimple_assign_rhs1 (stmt),
2245 gimple_assign_rhs2 (stmt),
2246 code2,
2247 op2a,
2248 op2b);
2249 if (t)
2250 return t;
2251 }
2252
2253 /* If the definition is an AND or OR expression, we may be able to
2254 simplify by reassociating. */
2255 if (innercode == TRUTH_AND_EXPR
2256 || innercode == TRUTH_OR_EXPR
2257 || (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
2258 && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR)))
2259 {
2260 tree inner1 = gimple_assign_rhs1 (stmt);
2261 tree inner2 = gimple_assign_rhs2 (stmt);
2262 gimple s;
2263 tree t;
2264 tree partial = NULL_TREE;
2265 bool is_or = (innercode == TRUTH_OR_EXPR || innercode == BIT_IOR_EXPR);
2266
2267 /* Check for boolean identities that don't require recursive examination
2268 of inner1/inner2:
2269 inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
2270 inner1 OR (inner1 AND inner2) => inner1
2271 !inner1 OR (inner1 OR inner2) => true
2272 !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
2273 */
2274 if (inner1 == true_test_var)
2275 return (is_or ? var : inner1);
2276 else if (inner2 == true_test_var)
2277 return (is_or ? var : inner2);
2278 else if (inner1 == false_test_var)
2279 return (is_or
2280 ? boolean_true_node
2281 : or_var_with_comparison (inner2, false, code2, op2a, op2b));
2282 else if (inner2 == false_test_var)
2283 return (is_or
2284 ? boolean_true_node
2285 : or_var_with_comparison (inner1, false, code2, op2a, op2b));
2286
2287 /* Next, redistribute/reassociate the OR across the inner tests.
2288 Compute the first partial result, (inner1 OR (op2a code op2b)) */
2289 if (TREE_CODE (inner1) == SSA_NAME
2290 && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
2291 && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
2292 && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s),
2293 gimple_assign_rhs1 (s),
2294 gimple_assign_rhs2 (s),
2295 code2, op2a, op2b)))
2296 {
2297 /* Handle the OR case, where we are reassociating:
2298 (inner1 OR inner2) OR (op2a code2 op2b)
2299 => (t OR inner2)
2300 If the partial result t is a constant, we win. Otherwise
2301 continue on to try reassociating with the other inner test. */
2302 if (innercode == TRUTH_OR_EXPR)
2303 {
2304 if (integer_onep (t))
2305 return boolean_true_node;
2306 else if (integer_zerop (t))
2307 return inner2;
2308 }
2309
2310 /* Handle the AND case, where we are redistributing:
2311 (inner1 AND inner2) OR (op2a code2 op2b)
2312 => (t AND (inner2 OR (op2a code op2b))) */
2313 else
2314 {
2315 if (integer_zerop (t))
2316 return boolean_false_node;
2317 else
2318 /* Save partial result for later. */
2319 partial = t;
2320 }
2321 }
2322
2323 /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
2324 if (TREE_CODE (inner2) == SSA_NAME
2325 && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
2326 && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
2327 && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s),
2328 gimple_assign_rhs1 (s),
2329 gimple_assign_rhs2 (s),
2330 code2, op2a, op2b)))
2331 {
2332 /* Handle the OR case, where we are reassociating:
2333 (inner1 OR inner2) OR (op2a code2 op2b)
2334 => (inner1 OR t) */
2335 if (innercode == TRUTH_OR_EXPR)
2336 {
2337 if (integer_zerop (t))
2338 return inner1;
2339 else if (integer_onep (t))
2340 return boolean_true_node;
2341 }
2342
2343 /* Handle the AND case, where we are redistributing:
2344 (inner1 AND inner2) OR (op2a code2 op2b)
2345 => (t AND (inner1 OR (op2a code2 op2b)))
2346 => (t AND partial) */
2347 else
2348 {
2349 if (integer_zerop (t))
2350 return boolean_false_node;
2351 else if (partial)
2352 {
2353 /* We already got a simplification for the other
2354 operand to the redistributed AND expression. The
2355 interesting case is when at least one is true.
2356 Or, if both are the same, we can apply the identity
2357 (x AND x) == true. */
2358 if (integer_onep (partial))
2359 return t;
2360 else if (integer_onep (t))
2361 return partial;
2362 else if (same_bool_result_p (t, partial))
2363 return boolean_true_node;
2364 }
2365 }
2366 }
2367 }
2368 return NULL_TREE;
2369}
2370
2371/* Try to simplify the OR of two comparisons defined by
2372 (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
2373 If this can be done without constructing an intermediate value,
2374 return the resulting tree; otherwise NULL_TREE is returned.
2375 This function is deliberately asymmetric as it recurses on SSA_DEFs
2376 in the first comparison but not the second. */
2377
2378static tree
2379or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
2380 enum tree_code code2, tree op2a, tree op2b)
2381{
2382 /* First check for ((x CODE1 y) OR (x CODE2 y)). */
2383 if (operand_equal_p (op1a, op2a, 0)
2384 && operand_equal_p (op1b, op2b, 0))
2385 {
2386 tree t = combine_comparisons (UNKNOWN_LOCATION,
2387 TRUTH_ORIF_EXPR, code1, code2,
2388 boolean_type_node, op1a, op1b);
2389 if (t)
2390 return t;
2391 }
2392
2393 /* Likewise the swapped case of the above. */
2394 if (operand_equal_p (op1a, op2b, 0)
2395 && operand_equal_p (op1b, op2a, 0))
2396 {
2397 tree t = combine_comparisons (UNKNOWN_LOCATION,
2398 TRUTH_ORIF_EXPR, code1,
2399 swap_tree_comparison (code2),
2400 boolean_type_node, op1a, op1b);
2401 if (t)
2402 return t;
2403 }
2404
2405 /* If both comparisons are of the same value against constants, we might
2406 be able to merge them. */
2407 if (operand_equal_p (op1a, op2a, 0)
2408 && TREE_CODE (op1b) == INTEGER_CST
2409 && TREE_CODE (op2b) == INTEGER_CST)
2410 {
2411 int cmp = tree_int_cst_compare (op1b, op2b);
2412
2413 /* If we have (op1a != op1b), we should either be able to
2414 return that or TRUE, depending on whether the constant op1b
2415 also satisfies the other comparison against op2b. */
2416 if (code1 == NE_EXPR)
2417 {
2418 bool done = true;
2419 bool val;
2420 switch (code2)
2421 {
2422 case EQ_EXPR: val = (cmp == 0); break;
2423 case NE_EXPR: val = (cmp != 0); break;
2424 case LT_EXPR: val = (cmp < 0); break;
2425 case GT_EXPR: val = (cmp > 0); break;
2426 case LE_EXPR: val = (cmp <= 0); break;
2427 case GE_EXPR: val = (cmp >= 0); break;
2428 default: done = false;
2429 }
2430 if (done)
2431 {
2432 if (val)
2433 return boolean_true_node;
2434 else
2435 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2436 }
2437 }
2438 /* Likewise if the second comparison is a != comparison. */
2439 else if (code2 == NE_EXPR)
2440 {
2441 bool done = true;
2442 bool val;
2443 switch (code1)
2444 {
2445 case EQ_EXPR: val = (cmp == 0); break;
2446 case NE_EXPR: val = (cmp != 0); break;
2447 case LT_EXPR: val = (cmp > 0); break;
2448 case GT_EXPR: val = (cmp < 0); break;
2449 case LE_EXPR: val = (cmp >= 0); break;
2450 case GE_EXPR: val = (cmp <= 0); break;
2451 default: done = false;
2452 }
2453 if (done)
2454 {
2455 if (val)
2456 return boolean_true_node;
2457 else
2458 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2459 }
2460 }
2461
2462 /* See if an equality test is redundant with the other comparison. */
2463 else if (code1 == EQ_EXPR)
2464 {
2465 bool val;
2466 switch (code2)
2467 {
2468 case EQ_EXPR: val = (cmp == 0); break;
2469 case NE_EXPR: val = (cmp != 0); break;
2470 case LT_EXPR: val = (cmp < 0); break;
2471 case GT_EXPR: val = (cmp > 0); break;
2472 case LE_EXPR: val = (cmp <= 0); break;
2473 case GE_EXPR: val = (cmp >= 0); break;
2474 default:
2475 val = false;
2476 }
2477 if (val)
2478 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2479 }
2480 else if (code2 == EQ_EXPR)
2481 {
2482 bool val;
2483 switch (code1)
2484 {
2485 case EQ_EXPR: val = (cmp == 0); break;
2486 case NE_EXPR: val = (cmp != 0); break;
2487 case LT_EXPR: val = (cmp > 0); break;
2488 case GT_EXPR: val = (cmp < 0); break;
2489 case LE_EXPR: val = (cmp >= 0); break;
2490 case GE_EXPR: val = (cmp <= 0); break;
2491 default:
2492 val = false;
2493 }
2494 if (val)
2495 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2496 }
2497
2498 /* Chose the less restrictive of two < or <= comparisons. */
2499 else if ((code1 == LT_EXPR || code1 == LE_EXPR)
2500 && (code2 == LT_EXPR || code2 == LE_EXPR))
2501 {
2502 if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
2503 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2504 else
2505 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2506 }
2507
2508 /* Likewise chose the less restrictive of two > or >= comparisons. */
2509 else if ((code1 == GT_EXPR || code1 == GE_EXPR)
2510 && (code2 == GT_EXPR || code2 == GE_EXPR))
2511 {
2512 if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR))
2513 return fold_build2 (code2, boolean_type_node, op2a, op2b);
2514 else
2515 return fold_build2 (code1, boolean_type_node, op1a, op1b);
2516 }
2517
2518 /* Check for singleton ranges. */
2519 else if (cmp == 0
2520 && ((code1 == LT_EXPR && code2 == GT_EXPR)
2521 || (code1 == GT_EXPR && code2 == LT_EXPR)))
2522 return fold_build2 (NE_EXPR, boolean_type_node, op1a, op2b);
2523
2524 /* Check for less/greater pairs that don't restrict the range at all. */
2525 else if (cmp >= 0
2526 && (code1 == LT_EXPR || code1 == LE_EXPR)
2527 && (code2 == GT_EXPR || code2 == GE_EXPR))
2528 return boolean_true_node;
2529 else if (cmp <= 0
2530 && (code1 == GT_EXPR || code1 == GE_EXPR)
2531 && (code2 == LT_EXPR || code2 == LE_EXPR))
2532 return boolean_true_node;
2533 }
2534
2535 /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
2536 NAME's definition is a truth value. See if there are any simplifications
2537 that can be done against the NAME's definition. */
2538 if (TREE_CODE (op1a) == SSA_NAME
2539 && (code1 == NE_EXPR || code1 == EQ_EXPR)
2540 && (integer_zerop (op1b) || integer_onep (op1b)))
2541 {
2542 bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
2543 || (code1 == NE_EXPR && integer_onep (op1b)));
2544 gimple stmt = SSA_NAME_DEF_STMT (op1a);
2545 switch (gimple_code (stmt))
2546 {
2547 case GIMPLE_ASSIGN:
2548 /* Try to simplify by copy-propagating the definition. */
2549 return or_var_with_comparison (op1a, invert, code2, op2a, op2b);
2550
2551 case GIMPLE_PHI:
2552 /* If every argument to the PHI produces the same result when
2553 ORed with the second comparison, we win.
2554 Do not do this unless the type is bool since we need a bool
2555 result here anyway. */
2556 if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
2557 {
2558 tree result = NULL_TREE;
2559 unsigned i;
2560 for (i = 0; i < gimple_phi_num_args (stmt); i++)
2561 {
2562 tree arg = gimple_phi_arg_def (stmt, i);
2563
2564 /* If this PHI has itself as an argument, ignore it.
2565 If all the other args produce the same result,
2566 we're still OK. */
2567 if (arg == gimple_phi_result (stmt))
2568 continue;
2569 else if (TREE_CODE (arg) == INTEGER_CST)
2570 {
2571 if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
2572 {
2573 if (!result)
2574 result = boolean_true_node;
2575 else if (!integer_onep (result))
2576 return NULL_TREE;
2577 }
2578 else if (!result)
2579 result = fold_build2 (code2, boolean_type_node,
2580 op2a, op2b);
2581 else if (!same_bool_comparison_p (result,
2582 code2, op2a, op2b))
2583 return NULL_TREE;
2584 }
2585 else if (TREE_CODE (arg) == SSA_NAME)
2586 {
2587 tree temp = or_var_with_comparison (arg, invert,
2588 code2, op2a, op2b);
2589 if (!temp)
2590 return NULL_TREE;
2591 else if (!result)
2592 result = temp;
2593 else if (!same_bool_result_p (result, temp))
2594 return NULL_TREE;
2595 }
2596 else
2597 return NULL_TREE;
2598 }
2599 return result;
2600 }
2601
2602 default:
2603 break;
2604 }
2605 }
2606 return NULL_TREE;
2607}
2608
2609/* Try to simplify the OR of two comparisons, specified by
2610 (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
2611 If this can be simplified to a single expression (without requiring
2612 introducing more SSA variables to hold intermediate values),
2613 return the resulting tree. Otherwise return NULL_TREE.
2614 If the result expression is non-null, it has boolean type. */
2615
2616tree
2617maybe_fold_or_comparisons (enum tree_code code1, tree op1a, tree op1b,
2618 enum tree_code code2, tree op2a, tree op2b)
2619{
2620 tree t = or_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b);
2621 if (t)
2622 return t;
2623 else
2624 return or_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b);
2625}