Line data Source code
1 : /* Statement simplification on GIMPLE.
2 : Copyright (C) 2010-2026 Free Software Foundation, Inc.
3 : Split out from tree-ssa-ccp.cc.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by the
9 : Free Software Foundation; either version 3, or (at your option) any
10 : later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT
13 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along 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 "backend.h"
25 : #include "target.h"
26 : #include "rtl.h"
27 : #include "tree.h"
28 : #include "gimple.h"
29 : #include "predict.h"
30 : #include "ssa.h"
31 : #include "cgraph.h"
32 : #include "gimple-pretty-print.h"
33 : #include "gimple-ssa-warn-access.h"
34 : #include "gimple-ssa-warn-restrict.h"
35 : #include "fold-const.h"
36 : #include "stmt.h"
37 : #include "expr.h"
38 : #include "stor-layout.h"
39 : #include "dumpfile.h"
40 : #include "gimple-iterator.h"
41 : #include "tree-pass.h"
42 : #include "gimple-fold.h"
43 : #include "gimplify.h"
44 : #include "tree-into-ssa.h"
45 : #include "tree-dfa.h"
46 : #include "tree-object-size.h"
47 : #include "tree-ssa.h"
48 : #include "tree-ssa-propagate.h"
49 : #include "ipa-utils.h"
50 : #include "tree-ssa-address.h"
51 : #include "langhooks.h"
52 : #include "gimplify-me.h"
53 : #include "dbgcnt.h"
54 : #include "builtins.h"
55 : #include "tree-eh.h"
56 : #include "gimple-match.h"
57 : #include "gomp-constants.h"
58 : #include "optabs-query.h"
59 : #include "omp-general.h"
60 : #include "tree-cfg.h"
61 : #include "fold-const-call.h"
62 : #include "stringpool.h"
63 : #include "attribs.h"
64 : #include "asan.h"
65 : #include "diagnostic-core.h"
66 : #include "intl.h"
67 : #include "calls.h"
68 : #include "tree-vector-builder.h"
69 : #include "tree-ssa-strlen.h"
70 : #include "varasm.h"
71 : #include "internal-fn.h"
72 : #include "gimple-range.h"
73 :
74 : enum strlen_range_kind {
75 : /* Compute the exact constant string length. */
76 : SRK_STRLEN,
77 : /* Compute the maximum constant string length. */
78 : SRK_STRLENMAX,
79 : /* Compute a range of string lengths bounded by object sizes. When
80 : the length of a string cannot be determined, consider as the upper
81 : bound the size of the enclosing object the string may be a member
82 : or element of. Also determine the size of the largest character
83 : array the string may refer to. */
84 : SRK_LENRANGE,
85 : /* Determine the integer value of the argument (not string length). */
86 : SRK_INT_VALUE
87 : };
88 :
89 : static bool
90 : get_range_strlen (tree, bitmap, strlen_range_kind, c_strlen_data *, unsigned);
91 :
92 : /* Return true when DECL can be referenced from current unit.
93 : FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
94 : We can get declarations that are not possible to reference for various
95 : reasons:
96 :
97 : 1) When analyzing C++ virtual tables.
98 : C++ virtual tables do have known constructors even
99 : when they are keyed to other compilation unit.
100 : Those tables can contain pointers to methods and vars
101 : in other units. Those methods have both STATIC and EXTERNAL
102 : set.
103 : 2) In WHOPR mode devirtualization might lead to reference
104 : to method that was partitioned elsewhere.
105 : In this case we have static VAR_DECL or FUNCTION_DECL
106 : that has no corresponding callgraph/varpool node
107 : declaring the body.
108 : 3) COMDAT functions referred by external vtables that
109 : we devirtualize only during final compilation stage.
110 : At this time we already decided that we will not output
111 : the function body and thus we can't reference the symbol
112 : directly. */
113 :
114 : static bool
115 4448741 : can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
116 : {
117 4448741 : varpool_node *vnode;
118 4448741 : struct cgraph_node *node;
119 4448741 : symtab_node *snode;
120 :
121 4448741 : if (DECL_ABSTRACT_P (decl))
122 : return false;
123 :
124 : /* We are concerned only about static/external vars and functions. */
125 1503646 : if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
126 5547701 : || !VAR_OR_FUNCTION_DECL_P (decl))
127 : return true;
128 :
129 : /* Static objects can be referred only if they are defined and not optimized
130 : out yet. */
131 4044055 : if (!TREE_PUBLIC (decl))
132 : {
133 1100199 : if (DECL_EXTERNAL (decl))
134 : return false;
135 : /* Before we start optimizing unreachable code we can be sure all
136 : static objects are defined. */
137 1100154 : if (symtab->function_flags_ready)
138 : return true;
139 1063144 : snode = symtab_node::get (decl);
140 1063144 : if (!snode || !snode->definition)
141 : return false;
142 1063089 : node = dyn_cast <cgraph_node *> (snode);
143 8731 : return !node || !node->inlined_to;
144 : }
145 :
146 : /* We will later output the initializer, so we can refer to it.
147 : So we are concerned only when DECL comes from initializer of
148 : external var or var that has been optimized out. */
149 2943856 : if (!from_decl
150 477449 : || !VAR_P (from_decl)
151 476322 : || (!DECL_EXTERNAL (from_decl)
152 203856 : && (vnode = varpool_node::get (from_decl)) != NULL
153 140475 : && vnode->definition)
154 3279709 : || (flag_ltrans
155 3 : && (vnode = varpool_node::get (from_decl)) != NULL
156 3 : && vnode->in_other_partition))
157 : return true;
158 : /* We are folding reference from external vtable. The vtable may refer
159 : to a symbol keyed to other compilation unit. The other compilation
160 : unit may be in separate DSO and the symbol may be hidden. */
161 335850 : if (DECL_VISIBILITY_SPECIFIED (decl)
162 329129 : && DECL_EXTERNAL (decl)
163 263533 : && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT
164 516047 : && (!(snode = symtab_node::get (decl)) || !snode->in_other_partition))
165 : return false;
166 : /* When function is public, we always can introduce new reference.
167 : Exception are the COMDAT functions where introducing a direct
168 : reference imply need to include function body in the current unit. */
169 155653 : if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
170 : return true;
171 : /* We have COMDAT. We are going to check if we still have definition
172 : or if the definition is going to be output in other partition.
173 : Bypass this when gimplifying; all needed functions will be produced.
174 :
175 : As observed in PR20991 for already optimized out comdat virtual functions
176 : it may be tempting to not necessarily give up because the copy will be
177 : output elsewhere when corresponding vtable is output.
178 : This is however not possible - ABI specify that COMDATs are output in
179 : units where they are used and when the other unit was compiled with LTO
180 : it is possible that vtable was kept public while the function itself
181 : was privatized. */
182 109956 : if (!symtab->function_flags_ready)
183 : return true;
184 :
185 97113 : snode = symtab_node::get (decl);
186 97113 : if (!snode
187 97113 : || ((!snode->definition || DECL_EXTERNAL (decl))
188 11931 : && (!snode->in_other_partition
189 0 : || (!snode->forced_by_abi && !snode->force_output))))
190 : return false;
191 59878 : node = dyn_cast <cgraph_node *> (snode);
192 59878 : return !node || !node->inlined_to;
193 : }
194 :
195 : /* CVAL is value taken from DECL_INITIAL of variable. Try to transform it into
196 : acceptable form for is_gimple_min_invariant.
197 : FROM_DECL (if non-NULL) specify variable whose constructor contains CVAL. */
198 :
199 : tree
200 15577493 : canonicalize_constructor_val (tree cval, tree from_decl)
201 : {
202 15577493 : if (CONSTANT_CLASS_P (cval))
203 : return cval;
204 :
205 9434984 : tree orig_cval = cval;
206 9434984 : STRIP_NOPS (cval);
207 9434984 : if (TREE_CODE (cval) == POINTER_PLUS_EXPR
208 9434984 : && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
209 : {
210 72287 : tree ptr = TREE_OPERAND (cval, 0);
211 72287 : if (is_gimple_min_invariant (ptr))
212 216150 : cval = build1_loc (EXPR_LOCATION (cval),
213 72050 : ADDR_EXPR, TREE_TYPE (ptr),
214 144100 : fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),
215 : ptr,
216 : fold_convert (ptr_type_node,
217 : TREE_OPERAND (cval, 1))));
218 : }
219 9434984 : if (TREE_CODE (cval) == ADDR_EXPR)
220 : {
221 5173399 : tree base = NULL_TREE;
222 5173399 : if (TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
223 : {
224 193 : base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
225 193 : if (base)
226 193 : TREE_OPERAND (cval, 0) = base;
227 : }
228 : else
229 5173206 : base = get_base_address (TREE_OPERAND (cval, 0));
230 5173399 : if (!base)
231 : return NULL_TREE;
232 :
233 2298504 : if (VAR_OR_FUNCTION_DECL_P (base)
234 6475404 : && !can_refer_decl_in_current_unit_p (base, from_decl))
235 : return NULL_TREE;
236 4992420 : if (TREE_TYPE (base) == error_mark_node)
237 : return NULL_TREE;
238 4992420 : if (VAR_P (base))
239 : /* ??? We should be able to assert that TREE_ADDRESSABLE is set,
240 : but since the use can be in a debug stmt we can't. */
241 : ;
242 2297619 : else if (TREE_CODE (base) == FUNCTION_DECL)
243 : {
244 : /* Make sure we create a cgraph node for functions we'll reference.
245 : They can be non-existent if the reference comes from an entry
246 : of an external vtable for example. */
247 1301120 : cgraph_node::get_create (base);
248 : }
249 : /* Fixup types in global initializers. */
250 4992420 : if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
251 40205 : cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
252 :
253 4992420 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
254 214814 : cval = fold_convert (TREE_TYPE (orig_cval), cval);
255 : return cval;
256 : }
257 : /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0. */
258 4261585 : if (TREE_CODE (cval) == INTEGER_CST)
259 : {
260 66590 : if (TREE_OVERFLOW_P (cval))
261 0 : cval = drop_tree_overflow (cval);
262 66590 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
263 63389 : cval = fold_convert (TREE_TYPE (orig_cval), cval);
264 : return cval;
265 : }
266 : return orig_cval;
267 : }
268 :
269 : /* If SYM is a constant variable with known value, return the value.
270 : NULL_TREE is returned otherwise. */
271 :
272 : tree
273 20448199 : get_symbol_constant_value (tree sym)
274 : {
275 20448199 : tree val = ctor_for_folding (sym);
276 20448199 : if (val != error_mark_node)
277 : {
278 39795 : if (val)
279 : {
280 37500 : val = canonicalize_constructor_val (unshare_expr (val), sym);
281 37500 : if (val
282 37500 : && is_gimple_min_invariant (val)
283 66134 : && useless_type_conversion_p (TREE_TYPE (sym), TREE_TYPE (val)))
284 : return val;
285 : else
286 8972 : return NULL_TREE;
287 : }
288 : /* Variables declared 'const' without an initializer
289 : have zero as the initializer if they may not be
290 : overridden at link or run time. */
291 2295 : if (!val
292 2295 : && is_gimple_reg_type (TREE_TYPE (sym)))
293 1958 : return build_zero_cst (TREE_TYPE (sym));
294 : }
295 :
296 : return NULL_TREE;
297 : }
298 :
299 :
300 :
301 : /* Subroutine of fold_stmt. We perform constant folding of the
302 : memory reference tree EXPR. */
303 :
304 : static tree
305 66188066 : maybe_fold_reference (tree expr)
306 : {
307 66188066 : tree result = NULL_TREE;
308 :
309 : /* Avoid expensive fold_const_aggregate_ref early on aggregate loads
310 : and esp. replacing STRING_CSTs inline. */
311 66188066 : if (!is_gimple_reg_type (TREE_TYPE (expr)))
312 : return NULL_TREE;
313 :
314 63063753 : if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
315 61720736 : || TREE_CODE (expr) == REALPART_EXPR
316 60926642 : || TREE_CODE (expr) == IMAGPART_EXPR)
317 64788662 : && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
318 5816 : result = fold_unary_loc (EXPR_LOCATION (expr),
319 : TREE_CODE (expr),
320 5816 : TREE_TYPE (expr),
321 5816 : TREE_OPERAND (expr, 0));
322 63057937 : else if (TREE_CODE (expr) == BIT_FIELD_REF
323 63057937 : && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
324 49 : result = fold_ternary_loc (EXPR_LOCATION (expr),
325 : TREE_CODE (expr),
326 49 : TREE_TYPE (expr),
327 49 : TREE_OPERAND (expr, 0),
328 49 : TREE_OPERAND (expr, 1),
329 49 : TREE_OPERAND (expr, 2));
330 : else
331 63057888 : result = fold_const_aggregate_ref (expr);
332 :
333 63063753 : if (result && is_gimple_min_invariant (result))
334 110307 : return result;
335 :
336 : return NULL_TREE;
337 : }
338 :
339 : /* Return true if EXPR is an acceptable right-hand-side for a
340 : GIMPLE assignment. We validate the entire tree, not just
341 : the root node, thus catching expressions that embed complex
342 : operands that are not permitted in GIMPLE. This function
343 : is needed because the folding routines in fold-const.cc
344 : may return such expressions in some cases, e.g., an array
345 : access with an embedded index addition. It may make more
346 : sense to have folding routines that are sensitive to the
347 : constraints on GIMPLE operands, rather than abandoning any
348 : any attempt to fold if the usual folding turns out to be too
349 : aggressive. */
350 :
351 : bool
352 0 : valid_gimple_rhs_p (tree expr)
353 : {
354 0 : enum tree_code code = TREE_CODE (expr);
355 :
356 0 : switch (TREE_CODE_CLASS (code))
357 : {
358 0 : case tcc_declaration:
359 0 : if (!is_gimple_variable (expr))
360 : return false;
361 : break;
362 :
363 : case tcc_constant:
364 : /* All constants are ok. */
365 : break;
366 :
367 0 : case tcc_comparison:
368 : /* GENERIC allows comparisons with non-boolean types, reject
369 : those for GIMPLE. Let vector-typed comparisons pass - rules
370 : for GENERIC and GIMPLE are the same here. */
371 0 : if (!(INTEGRAL_TYPE_P (TREE_TYPE (expr))
372 0 : && (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
373 0 : || TYPE_PRECISION (TREE_TYPE (expr)) == 1))
374 0 : && ! VECTOR_TYPE_P (TREE_TYPE (expr)))
375 : return false;
376 :
377 : /* Fallthru. */
378 0 : case tcc_binary:
379 0 : if (!is_gimple_val (TREE_OPERAND (expr, 0))
380 0 : || !is_gimple_val (TREE_OPERAND (expr, 1)))
381 : return false;
382 : break;
383 :
384 0 : case tcc_unary:
385 0 : if (!is_gimple_val (TREE_OPERAND (expr, 0)))
386 : return false;
387 : break;
388 :
389 0 : case tcc_expression:
390 0 : switch (code)
391 : {
392 0 : case ADDR_EXPR:
393 0 : {
394 0 : tree t;
395 0 : if (is_gimple_min_invariant (expr))
396 : return true;
397 0 : t = TREE_OPERAND (expr, 0);
398 0 : while (handled_component_p (t))
399 : {
400 : /* ??? More checks needed, see the GIMPLE verifier. */
401 0 : if ((TREE_CODE (t) == ARRAY_REF
402 0 : || TREE_CODE (t) == ARRAY_RANGE_REF)
403 0 : && !is_gimple_val (TREE_OPERAND (t, 1)))
404 : return false;
405 0 : t = TREE_OPERAND (t, 0);
406 : }
407 0 : if (!is_gimple_id (t))
408 : return false;
409 : }
410 : break;
411 :
412 0 : default:
413 0 : if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
414 : {
415 0 : if (!is_gimple_val (TREE_OPERAND (expr, 0))
416 0 : || !is_gimple_val (TREE_OPERAND (expr, 1))
417 0 : || !is_gimple_val (TREE_OPERAND (expr, 2)))
418 : return false;
419 : break;
420 : }
421 : return false;
422 : }
423 : break;
424 :
425 : case tcc_vl_exp:
426 : return false;
427 :
428 0 : case tcc_exceptional:
429 0 : if (code == CONSTRUCTOR)
430 : {
431 : unsigned i;
432 : tree elt;
433 0 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)
434 0 : if (!is_gimple_val (elt))
435 : return false;
436 : return true;
437 : }
438 0 : if (code != SSA_NAME)
439 : return false;
440 : break;
441 :
442 0 : case tcc_reference:
443 0 : if (code == BIT_FIELD_REF)
444 0 : return is_gimple_val (TREE_OPERAND (expr, 0));
445 : return false;
446 :
447 : default:
448 : return false;
449 : }
450 :
451 : return true;
452 : }
453 :
454 :
455 : /* Attempt to fold an assignment statement pointed-to by SI. Returns a
456 : replacement rhs for the statement or NULL_TREE if no simplification
457 : could be made. It is assumed that the operands have been previously
458 : folded. */
459 :
460 : static tree
461 263116346 : fold_gimple_assign (gimple_stmt_iterator *si)
462 : {
463 263116346 : gimple *stmt = gsi_stmt (*si);
464 263116346 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
465 263116346 : location_t loc = gimple_location (stmt);
466 :
467 263116346 : tree result = NULL_TREE;
468 :
469 263116346 : switch (get_gimple_rhs_class (subcode))
470 : {
471 174526122 : case GIMPLE_SINGLE_RHS:
472 174526122 : {
473 174526122 : tree rhs = gimple_assign_rhs1 (stmt);
474 :
475 174526122 : if (TREE_CLOBBER_P (rhs))
476 : return NULL_TREE;
477 :
478 160271664 : if (REFERENCE_CLASS_P (rhs))
479 63462554 : return maybe_fold_reference (rhs);
480 :
481 96809110 : else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
482 : {
483 178729 : tree val = OBJ_TYPE_REF_EXPR (rhs);
484 178729 : if (is_gimple_min_invariant (val))
485 : return val;
486 178698 : else if (flag_devirtualize && virtual_method_call_p (rhs))
487 : {
488 178658 : bool final;
489 178658 : vec <cgraph_node *>targets
490 178658 : = possible_polymorphic_call_targets (rhs, stmt, &final);
491 178930 : if (final && targets.length () <= 1 && dbg_cnt (devirt))
492 : {
493 42 : if (dump_enabled_p ())
494 : {
495 0 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
496 : "resolving virtual function address "
497 : "reference to function %s\n",
498 0 : targets.length () == 1
499 0 : ? targets[0]->name ()
500 : : "NULL");
501 : }
502 42 : if (targets.length () == 1)
503 : {
504 33 : val = fold_convert (TREE_TYPE (val),
505 : build_fold_addr_expr_loc
506 : (loc, targets[0]->decl));
507 33 : STRIP_USELESS_TYPE_CONVERSION (val);
508 : }
509 : else
510 : /* We cannot use __builtin_unreachable here because it
511 : cannot have address taken. */
512 9 : val = build_int_cst (TREE_TYPE (val), 0);
513 42 : return val;
514 : }
515 : }
516 : }
517 :
518 96630381 : else if (TREE_CODE (rhs) == ADDR_EXPR)
519 : {
520 15328655 : tree ref = TREE_OPERAND (rhs, 0);
521 15328655 : if (TREE_CODE (ref) == MEM_REF
522 15328655 : && integer_zerop (TREE_OPERAND (ref, 1)))
523 : {
524 2647 : result = TREE_OPERAND (ref, 0);
525 2647 : if (!useless_type_conversion_p (TREE_TYPE (rhs),
526 2647 : TREE_TYPE (result)))
527 0 : result = build1 (NOP_EXPR, TREE_TYPE (rhs), result);
528 : return result;
529 : }
530 : }
531 :
532 81301726 : else if (TREE_CODE (rhs) == CONSTRUCTOR
533 81301726 : && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
534 : {
535 : /* Fold a constant vector CONSTRUCTOR to VECTOR_CST. */
536 : unsigned i;
537 : tree val;
538 :
539 470050 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
540 465681 : if (! CONSTANT_CLASS_P (val))
541 : return NULL_TREE;
542 :
543 4369 : return build_vector_from_ctor (TREE_TYPE (rhs),
544 8738 : CONSTRUCTOR_ELTS (rhs));
545 : }
546 :
547 80928485 : else if (DECL_P (rhs)
548 80928485 : && is_gimple_reg_type (TREE_TYPE (rhs)))
549 12285332 : return get_symbol_constant_value (rhs);
550 : }
551 : break;
552 :
553 : case GIMPLE_UNARY_RHS:
554 : break;
555 :
556 : case GIMPLE_BINARY_RHS:
557 : break;
558 :
559 563693 : case GIMPLE_TERNARY_RHS:
560 1127386 : result = fold_ternary_loc (loc, subcode,
561 563693 : TREE_TYPE (gimple_assign_lhs (stmt)),
562 : gimple_assign_rhs1 (stmt),
563 : gimple_assign_rhs2 (stmt),
564 : gimple_assign_rhs3 (stmt));
565 :
566 563693 : if (result)
567 : {
568 0 : STRIP_USELESS_TYPE_CONVERSION (result);
569 0 : if (valid_gimple_rhs_p (result))
570 0 : return result;
571 : }
572 : break;
573 :
574 0 : case GIMPLE_INVALID_RHS:
575 0 : gcc_unreachable ();
576 : }
577 :
578 : return NULL_TREE;
579 : }
580 :
581 :
582 : /* Replace a statement at *SI_P with a sequence of statements in STMTS,
583 : adjusting the replacement stmts location and virtual operands.
584 :
585 : If the statements has an lhs, either:
586 :
587 : - the last statement of the new sequence must assign to the same lhs or
588 :
589 : - the caller must ensure that all uses of the old lhs have been
590 : removed before calling this function. This includes removing
591 : all debug uses. */
592 :
593 : void
594 134125 : gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
595 : {
596 134125 : gimple *stmt = gsi_stmt (*si_p);
597 :
598 134125 : if (gimple_has_location (stmt))
599 111996 : annotate_all_with_location (stmts, gimple_location (stmt));
600 :
601 : /* First iterate over the replacement statements backward, assigning
602 : virtual operands to their defining statements. */
603 134125 : gimple *laststore = NULL;
604 268250 : for (gimple_stmt_iterator i = gsi_last (stmts);
605 473715 : !gsi_end_p (i); gsi_prev (&i))
606 : {
607 205465 : gimple *new_stmt = gsi_stmt (i);
608 205465 : if ((gimple_assign_single_p (new_stmt)
609 129941 : && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
610 335136 : || (is_gimple_call (new_stmt)
611 14889 : && (gimple_call_flags (new_stmt)
612 14889 : & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0))
613 : {
614 2329 : tree vdef;
615 2329 : if (!laststore)
616 2323 : vdef = gimple_vdef (stmt);
617 : else
618 6 : vdef = make_ssa_name (gimple_vop (cfun), new_stmt);
619 2329 : gimple_set_vdef (new_stmt, vdef);
620 2329 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
621 1397 : SSA_NAME_DEF_STMT (vdef) = new_stmt;
622 : laststore = new_stmt;
623 : }
624 : }
625 :
626 : /* Second iterate over the statements forward, assigning virtual
627 : operands to their uses. */
628 134125 : tree reaching_vuse = gimple_vuse (stmt);
629 134125 : for (gimple_stmt_iterator i = gsi_start (stmts);
630 339590 : !gsi_end_p (i); gsi_next (&i))
631 : {
632 205465 : gimple *new_stmt = gsi_stmt (i);
633 : /* If the new statement possibly has a VUSE, update it with exact SSA
634 : name we know will reach this one. */
635 205465 : if (gimple_has_mem_ops (new_stmt))
636 205463 : gimple_set_vuse (new_stmt, reaching_vuse);
637 205465 : gimple_set_modified (new_stmt, true);
638 614990 : if (gimple_vdef (new_stmt))
639 : reaching_vuse = gimple_vdef (new_stmt);
640 : }
641 :
642 : /* If the new sequence does not do a store release the virtual
643 : definition of the original statement. */
644 134125 : if (reaching_vuse
645 223742 : && reaching_vuse == gimple_vuse (stmt))
646 : {
647 88226 : tree vdef = gimple_vdef (stmt);
648 88226 : if (vdef
649 1499 : && TREE_CODE (vdef) == SSA_NAME)
650 : {
651 1443 : unlink_stmt_vdef (stmt);
652 1443 : release_ssa_name (vdef);
653 : }
654 : }
655 :
656 : /* Finally replace the original statement with the sequence. */
657 134125 : gsi_replace_with_seq (si_p, stmts, false);
658 134125 : }
659 :
660 : /* Helper function for update_gimple_call and
661 : gimplify_and_update_call_from_tree. A GIMPLE_CALL STMT is being replaced
662 : with GIMPLE_CALL NEW_STMT. */
663 :
664 : static void
665 2458 : finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
666 : gimple *stmt)
667 : {
668 2458 : tree lhs = gimple_call_lhs (stmt);
669 2458 : gimple_call_set_lhs (new_stmt, lhs);
670 2458 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
671 794 : SSA_NAME_DEF_STMT (lhs) = new_stmt;
672 2458 : gimple_move_vops (new_stmt, stmt);
673 2458 : gimple_set_location (new_stmt, gimple_location (stmt));
674 2458 : if (gimple_block (new_stmt) == NULL_TREE)
675 1 : gimple_set_block (new_stmt, gimple_block (stmt));
676 2458 : gsi_replace (si_p, new_stmt, false);
677 2458 : }
678 :
679 : /* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN
680 : with number of arguments NARGS, where the arguments in GIMPLE form
681 : follow NARGS argument. */
682 :
683 : bool
684 2455 : update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
685 : {
686 2455 : va_list ap;
687 2455 : gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));
688 :
689 2455 : gcc_assert (is_gimple_call (stmt));
690 2455 : va_start (ap, nargs);
691 2455 : new_stmt = gimple_build_call_valist (fn, nargs, ap);
692 2455 : finish_update_gimple_call (si_p, new_stmt, stmt);
693 2455 : va_end (ap);
694 2455 : return true;
695 : }
696 :
697 : /* Return true if EXPR is a CALL_EXPR suitable for representation
698 : as a single GIMPLE_CALL statement. If the arguments require
699 : further gimplification, return false. */
700 :
701 : static bool
702 60436 : valid_gimple_call_p (tree expr)
703 : {
704 60436 : unsigned i, nargs;
705 :
706 60436 : if (TREE_CODE (expr) != CALL_EXPR)
707 : return false;
708 :
709 3 : nargs = call_expr_nargs (expr);
710 6 : for (i = 0; i < nargs; i++)
711 : {
712 3 : tree arg = CALL_EXPR_ARG (expr, i);
713 3 : if (is_gimple_reg_type (TREE_TYPE (arg)))
714 : {
715 3 : if (!is_gimple_val (arg))
716 : return false;
717 : }
718 : else
719 0 : if (!is_gimple_lvalue (arg))
720 : return false;
721 : }
722 :
723 : return true;
724 : }
725 :
726 : /* Convert EXPR into a GIMPLE value suitable for substitution on the
727 : RHS of an assignment. Insert the necessary statements before
728 : iterator *SI_P. The statement at *SI_P, which must be a GIMPLE_CALL
729 : is replaced. If the call is expected to produces a result, then it
730 : is replaced by an assignment of the new RHS to the result variable.
731 : If the result is to be ignored, then the call is replaced by a
732 : GIMPLE_NOP. A proper VDEF chain is retained by making the first
733 : VUSE and the last VDEF of the whole sequence be the same as the replaced
734 : statement and using new SSA names for stores in between. */
735 :
736 : void
737 60436 : gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
738 : {
739 60436 : tree lhs;
740 60436 : gimple *stmt, *new_stmt;
741 60436 : gimple_stmt_iterator i;
742 60436 : gimple_seq stmts = NULL;
743 :
744 60436 : stmt = gsi_stmt (*si_p);
745 :
746 60436 : gcc_assert (is_gimple_call (stmt));
747 :
748 60436 : if (valid_gimple_call_p (expr))
749 : {
750 : /* The call has simplified to another call. */
751 3 : tree fn = CALL_EXPR_FN (expr);
752 3 : unsigned i;
753 3 : unsigned nargs = call_expr_nargs (expr);
754 3 : vec<tree> args = vNULL;
755 3 : gcall *new_stmt;
756 :
757 3 : if (nargs > 0)
758 : {
759 3 : args.create (nargs);
760 3 : args.safe_grow_cleared (nargs, true);
761 :
762 9 : for (i = 0; i < nargs; i++)
763 3 : args[i] = CALL_EXPR_ARG (expr, i);
764 : }
765 :
766 3 : new_stmt = gimple_build_call_vec (fn, args);
767 3 : finish_update_gimple_call (si_p, new_stmt, stmt);
768 3 : args.release ();
769 3 : return;
770 : }
771 :
772 60433 : lhs = gimple_call_lhs (stmt);
773 60433 : if (lhs == NULL_TREE)
774 : {
775 2492 : push_gimplify_context (gimple_in_ssa_p (cfun));
776 1246 : gimplify_and_add (expr, &stmts);
777 1246 : pop_gimplify_context (NULL);
778 :
779 : /* We can end up with folding a memcpy of an empty class assignment
780 : which gets optimized away by C++ gimplification. */
781 1246 : if (gimple_seq_empty_p (stmts))
782 : {
783 1111 : if (gimple_in_ssa_p (cfun))
784 : {
785 1111 : unlink_stmt_vdef (stmt);
786 1111 : release_defs (stmt);
787 : }
788 1111 : gsi_replace (si_p, gimple_build_nop (), false);
789 1111 : return;
790 : }
791 : }
792 : else
793 : {
794 59187 : tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
795 59187 : new_stmt = gimple_build_assign (lhs, tmp);
796 59187 : i = gsi_last (stmts);
797 59187 : gsi_insert_after_without_update (&i, new_stmt,
798 : GSI_CONTINUE_LINKING);
799 : }
800 :
801 59322 : gsi_replace_with_seq_vops (si_p, stmts);
802 : }
803 :
804 : /* Print a message in the dump file recording transformation of FROM to TO. */
805 :
806 : static void
807 40511 : dump_transformation (gcall *from, gcall *to)
808 : {
809 40511 : if (dump_enabled_p ())
810 12 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, from, "simplified %T to %T\n",
811 : gimple_call_fn (from), gimple_call_fn (to));
812 40511 : }
813 :
814 : /* Replace the call at *GSI with the gimple value VAL. */
815 :
816 : void
817 90590 : replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
818 : {
819 90590 : gimple *stmt = gsi_stmt (*gsi);
820 90590 : tree lhs = gimple_call_lhs (stmt);
821 90590 : gimple *repl;
822 90590 : if (lhs)
823 : {
824 85580 : if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (val)))
825 2178 : val = fold_convert (TREE_TYPE (lhs), val);
826 85580 : repl = gimple_build_assign (lhs, val);
827 : }
828 : else
829 5010 : repl = gimple_build_nop ();
830 90590 : tree vdef = gimple_vdef (stmt);
831 90590 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
832 : {
833 5586 : unlink_stmt_vdef (stmt);
834 5586 : release_ssa_name (vdef);
835 : }
836 90590 : gsi_replace (gsi, repl, false);
837 90590 : }
838 :
839 : /* Replace the call at *GSI with the new call REPL and fold that
840 : again. */
841 :
842 : static void
843 40511 : replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
844 : {
845 40511 : gimple *stmt = gsi_stmt (*gsi);
846 40511 : dump_transformation (as_a <gcall *> (stmt), as_a <gcall *> (repl));
847 40511 : gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
848 40511 : gimple_set_location (repl, gimple_location (stmt));
849 40511 : gimple_move_vops (repl, stmt);
850 40511 : gsi_replace (gsi, repl, false);
851 40511 : fold_stmt (gsi);
852 40511 : }
853 :
854 : /* Return true if VAR is a VAR_DECL or a component thereof. */
855 :
856 : static bool
857 420685 : var_decl_component_p (tree var)
858 : {
859 420685 : tree inner = var;
860 602520 : while (handled_component_p (inner))
861 181835 : inner = TREE_OPERAND (inner, 0);
862 420685 : return (DECL_P (inner)
863 420685 : || (TREE_CODE (inner) == MEM_REF
864 43181 : && TREE_CODE (TREE_OPERAND (inner, 0)) == ADDR_EXPR));
865 : }
866 :
867 : /* Return TRUE if the SIZE argument, representing the size of an
868 : object, is in a range of values of which exactly zero is valid. */
869 :
870 : static bool
871 1054721 : size_must_be_zero_p (tree size)
872 : {
873 1054721 : if (integer_zerop (size))
874 : return true;
875 :
876 1052111 : if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size)))
877 : return false;
878 :
879 639905 : tree type = TREE_TYPE (size);
880 639905 : int prec = TYPE_PRECISION (type);
881 :
882 : /* Compute the value of SSIZE_MAX, the largest positive value that
883 : can be stored in ssize_t, the signed counterpart of size_t. */
884 639905 : wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
885 639905 : wide_int zero = wi::zero (TYPE_PRECISION (type));
886 639905 : int_range_max valid_range (type, zero, ssize_max);
887 639905 : int_range_max vr;
888 1279810 : get_range_query (cfun)->range_of_expr (vr, size);
889 :
890 639905 : if (vr.undefined_p ())
891 82 : vr.set_varying (TREE_TYPE (size));
892 639905 : vr.intersect (valid_range);
893 639905 : return vr.zero_p ();
894 639905 : }
895 :
896 : /* Fold function call to builtin mem{{,p}cpy,move}. Try to detect and
897 : diagnose (otherwise undefined) overlapping copies without preventing
898 : folding. When folded, GCC guarantees that overlapping memcpy has
899 : the same semantics as memmove. Call to the library memcpy need not
900 : provide the same guarantee. Return false if no simplification can
901 : be made. */
902 :
903 : static bool
904 1054721 : gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
905 : tree dest, tree src, enum built_in_function code)
906 : {
907 1054721 : gimple *stmt = gsi_stmt (*gsi);
908 1054721 : tree lhs = gimple_call_lhs (stmt);
909 1054721 : tree len = gimple_call_arg (stmt, 2);
910 1054721 : location_t loc = gimple_location (stmt);
911 :
912 : /* If the LEN parameter is a constant zero or in range where
913 : the only valid value is zero, return DEST. */
914 1054721 : if (size_must_be_zero_p (len))
915 : {
916 2655 : gimple *repl;
917 2655 : if (gimple_call_lhs (stmt))
918 60 : repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
919 : else
920 2595 : repl = gimple_build_nop ();
921 2655 : tree vdef = gimple_vdef (stmt);
922 2655 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
923 : {
924 477 : unlink_stmt_vdef (stmt);
925 477 : release_ssa_name (vdef);
926 : }
927 2655 : gsi_replace (gsi, repl, false);
928 2655 : return true;
929 : }
930 :
931 : /* If SRC and DEST are the same (and not volatile), return
932 : DEST{,+LEN,+LEN-1}. */
933 1052066 : if (operand_equal_p (src, dest, 0))
934 : {
935 : /* Avoid diagnosing exact overlap in calls to __builtin_memcpy.
936 : It's safe and may even be emitted by GCC itself (see bug
937 : 32667). */
938 88 : unlink_stmt_vdef (stmt);
939 176 : if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
940 48 : release_ssa_name (gimple_vdef (stmt));
941 88 : if (!lhs)
942 : {
943 67 : gsi_replace (gsi, gimple_build_nop (), false);
944 67 : return true;
945 : }
946 21 : goto done;
947 : }
948 2103956 : else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
949 : return false;
950 : else
951 : {
952 : /* We cannot (easily) change the type of the copy if it is a storage
953 : order barrier, i.e. is equivalent to a VIEW_CONVERT_EXPR that can
954 : modify the storage order of objects (see storage_order_barrier_p). */
955 1051978 : tree srctype
956 1065719 : = POINTER_TYPE_P (TREE_TYPE (src))
957 1065719 : ? TREE_TYPE (TREE_TYPE (src)) : NULL_TREE;
958 1051978 : tree desttype
959 1072429 : = POINTER_TYPE_P (TREE_TYPE (dest))
960 1072429 : ? TREE_TYPE (TREE_TYPE (dest)) : NULL_TREE;
961 1051978 : tree destvar, srcvar, srcoff;
962 1051978 : unsigned int src_align, dest_align;
963 1051978 : unsigned HOST_WIDE_INT tmp_len;
964 1051978 : const char *tmp_str;
965 :
966 : /* Build accesses at offset zero with a ref-all character type. */
967 1051978 : tree off0
968 1051978 : = build_int_cst (build_pointer_type_for_mode (char_type_node,
969 : ptr_mode, true), 0);
970 :
971 : /* If we can perform the copy efficiently with first doing all loads
972 : and then all stores inline it that way. Currently efficiently
973 : means that we can load all the memory into a single integer
974 : register which is what MOVE_MAX gives us. */
975 1051978 : src_align = get_pointer_alignment (src);
976 1051978 : dest_align = get_pointer_alignment (dest);
977 1051978 : if (tree_fits_uhwi_p (len)
978 401743 : && compare_tree_int (len, MOVE_MAX) <= 0
979 : /* FIXME: Don't transform copies from strings with known length.
980 : Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c
981 : from being handled, and the case was XFAILed for that reason.
982 : Now that it is handled and the XFAIL removed, as soon as other
983 : strlenopt tests that rely on it for passing are adjusted, this
984 : hack can be removed. */
985 301753 : && !c_strlen (src, 1)
986 193339 : && !((tmp_str = getbyterep (src, &tmp_len)) != NULL
987 80970 : && memchr (tmp_str, 0, tmp_len) == NULL)
988 126093 : && !(srctype
989 126093 : && AGGREGATE_TYPE_P (srctype)
990 60435 : && TYPE_REVERSE_STORAGE_ORDER (srctype))
991 1177938 : && !(desttype
992 125960 : && AGGREGATE_TYPE_P (desttype)
993 69530 : && TYPE_REVERSE_STORAGE_ORDER (desttype)))
994 : {
995 125927 : unsigned ilen = tree_to_uhwi (len);
996 125927 : if (pow2p_hwi (ilen))
997 : {
998 : /* Detect out-of-bounds accesses without issuing warnings.
999 : Avoid folding out-of-bounds copies but to avoid false
1000 : positives for unreachable code defer warning until after
1001 : DCE has worked its magic.
1002 : -Wrestrict is still diagnosed. */
1003 25258 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1004 : dest, src, len, len,
1005 25258 : false, false))
1006 981 : if (warning != OPT_Wrestrict)
1007 1048433 : return false;
1008 :
1009 24336 : scalar_int_mode imode;
1010 24336 : machine_mode mode;
1011 24336 : if (int_mode_for_size (ilen * BITS_PER_UNIT, 0).exists (&imode)
1012 48672 : && bitwise_mode_for_size (ilen
1013 24336 : * BITS_PER_UNIT).exists (&mode)
1014 48672 : && known_eq (GET_MODE_BITSIZE (mode), ilen * BITS_PER_UNIT)
1015 : /* If the destination pointer is not aligned we must be able
1016 : to emit an unaligned store. */
1017 24336 : && (dest_align >= GET_MODE_ALIGNMENT (mode)
1018 13144 : || !targetm.slow_unaligned_access (mode, dest_align)
1019 0 : || (optab_handler (movmisalign_optab, mode)
1020 : != CODE_FOR_nothing)))
1021 : {
1022 24336 : tree type = bitwise_type_for_mode (mode);
1023 24336 : tree srctype = type;
1024 24336 : tree desttype = type;
1025 24336 : if (src_align < GET_MODE_ALIGNMENT (mode))
1026 12528 : srctype = build_aligned_type (type, src_align);
1027 24336 : tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
1028 24336 : tree tem = fold_const_aggregate_ref (srcmem);
1029 24336 : if (tem)
1030 : srcmem = tem;
1031 23274 : else if (src_align < GET_MODE_ALIGNMENT (mode)
1032 12270 : && targetm.slow_unaligned_access (mode, src_align)
1033 23274 : && (optab_handler (movmisalign_optab, mode)
1034 : == CODE_FOR_nothing))
1035 : srcmem = NULL_TREE;
1036 23274 : if (srcmem)
1037 : {
1038 24336 : gimple *new_stmt;
1039 24336 : if (is_gimple_reg_type (TREE_TYPE (srcmem)))
1040 : {
1041 24336 : new_stmt = gimple_build_assign (NULL_TREE, srcmem);
1042 24336 : srcmem
1043 24336 : = make_ssa_name (TREE_TYPE (srcmem), new_stmt);
1044 24336 : gimple_assign_set_lhs (new_stmt, srcmem);
1045 48672 : gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1046 24336 : gimple_set_location (new_stmt, loc);
1047 24336 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1048 : }
1049 24336 : if (dest_align < GET_MODE_ALIGNMENT (mode))
1050 13144 : desttype = build_aligned_type (type, dest_align);
1051 24336 : new_stmt
1052 24336 : = gimple_build_assign (fold_build2 (MEM_REF, desttype,
1053 : dest, off0),
1054 : srcmem);
1055 24336 : gimple_move_vops (new_stmt, stmt);
1056 24336 : if (!lhs)
1057 : {
1058 20975 : gsi_replace (gsi, new_stmt, false);
1059 20975 : return true;
1060 : }
1061 3361 : gimple_set_location (new_stmt, loc);
1062 3361 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1063 3361 : goto done;
1064 : }
1065 : }
1066 : }
1067 : }
1068 :
1069 1026720 : if (code == BUILT_IN_MEMMOVE)
1070 : {
1071 : /* Both DEST and SRC must be pointer types.
1072 : ??? This is what old code did. Is the testing for pointer types
1073 : really mandatory?
1074 :
1075 : If either SRC is readonly or length is 1, we can use memcpy. */
1076 209782 : if (!dest_align || !src_align)
1077 : return false;
1078 209782 : if (readonly_data_expr (src)
1079 209782 : || (tree_fits_uhwi_p (len)
1080 32964 : && (MIN (src_align, dest_align) / BITS_PER_UNIT
1081 32964 : >= tree_to_uhwi (len))))
1082 : {
1083 1069386 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1084 20953 : if (!fn)
1085 : return false;
1086 20953 : gimple_call_set_fndecl (stmt, fn);
1087 20953 : gimple_call_set_arg (stmt, 0, dest);
1088 20953 : gimple_call_set_arg (stmt, 1, src);
1089 20953 : fold_stmt (gsi);
1090 20953 : return true;
1091 : }
1092 :
1093 : /* If *src and *dest can't overlap, optimize into memcpy as well. */
1094 188829 : if (TREE_CODE (src) == ADDR_EXPR
1095 5508 : && TREE_CODE (dest) == ADDR_EXPR)
1096 : {
1097 1826 : tree src_base, dest_base, fn;
1098 1826 : poly_int64 src_offset = 0, dest_offset = 0;
1099 1826 : poly_uint64 maxsize;
1100 :
1101 1826 : srcvar = TREE_OPERAND (src, 0);
1102 1826 : src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
1103 1826 : if (src_base == NULL)
1104 0 : src_base = srcvar;
1105 1826 : destvar = TREE_OPERAND (dest, 0);
1106 1826 : dest_base = get_addr_base_and_unit_offset (destvar,
1107 : &dest_offset);
1108 1826 : if (dest_base == NULL)
1109 0 : dest_base = destvar;
1110 1826 : if (!poly_int_tree_p (len, &maxsize))
1111 229 : maxsize = -1;
1112 1826 : if (SSA_VAR_P (src_base)
1113 1816 : && SSA_VAR_P (dest_base))
1114 : {
1115 1816 : if (operand_equal_p (src_base, dest_base, 0)
1116 1816 : && ranges_maybe_overlap_p (src_offset, maxsize,
1117 : dest_offset, maxsize))
1118 : return false;
1119 : }
1120 10 : else if (TREE_CODE (src_base) == MEM_REF
1121 0 : && TREE_CODE (dest_base) == MEM_REF)
1122 : {
1123 0 : if (! operand_equal_p (TREE_OPERAND (src_base, 0),
1124 0 : TREE_OPERAND (dest_base, 0), 0))
1125 0 : return false;
1126 0 : poly_offset_int full_src_offset
1127 0 : = mem_ref_offset (src_base) + src_offset;
1128 0 : poly_offset_int full_dest_offset
1129 0 : = mem_ref_offset (dest_base) + dest_offset;
1130 0 : if (ranges_maybe_overlap_p (full_src_offset, maxsize,
1131 : full_dest_offset, maxsize))
1132 : return false;
1133 0 : }
1134 : else
1135 : return false;
1136 :
1137 3213 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1138 1387 : if (!fn)
1139 : return false;
1140 1387 : gimple_call_set_fndecl (stmt, fn);
1141 1387 : gimple_call_set_arg (stmt, 0, dest);
1142 1387 : gimple_call_set_arg (stmt, 1, src);
1143 1387 : fold_stmt (gsi);
1144 1387 : return true;
1145 : }
1146 :
1147 : /* If the destination and source do not alias optimize into
1148 : memcpy as well. */
1149 187003 : if ((is_gimple_min_invariant (dest)
1150 183318 : || TREE_CODE (dest) == SSA_NAME)
1151 351822 : && (is_gimple_min_invariant (src)
1152 164843 : || TREE_CODE (src) == SSA_NAME))
1153 : {
1154 168061 : ao_ref destr, srcr;
1155 168061 : ao_ref_init_from_ptr_and_size (&destr, dest, len);
1156 168061 : ao_ref_init_from_ptr_and_size (&srcr, src, len);
1157 168061 : if (!refs_may_alias_p_1 (&destr, &srcr, false))
1158 : {
1159 10289 : tree fn;
1160 10289 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1161 10289 : if (!fn)
1162 10289 : return false;
1163 10289 : gimple_call_set_fndecl (stmt, fn);
1164 10289 : gimple_call_set_arg (stmt, 0, dest);
1165 10289 : gimple_call_set_arg (stmt, 1, src);
1166 10289 : fold_stmt (gsi);
1167 10289 : return true;
1168 : }
1169 : }
1170 :
1171 : return false;
1172 : }
1173 :
1174 816938 : if (!tree_fits_shwi_p (len))
1175 : return false;
1176 326397 : if (!srctype
1177 326397 : || (AGGREGATE_TYPE_P (srctype)
1178 205743 : && TYPE_REVERSE_STORAGE_ORDER (srctype)))
1179 : return false;
1180 326264 : if (!desttype
1181 326264 : || (AGGREGATE_TYPE_P (desttype)
1182 190917 : && TYPE_REVERSE_STORAGE_ORDER (desttype)))
1183 : return false;
1184 : /* In the following try to find a type that is most natural to be
1185 : used for the memcpy source and destination and that allows
1186 : the most optimization when memcpy is turned into a plain assignment
1187 : using that type. In theory we could always use a char[len] type
1188 : but that only gains us that the destination and source possibly
1189 : no longer will have their address taken. */
1190 326231 : if (TREE_CODE (srctype) == ARRAY_TYPE
1191 326231 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
1192 130995 : srctype = TREE_TYPE (srctype);
1193 326231 : if (TREE_CODE (desttype) == ARRAY_TYPE
1194 326231 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
1195 103365 : desttype = TREE_TYPE (desttype);
1196 326231 : if (TREE_ADDRESSABLE (srctype)
1197 326184 : || TREE_ADDRESSABLE (desttype))
1198 : return false;
1199 :
1200 : /* Make sure we are not copying using a floating-point mode or
1201 : a type whose size possibly does not match its precision. */
1202 651637 : if (FLOAT_MODE_P (TYPE_MODE (desttype))
1203 325238 : || TREE_CODE (desttype) == BOOLEAN_TYPE
1204 651352 : || TREE_CODE (desttype) == ENUMERAL_TYPE)
1205 940 : desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
1206 651839 : if (FLOAT_MODE_P (TYPE_MODE (srctype))
1207 325591 : || TREE_CODE (srctype) == BOOLEAN_TYPE
1208 651709 : || TREE_CODE (srctype) == ENUMERAL_TYPE)
1209 583 : srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
1210 326136 : if (!srctype)
1211 120 : srctype = desttype;
1212 326136 : if (!desttype)
1213 0 : desttype = srctype;
1214 326136 : if (!srctype)
1215 : return false;
1216 :
1217 326136 : src_align = get_pointer_alignment (src);
1218 326136 : dest_align = get_pointer_alignment (dest);
1219 :
1220 : /* Choose between src and destination type for the access based
1221 : on alignment, whether the access constitutes a register access
1222 : and whether it may actually expose a declaration for SSA rewrite
1223 : or SRA decomposition. Also try to expose a string constant, we
1224 : might be able to concatenate several of them later into a single
1225 : string store. */
1226 326136 : destvar = NULL_TREE;
1227 326136 : srcvar = NULL_TREE;
1228 326136 : if (TREE_CODE (dest) == ADDR_EXPR
1229 114910 : && var_decl_component_p (TREE_OPERAND (dest, 0))
1230 114906 : && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)
1231 25109 : && dest_align >= TYPE_ALIGN (desttype)
1232 351245 : && (is_gimple_reg_type (desttype)
1233 24681 : || src_align >= TYPE_ALIGN (desttype)))
1234 19784 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1235 306352 : else if (TREE_CODE (src) == ADDR_EXPR
1236 241580 : && var_decl_component_p (TREE_OPERAND (src, 0))
1237 47192 : && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
1238 9069 : && src_align >= TYPE_ALIGN (srctype)
1239 315405 : && (is_gimple_reg_type (srctype)
1240 8890 : || dest_align >= TYPE_ALIGN (srctype)))
1241 3140 : srcvar = fold_build2 (MEM_REF, srctype, src, off0);
1242 : /* FIXME: Don't transform copies from strings with known original length.
1243 : As soon as strlenopt tests that rely on it for passing are adjusted,
1244 : this hack can be removed. */
1245 303212 : else if (gimple_call_alloca_for_var_p (stmt)
1246 115 : && (srcvar = string_constant (src, &srcoff, NULL, NULL))
1247 3 : && integer_zerop (srcoff)
1248 3 : && tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (srcvar)), len)
1249 303215 : && dest_align >= TYPE_ALIGN (TREE_TYPE (srcvar)))
1250 3 : srctype = TREE_TYPE (srcvar);
1251 : else
1252 : return false;
1253 :
1254 : /* Now that we chose an access type express the other side in
1255 : terms of it if the target allows that with respect to alignment
1256 : constraints. */
1257 22927 : if (srcvar == NULL_TREE)
1258 : {
1259 19784 : if (src_align >= TYPE_ALIGN (desttype))
1260 19766 : srcvar = fold_build2 (MEM_REF, desttype, src, off0);
1261 : else
1262 : {
1263 18 : enum machine_mode mode = TYPE_MODE (desttype);
1264 18 : if ((mode == BLKmode && STRICT_ALIGNMENT)
1265 18 : || (targetm.slow_unaligned_access (mode, src_align)
1266 18 : && (optab_handler (movmisalign_optab, mode)
1267 : == CODE_FOR_nothing)))
1268 : return false;
1269 18 : srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
1270 : src_align);
1271 18 : srcvar = fold_build2 (MEM_REF, srctype, src, off0);
1272 : }
1273 : }
1274 3143 : else if (destvar == NULL_TREE)
1275 : {
1276 3143 : if (dest_align >= TYPE_ALIGN (srctype))
1277 3143 : destvar = fold_build2 (MEM_REF, srctype, dest, off0);
1278 : else
1279 : {
1280 0 : enum machine_mode mode = TYPE_MODE (srctype);
1281 0 : if ((mode == BLKmode && STRICT_ALIGNMENT)
1282 0 : || (targetm.slow_unaligned_access (mode, dest_align)
1283 0 : && (optab_handler (movmisalign_optab, mode)
1284 : == CODE_FOR_nothing)))
1285 : return false;
1286 0 : desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
1287 : dest_align);
1288 0 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1289 : }
1290 : }
1291 :
1292 : /* Same as above, detect out-of-bounds accesses without issuing
1293 : warnings. Avoid folding out-of-bounds copies but to avoid
1294 : false positives for unreachable code defer warning until
1295 : after DCE has worked its magic.
1296 : -Wrestrict is still diagnosed. */
1297 22927 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1298 : dest, src, len, len,
1299 22927 : false, false))
1300 1263 : if (warning != OPT_Wrestrict)
1301 : return false;
1302 :
1303 21672 : gimple *new_stmt;
1304 21672 : if (is_gimple_reg_type (TREE_TYPE (srcvar)))
1305 : {
1306 551 : tree tem = fold_const_aggregate_ref (srcvar);
1307 551 : if (tem)
1308 530 : srcvar = tem;
1309 551 : if (! is_gimple_min_invariant (srcvar))
1310 : {
1311 21 : new_stmt = gimple_build_assign (NULL_TREE, srcvar);
1312 21 : srcvar = make_ssa_name (TREE_TYPE (srcvar), new_stmt);
1313 21 : gimple_assign_set_lhs (new_stmt, srcvar);
1314 42 : gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1315 21 : gimple_set_location (new_stmt, loc);
1316 21 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1317 : }
1318 551 : new_stmt = gimple_build_assign (destvar, srcvar);
1319 551 : goto set_vop_and_replace;
1320 : }
1321 :
1322 : /* We get an aggregate copy. If the source is a STRING_CST, then
1323 : directly use its type to perform the copy. */
1324 21121 : if (TREE_CODE (srcvar) == STRING_CST)
1325 : desttype = srctype;
1326 :
1327 : /* Or else, use an unsigned char[] type to perform the copy in order
1328 : to preserve padding and to avoid any issues with TREE_ADDRESSABLE
1329 : types or float modes behavior on copying. */
1330 : else
1331 : {
1332 42236 : desttype = build_array_type_nelts (unsigned_char_type_node,
1333 21118 : tree_to_uhwi (len));
1334 21118 : srctype = desttype;
1335 21118 : if (src_align > TYPE_ALIGN (srctype))
1336 12680 : srctype = build_aligned_type (srctype, src_align);
1337 21118 : srcvar = fold_build2 (MEM_REF, srctype, src, off0);
1338 : }
1339 :
1340 21121 : if (dest_align > TYPE_ALIGN (desttype))
1341 13261 : desttype = build_aligned_type (desttype, dest_align);
1342 21121 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1343 21121 : new_stmt = gimple_build_assign (destvar, srcvar);
1344 :
1345 21672 : set_vop_and_replace:
1346 21672 : gimple_move_vops (new_stmt, stmt);
1347 21672 : if (!lhs)
1348 : {
1349 21488 : gsi_replace (gsi, new_stmt, false);
1350 21488 : return true;
1351 : }
1352 184 : gimple_set_location (new_stmt, loc);
1353 184 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1354 : }
1355 :
1356 3566 : done:
1357 3566 : gimple_seq stmts = NULL;
1358 3566 : if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
1359 3566 : len = NULL_TREE;
1360 198 : else if (code == BUILT_IN_MEMPCPY)
1361 : {
1362 198 : len = gimple_convert_to_ptrofftype (&stmts, loc, len);
1363 198 : dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
1364 198 : TREE_TYPE (dest), dest, len);
1365 : }
1366 : else
1367 0 : gcc_unreachable ();
1368 :
1369 3566 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1370 3566 : gimple *repl = gimple_build_assign (lhs, dest);
1371 3566 : gsi_replace (gsi, repl, false);
1372 3566 : return true;
1373 : }
1374 :
1375 : /* Transform a call to built-in bcmp(a, b, len) at *GSI into one
1376 : to built-in memcmp (a, b, len). */
1377 :
1378 : static bool
1379 148 : gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
1380 : {
1381 148 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCMP);
1382 :
1383 148 : if (!fn)
1384 : return false;
1385 :
1386 : /* Transform bcmp (a, b, len) into memcmp (a, b, len). */
1387 :
1388 148 : gimple *stmt = gsi_stmt (*gsi);
1389 296 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
1390 : return false;
1391 148 : tree a = gimple_call_arg (stmt, 0);
1392 148 : tree b = gimple_call_arg (stmt, 1);
1393 148 : tree len = gimple_call_arg (stmt, 2);
1394 :
1395 148 : gimple *repl = gimple_build_call (fn, 3, a, b, len);
1396 148 : replace_call_with_call_and_fold (gsi, repl);
1397 :
1398 148 : return true;
1399 : }
1400 :
1401 : /* Transform a call to built-in bcopy (src, dest, len) at *GSI into one
1402 : to built-in memmove (dest, src, len). */
1403 :
1404 : static bool
1405 367 : gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
1406 : {
1407 367 : tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
1408 :
1409 367 : if (!fn)
1410 : return false;
1411 :
1412 : /* bcopy has been removed from POSIX in Issue 7 but Issue 6 specifies
1413 : it's equivalent to memmove (not memcpy). Transform bcopy (src, dest,
1414 : len) into memmove (dest, src, len). */
1415 :
1416 367 : gimple *stmt = gsi_stmt (*gsi);
1417 734 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1418 : return false;
1419 367 : tree src = gimple_call_arg (stmt, 0);
1420 367 : tree dest = gimple_call_arg (stmt, 1);
1421 367 : tree len = gimple_call_arg (stmt, 2);
1422 :
1423 367 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
1424 367 : gimple_call_set_fntype (as_a <gcall *> (stmt), TREE_TYPE (fn));
1425 367 : replace_call_with_call_and_fold (gsi, repl);
1426 :
1427 367 : return true;
1428 : }
1429 :
1430 : /* Transform a call to built-in bzero (dest, len) at *GSI into one
1431 : to built-in memset (dest, 0, len). */
1432 :
1433 : static bool
1434 250 : gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
1435 : {
1436 250 : tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
1437 :
1438 250 : if (!fn)
1439 : return false;
1440 :
1441 : /* Transform bzero (dest, len) into memset (dest, 0, len). */
1442 :
1443 250 : gimple *stmt = gsi_stmt (*gsi);
1444 500 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1445 : return false;
1446 250 : tree dest = gimple_call_arg (stmt, 0);
1447 250 : tree len = gimple_call_arg (stmt, 1);
1448 :
1449 250 : gimple_seq seq = NULL;
1450 250 : gimple *repl = gimple_build_call (fn, 3, dest, integer_zero_node, len);
1451 250 : gimple_seq_add_stmt_without_update (&seq, repl);
1452 250 : gsi_replace_with_seq_vops (gsi, seq);
1453 250 : fold_stmt (gsi);
1454 :
1455 250 : return true;
1456 : }
1457 :
1458 : /* Fold function call to builtin memset or bzero at *GSI setting the
1459 : memory of size LEN to VAL. Return whether a simplification was made. */
1460 :
1461 : static bool
1462 315790 : gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
1463 : {
1464 315790 : gimple *stmt = gsi_stmt (*gsi);
1465 315790 : tree etype;
1466 315790 : unsigned HOST_WIDE_INT length, cval;
1467 :
1468 : /* If the LEN parameter is zero, return DEST. */
1469 315790 : if (integer_zerop (len))
1470 : {
1471 833 : replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
1472 833 : return true;
1473 : }
1474 :
1475 629914 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1476 : return false;
1477 :
1478 314879 : if (! tree_fits_uhwi_p (len))
1479 : return false;
1480 :
1481 207385 : length = tree_to_uhwi (len);
1482 :
1483 207385 : tree dest = gimple_call_arg (stmt, 0);
1484 207385 : if (length == 1
1485 207385 : && POINTER_TYPE_P (TREE_TYPE (dest)))
1486 : {
1487 : /* Keep the original call until object-size analysis has inspected it. */
1488 3440 : if (!(cfun->curr_properties & PROP_objsz))
1489 : return false;
1490 :
1491 : /* Detect out-of-bounds accesses without issuing warnings.
1492 : Avoid folding out-of-bounds accesses but to avoid false
1493 : positives for unreachable code defer warning until after
1494 : DCE has worked its magic.
1495 : -Wrestrict is still diagnosed. */
1496 587 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1497 : dest, NULL_TREE, len,
1498 587 : NULL_TREE, false, false))
1499 20 : if (warning != OPT_Wrestrict)
1500 : return false;
1501 :
1502 567 : etype = unsigned_char_type_node;
1503 567 : tree ptype = TREE_TYPE (TREE_TYPE (dest));
1504 567 : if (TYPE_VOLATILE (ptype))
1505 0 : etype = build_qualified_type (etype, TYPE_QUAL_VOLATILE);
1506 :
1507 567 : location_t loc = gimple_location (stmt);
1508 567 : tree cval_tree;
1509 567 : if (TREE_CODE (c) == INTEGER_CST)
1510 522 : cval_tree = fold_convert (etype, c);
1511 : else
1512 45 : cval_tree = gimple_convert (gsi, true, GSI_SAME_STMT, loc, etype, c);
1513 :
1514 : /* Build accesses at offset zero with a ref-all character type. */
1515 567 : tree off0
1516 567 : = build_int_cst (build_pointer_type_for_mode (char_type_node,
1517 : ptr_mode, true), 0);
1518 567 : tree var = fold_build2_loc (loc, MEM_REF, etype, dest, off0);
1519 567 : gimple *store = gimple_build_assign (var, cval_tree);
1520 567 : gimple_move_vops (store, stmt);
1521 567 : gimple_set_location (store, loc);
1522 567 : copy_warning (store, stmt);
1523 :
1524 567 : tree lhs = gimple_call_lhs (stmt);
1525 567 : if (!lhs)
1526 : {
1527 458 : gsi_replace (gsi, store, false);
1528 458 : return true;
1529 : }
1530 :
1531 109 : gsi_insert_before (gsi, store, GSI_SAME_STMT);
1532 109 : tree ret = dest;
1533 109 : if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (dest)))
1534 0 : ret = gimple_convert (gsi, true, GSI_SAME_STMT, loc,
1535 0 : TREE_TYPE (lhs), dest);
1536 109 : gimple *asgn = gimple_build_assign (lhs, ret);
1537 109 : gsi_replace (gsi, asgn, false);
1538 :
1539 109 : return true;
1540 : }
1541 :
1542 203945 : if (TREE_CODE (c) != INTEGER_CST)
1543 : return false;
1544 :
1545 198304 : tree var = dest;
1546 198304 : if (TREE_CODE (var) != ADDR_EXPR)
1547 : return false;
1548 :
1549 160484 : var = TREE_OPERAND (var, 0);
1550 160484 : if (TREE_THIS_VOLATILE (var))
1551 : return false;
1552 :
1553 160441 : etype = TREE_TYPE (var);
1554 160441 : if (TREE_CODE (etype) == ARRAY_TYPE)
1555 84922 : etype = TREE_TYPE (etype);
1556 :
1557 160441 : if ((!INTEGRAL_TYPE_P (etype)
1558 95368 : && !POINTER_TYPE_P (etype))
1559 160867 : || BITINT_TYPE_P (etype))
1560 : return false;
1561 :
1562 64195 : if (! var_decl_component_p (var))
1563 : return false;
1564 :
1565 64195 : if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
1566 1407 : || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
1567 65602 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
1568 65602 : || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
1569 : return false;
1570 :
1571 1407 : if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
1572 : return false;
1573 :
1574 1407 : if (!type_has_mode_precision_p (etype))
1575 7 : etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype),
1576 7 : TYPE_UNSIGNED (etype));
1577 :
1578 1407 : if (integer_zerop (c))
1579 : cval = 0;
1580 : else
1581 : {
1582 59 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
1583 : return NULL_TREE;
1584 :
1585 59 : cval = TREE_INT_CST_LOW (c);
1586 59 : cval &= 0xff;
1587 59 : cval |= cval << 8;
1588 59 : cval |= cval << 16;
1589 59 : cval |= (cval << 31) << 1;
1590 : }
1591 :
1592 1407 : var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
1593 1407 : gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
1594 1407 : gimple_move_vops (store, stmt);
1595 1407 : gimple_set_location (store, gimple_location (stmt));
1596 1407 : gsi_insert_before (gsi, store, GSI_SAME_STMT);
1597 1407 : if (gimple_call_lhs (stmt))
1598 : {
1599 0 : gimple *asgn = gimple_build_assign (gimple_call_lhs (stmt), dest);
1600 0 : gsi_replace (gsi, asgn, false);
1601 : }
1602 : else
1603 : {
1604 1407 : gimple_stmt_iterator gsi2 = *gsi;
1605 1407 : gsi_prev (gsi);
1606 1407 : gsi_remove (&gsi2, true);
1607 : }
1608 :
1609 : return true;
1610 : }
1611 :
1612 : /* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
1613 :
1614 : static bool
1615 449741 : get_range_strlen_tree (tree arg, bitmap visited, strlen_range_kind rkind,
1616 : c_strlen_data *pdata, unsigned eltsize)
1617 : {
1618 449741 : gcc_assert (TREE_CODE (arg) != SSA_NAME);
1619 :
1620 : /* The length computed by this invocation of the function. */
1621 449741 : tree val = NULL_TREE;
1622 :
1623 : /* True if VAL is an optimistic (tight) bound determined from
1624 : the size of the character array in which the string may be
1625 : stored. In that case, the computed VAL is used to set
1626 : PDATA->MAXBOUND. */
1627 449741 : bool tight_bound = false;
1628 :
1629 : /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
1630 449741 : if (TREE_CODE (arg) == ADDR_EXPR
1631 449741 : && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
1632 : {
1633 28770 : tree op = TREE_OPERAND (arg, 0);
1634 28770 : if (integer_zerop (TREE_OPERAND (op, 1)))
1635 : {
1636 12569 : tree aop0 = TREE_OPERAND (op, 0);
1637 12569 : if (TREE_CODE (aop0) == INDIRECT_REF
1638 12569 : && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
1639 0 : return get_range_strlen (TREE_OPERAND (aop0, 0), visited, rkind,
1640 0 : pdata, eltsize);
1641 : }
1642 16201 : else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
1643 16201 : && rkind == SRK_LENRANGE)
1644 : {
1645 : /* Fail if an array is the last member of a struct object
1646 : since it could be treated as a (fake) flexible array
1647 : member. */
1648 4800 : tree idx = TREE_OPERAND (op, 1);
1649 :
1650 4800 : arg = TREE_OPERAND (op, 0);
1651 4800 : tree optype = TREE_TYPE (arg);
1652 4800 : if (tree dom = TYPE_DOMAIN (optype))
1653 4800 : if (tree bound = TYPE_MAX_VALUE (dom))
1654 4800 : if (TREE_CODE (bound) == INTEGER_CST
1655 4800 : && TREE_CODE (idx) == INTEGER_CST
1656 8030 : && tree_int_cst_lt (bound, idx))
1657 : return false;
1658 : }
1659 : }
1660 :
1661 449533 : if (rkind == SRK_INT_VALUE)
1662 : {
1663 : /* We are computing the maximum value (not string length). */
1664 3083 : val = arg;
1665 3083 : if (TREE_CODE (val) != INTEGER_CST
1666 3083 : || tree_int_cst_sgn (val) < 0)
1667 : return false;
1668 : }
1669 : else
1670 : {
1671 446450 : c_strlen_data lendata = { };
1672 446450 : val = c_strlen (arg, 1, &lendata, eltsize);
1673 :
1674 446450 : if (!val && lendata.decl)
1675 : {
1676 : /* ARG refers to an unterminated const character array.
1677 : DATA.DECL with size DATA.LEN. */
1678 4184 : val = lendata.minlen;
1679 4184 : pdata->decl = lendata.decl;
1680 : }
1681 : }
1682 :
1683 : /* Set if VAL represents the maximum length based on array size (set
1684 : when exact length cannot be determined). */
1685 446960 : bool maxbound = false;
1686 :
1687 446960 : if (!val && rkind == SRK_LENRANGE)
1688 : {
1689 244808 : if (TREE_CODE (arg) == ADDR_EXPR)
1690 86963 : return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
1691 86963 : pdata, eltsize);
1692 :
1693 157845 : if (TREE_CODE (arg) == ARRAY_REF)
1694 : {
1695 18558 : tree optype = TREE_TYPE (TREE_OPERAND (arg, 0));
1696 :
1697 : /* Determine the "innermost" array type. */
1698 18558 : while (TREE_CODE (optype) == ARRAY_TYPE
1699 25504 : && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
1700 6946 : optype = TREE_TYPE (optype);
1701 :
1702 : /* Avoid arrays of pointers. */
1703 18558 : tree eltype = TREE_TYPE (optype);
1704 18558 : if (TREE_CODE (optype) != ARRAY_TYPE
1705 18558 : || !INTEGRAL_TYPE_P (eltype))
1706 : return false;
1707 :
1708 : /* Fail when the array bound is unknown or zero. */
1709 13629 : val = TYPE_SIZE_UNIT (optype);
1710 13629 : if (!val
1711 13557 : || TREE_CODE (val) != INTEGER_CST
1712 27158 : || integer_zerop (val))
1713 : return false;
1714 :
1715 13524 : val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
1716 : integer_one_node);
1717 :
1718 : /* Set the minimum size to zero since the string in
1719 : the array could have zero length. */
1720 13524 : pdata->minlen = ssize_int (0);
1721 :
1722 13524 : tight_bound = true;
1723 : }
1724 139287 : else if (TREE_CODE (arg) == COMPONENT_REF
1725 139287 : && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1)))
1726 : == ARRAY_TYPE))
1727 : {
1728 : /* Use the type of the member array to determine the upper
1729 : bound on the length of the array. This may be overly
1730 : optimistic if the array itself isn't NUL-terminated and
1731 : the caller relies on the subsequent member to contain
1732 : the NUL but that would only be considered valid if
1733 : the array were the last member of a struct. */
1734 :
1735 10030 : tree fld = TREE_OPERAND (arg, 1);
1736 :
1737 10030 : tree optype = TREE_TYPE (fld);
1738 :
1739 : /* Determine the "innermost" array type. */
1740 10030 : while (TREE_CODE (optype) == ARRAY_TYPE
1741 10592 : && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
1742 562 : optype = TREE_TYPE (optype);
1743 :
1744 : /* Fail when the array bound is unknown or zero. */
1745 10030 : val = TYPE_SIZE_UNIT (optype);
1746 10030 : if (!val
1747 9794 : || TREE_CODE (val) != INTEGER_CST
1748 19789 : || integer_zerop (val))
1749 : return false;
1750 9680 : val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
1751 : integer_one_node);
1752 :
1753 : /* Set the minimum size to zero since the string in
1754 : the array could have zero length. */
1755 9680 : pdata->minlen = ssize_int (0);
1756 :
1757 : /* The array size determined above is an optimistic bound
1758 : on the length. If the array isn't nul-terminated the
1759 : length computed by the library function would be greater.
1760 : Even though using strlen to cross the subobject boundary
1761 : is undefined, avoid drawing conclusions from the member
1762 : type about the length here. */
1763 9680 : tight_bound = true;
1764 : }
1765 129257 : else if (TREE_CODE (arg) == MEM_REF
1766 35042 : && TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
1767 10224 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == INTEGER_TYPE
1768 139043 : && TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
1769 : {
1770 : /* Handle a MEM_REF into a DECL accessing an array of integers,
1771 : being conservative about references to extern structures with
1772 : flexible array members that can be initialized to arbitrary
1773 : numbers of elements as an extension (static structs are okay). */
1774 9786 : tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
1775 9786 : if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
1776 19559 : && (decl_binds_to_current_def_p (ref)
1777 438 : || !array_ref_flexible_size_p (arg)))
1778 : {
1779 : /* Fail if the offset is out of bounds. Such accesses
1780 : should be diagnosed at some point. */
1781 9660 : val = DECL_SIZE_UNIT (ref);
1782 9660 : if (!val
1783 9488 : || TREE_CODE (val) != INTEGER_CST
1784 19148 : || integer_zerop (val))
1785 371 : return false;
1786 :
1787 9486 : poly_offset_int psiz = wi::to_offset (val);
1788 9486 : poly_offset_int poff = mem_ref_offset (arg);
1789 9486 : if (known_le (psiz, poff))
1790 : return false;
1791 :
1792 9289 : pdata->minlen = ssize_int (0);
1793 :
1794 : /* Subtract the offset and one for the terminating nul. */
1795 9289 : psiz -= poff;
1796 9289 : psiz -= 1;
1797 9289 : val = wide_int_to_tree (TREE_TYPE (val), psiz);
1798 : /* Since VAL reflects the size of a declared object
1799 : rather the type of the access it is not a tight bound. */
1800 : }
1801 : }
1802 119471 : else if (TREE_CODE (arg) == PARM_DECL || VAR_P (arg))
1803 : {
1804 : /* Avoid handling pointers to arrays. GCC might misuse
1805 : a pointer to an array of one bound to point to an array
1806 : object of a greater bound. */
1807 70906 : tree argtype = TREE_TYPE (arg);
1808 70906 : if (TREE_CODE (argtype) == ARRAY_TYPE)
1809 : {
1810 42425 : val = TYPE_SIZE_UNIT (argtype);
1811 42425 : if (!val
1812 41659 : || TREE_CODE (val) != INTEGER_CST
1813 84084 : || integer_zerop (val))
1814 : return false;
1815 41544 : val = wide_int_to_tree (TREE_TYPE (val),
1816 41544 : wi::sub (wi::to_wide (val), 1));
1817 :
1818 : /* Set the minimum size to zero since the string in
1819 : the array could have zero length. */
1820 41544 : pdata->minlen = ssize_int (0);
1821 : }
1822 : }
1823 : maxbound = true;
1824 : }
1825 :
1826 353361 : if (!val)
1827 : return false;
1828 :
1829 : /* Adjust the lower bound on the string length as necessary. */
1830 251763 : if (!pdata->minlen
1831 251763 : || (rkind != SRK_STRLEN
1832 78435 : && TREE_CODE (pdata->minlen) == INTEGER_CST
1833 78435 : && TREE_CODE (val) == INTEGER_CST
1834 78430 : && tree_int_cst_lt (val, pdata->minlen)))
1835 173347 : pdata->minlen = val;
1836 :
1837 251763 : if (pdata->maxbound && TREE_CODE (pdata->maxbound) == INTEGER_CST)
1838 : {
1839 : /* Adjust the tighter (more optimistic) string length bound
1840 : if necessary and proceed to adjust the more conservative
1841 : bound. */
1842 7673 : if (TREE_CODE (val) == INTEGER_CST)
1843 : {
1844 7673 : if (tree_int_cst_lt (pdata->maxbound, val))
1845 665 : pdata->maxbound = val;
1846 : }
1847 : else
1848 0 : pdata->maxbound = val;
1849 : }
1850 244090 : else if (pdata->maxbound || maxbound)
1851 : /* Set PDATA->MAXBOUND only if it either isn't INTEGER_CST or
1852 : if VAL corresponds to the maximum length determined based
1853 : on the type of the object. */
1854 70737 : pdata->maxbound = val;
1855 :
1856 251763 : if (tight_bound)
1857 : {
1858 : /* VAL computed above represents an optimistically tight bound
1859 : on the length of the string based on the referenced object's
1860 : or subobject's type. Determine the conservative upper bound
1861 : based on the enclosing object's size if possible. */
1862 23204 : if (rkind == SRK_LENRANGE)
1863 : {
1864 23204 : poly_int64 offset;
1865 23204 : tree base = get_addr_base_and_unit_offset (arg, &offset);
1866 23204 : if (!base)
1867 : {
1868 : /* When the call above fails due to a non-constant offset
1869 : assume the offset is zero and use the size of the whole
1870 : enclosing object instead. */
1871 7837 : base = get_base_address (arg);
1872 7837 : offset = 0;
1873 : }
1874 : /* If the base object is a pointer no upper bound on the length
1875 : can be determined. Otherwise the maximum length is equal to
1876 : the size of the enclosing object minus the offset of
1877 : the referenced subobject minus 1 (for the terminating nul). */
1878 23204 : tree type = TREE_TYPE (base);
1879 23204 : if (POINTER_TYPE_P (type)
1880 23200 : || (TREE_CODE (base) != PARM_DECL && !VAR_P (base))
1881 41906 : || !(val = DECL_SIZE_UNIT (base)))
1882 5749 : val = build_all_ones_cst (size_type_node);
1883 : else
1884 : {
1885 17455 : val = DECL_SIZE_UNIT (base);
1886 17455 : val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
1887 : size_int (offset + 1));
1888 : }
1889 : }
1890 : else
1891 : return false;
1892 : }
1893 :
1894 251763 : if (pdata->maxlen)
1895 : {
1896 : /* Adjust the more conservative bound if possible/necessary
1897 : and fail otherwise. */
1898 15124 : if (rkind != SRK_STRLEN)
1899 : {
1900 14193 : if (TREE_CODE (pdata->maxlen) != INTEGER_CST
1901 14193 : || TREE_CODE (val) != INTEGER_CST)
1902 : return false;
1903 :
1904 14188 : if (tree_int_cst_lt (pdata->maxlen, val))
1905 1364 : pdata->maxlen = val;
1906 : return true;
1907 : }
1908 931 : else if (simple_cst_equal (val, pdata->maxlen) != 1)
1909 : {
1910 : /* Fail if the length of this ARG is different from that
1911 : previously determined from another ARG. */
1912 : return false;
1913 : }
1914 : }
1915 :
1916 236763 : pdata->maxlen = val;
1917 236763 : return rkind == SRK_LENRANGE || !integer_all_onesp (val);
1918 : }
1919 :
1920 : /* For an ARG referencing one or more strings, try to obtain the range
1921 : of their lengths, or the size of the largest array ARG refers to if
1922 : the range of lengths cannot be determined, and store all in *PDATA.
1923 : For an integer ARG (when RKIND == SRK_INT_VALUE), try to determine
1924 : the maximum constant value.
1925 : If ARG is an SSA_NAME, follow its use-def chains. When RKIND ==
1926 : SRK_STRLEN, then if PDATA->MAXLEN is not equal to the determined
1927 : length or if we are unable to determine the length, return false.
1928 : VISITED is a bitmap of visited variables.
1929 : RKIND determines the kind of value or range to obtain (see
1930 : strlen_range_kind).
1931 : Set PDATA->DECL if ARG refers to an unterminated constant array.
1932 : On input, set ELTSIZE to 1 for normal single byte character strings,
1933 : and either 2 or 4 for wide character strings (the size of wchar_t).
1934 : Return true if *PDATA was successfully populated and false otherwise. */
1935 :
1936 : static bool
1937 1369369 : get_range_strlen (tree arg, bitmap visited,
1938 : strlen_range_kind rkind,
1939 : c_strlen_data *pdata, unsigned eltsize)
1940 : {
1941 :
1942 1451292 : if (TREE_CODE (arg) != SSA_NAME)
1943 449741 : return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);
1944 :
1945 : /* If ARG is registered for SSA update we cannot look at its defining
1946 : statement. */
1947 1001551 : if (name_registered_for_update_p (arg))
1948 : return false;
1949 :
1950 : /* If we were already here, break the infinite cycle. */
1951 1001551 : if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
1952 : return true;
1953 :
1954 995840 : tree var = arg;
1955 995840 : gimple *def_stmt = SSA_NAME_DEF_STMT (var);
1956 :
1957 995840 : switch (gimple_code (def_stmt))
1958 : {
1959 125666 : case GIMPLE_ASSIGN:
1960 : /* The RHS of the statement defining VAR must either have a
1961 : constant length or come from another SSA_NAME with a constant
1962 : length. */
1963 125666 : if (gimple_assign_single_p (def_stmt)
1964 125666 : || gimple_assign_unary_nop_p (def_stmt))
1965 : {
1966 81923 : tree rhs = gimple_assign_rhs1 (def_stmt);
1967 81923 : return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
1968 : }
1969 43743 : else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
1970 : {
1971 246 : tree ops[2] = { gimple_assign_rhs2 (def_stmt),
1972 246 : gimple_assign_rhs3 (def_stmt) };
1973 :
1974 738 : for (unsigned int i = 0; i < 2; i++)
1975 492 : if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
1976 : {
1977 28 : if (rkind != SRK_LENRANGE)
1978 : return false;
1979 : /* Set the upper bound to the maximum to prevent
1980 : it from being adjusted in the next iteration but
1981 : leave MINLEN and the more conservative MAXBOUND
1982 : determined so far alone (or leave them null if
1983 : they haven't been set yet). That the MINLEN is
1984 : in fact zero can be determined from MAXLEN being
1985 : unbounded but the discovered minimum is used for
1986 : diagnostics. */
1987 28 : pdata->maxlen = build_all_ones_cst (size_type_node);
1988 : }
1989 : return true;
1990 : }
1991 : return false;
1992 :
1993 : case GIMPLE_PHI:
1994 : /* Unless RKIND == SRK_LENRANGE, all arguments of the PHI node
1995 : must have a constant length. */
1996 85052 : for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
1997 : {
1998 61851 : tree arg = gimple_phi_arg (def_stmt, i)->def;
1999 :
2000 : /* If this PHI has itself as an argument, we cannot
2001 : determine the string length of this argument. However,
2002 : if we can find a constant string length for the other
2003 : PHI args then we can still be sure that this is a
2004 : constant string length. So be optimistic and just
2005 : continue with the next argument. */
2006 61851 : if (arg == gimple_phi_result (def_stmt))
2007 0 : continue;
2008 :
2009 61851 : if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
2010 : {
2011 29996 : if (rkind != SRK_LENRANGE)
2012 : return false;
2013 : /* Set the upper bound to the maximum to prevent
2014 : it from being adjusted in the next iteration but
2015 : leave MINLEN and the more conservative MAXBOUND
2016 : determined so far alone (or leave them null if
2017 : they haven't been set yet). That the MINLEN is
2018 : in fact zero can be determined from MAXLEN being
2019 : unbounded but the discovered minimum is used for
2020 : diagnostics. */
2021 28262 : pdata->maxlen = build_all_ones_cst (size_type_node);
2022 : }
2023 : }
2024 : return true;
2025 :
2026 : default:
2027 : return false;
2028 : }
2029 : }
2030 :
2031 : /* Try to obtain the range of the lengths of the string(s) referenced
2032 : by ARG, or the size of the largest array ARG refers to if the range
2033 : of lengths cannot be determined, and store all in *PDATA which must
2034 : be zero-initialized on input except PDATA->MAXBOUND may be set to
2035 : a non-null tree node other than INTEGER_CST to request to have it
2036 : set to the length of the longest string in a PHI. ELTSIZE is
2037 : the expected size of the string element in bytes: 1 for char and
2038 : some power of 2 for wide characters.
2039 : Return true if the range [PDATA->MINLEN, PDATA->MAXLEN] is suitable
2040 : for optimization. Returning false means that a nonzero PDATA->MINLEN
2041 : doesn't reflect the true lower bound of the range when PDATA->MAXLEN
2042 : is -1 (in that case, the actual range is indeterminate, i.e.,
2043 : [0, PTRDIFF_MAX - 2]. */
2044 :
2045 : bool
2046 1146981 : get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
2047 : {
2048 1146981 : auto_bitmap visited;
2049 1146981 : tree maxbound = pdata->maxbound;
2050 :
2051 1146981 : if (!get_range_strlen (arg, visited, SRK_LENRANGE, pdata, eltsize))
2052 : {
2053 : /* On failure extend the length range to an impossible maximum
2054 : (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
2055 : members can stay unchanged regardless. */
2056 922302 : pdata->minlen = ssize_int (0);
2057 922302 : pdata->maxlen = build_all_ones_cst (size_type_node);
2058 : }
2059 224679 : else if (!pdata->minlen)
2060 9088 : pdata->minlen = ssize_int (0);
2061 :
2062 : /* If it's unchanged from it initial non-null value, set the conservative
2063 : MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
2064 1146981 : if (maxbound && pdata->maxbound == maxbound)
2065 650797 : pdata->maxbound = build_all_ones_cst (size_type_node);
2066 :
2067 1146981 : return !integer_all_onesp (pdata->maxlen);
2068 1146981 : }
2069 :
2070 : /* Return the maximum value for ARG given RKIND (see strlen_range_kind).
2071 : For ARG of pointer types, NONSTR indicates if the caller is prepared
2072 : to handle unterminated strings. For integer ARG and when RKIND ==
2073 : SRK_INT_VALUE, NONSTR must be null.
2074 :
2075 : If an unterminated array is discovered and our caller handles
2076 : unterminated arrays, then bubble up the offending DECL and
2077 : return the maximum size. Otherwise return NULL. */
2078 :
2079 : static tree
2080 95910 : get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
2081 : {
2082 : /* A non-null NONSTR is meaningless when determining the maximum
2083 : value of an integer ARG. */
2084 95910 : gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL);
2085 :
2086 : // If arg is already a constant, simply return it.
2087 95910 : if (TREE_CODE (arg) == INTEGER_CST && rkind == SRK_INT_VALUE)
2088 : return arg;
2089 :
2090 : /* ARG must have an integral type when RKIND says so. */
2091 72983 : gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
2092 :
2093 73082 : auto_bitmap visited;
2094 :
2095 : /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
2096 : is unbounded. */
2097 73082 : c_strlen_data lendata = { };
2098 73082 : if (!get_range_strlen (arg, visited, rkind, &lendata, /* eltsize = */1))
2099 49971 : lendata.maxlen = NULL_TREE;
2100 23111 : else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
2101 0 : lendata.maxlen = NULL_TREE;
2102 :
2103 73082 : if (nonstr)
2104 : {
2105 : /* For callers prepared to handle unterminated arrays set
2106 : *NONSTR to point to the declaration of the array and return
2107 : the maximum length/size. */
2108 24067 : *nonstr = lendata.decl;
2109 24067 : return lendata.maxlen;
2110 : }
2111 :
2112 : /* Fail if the constant array isn't nul-terminated. */
2113 49015 : return lendata.decl ? NULL_TREE : lendata.maxlen;
2114 73082 : }
2115 :
2116 : /* Return true if LEN is known to be less than or equal to (or if STRICT is
2117 : true, strictly less than) the lower bound of SIZE at compile time and false
2118 : otherwise. */
2119 :
2120 : static bool
2121 63260 : known_lower (gimple *stmt, tree len, tree size, bool strict = false)
2122 : {
2123 63260 : if (len == NULL_TREE)
2124 : return false;
2125 :
2126 236290 : wide_int size_range[2];
2127 236290 : wide_int len_range[2];
2128 47258 : if (get_range (len, stmt, len_range) && get_range (size, stmt, size_range))
2129 : {
2130 16555 : if (strict)
2131 1867 : return wi::ltu_p (len_range[1], size_range[0]);
2132 : else
2133 14688 : return wi::leu_p (len_range[1], size_range[0]);
2134 : }
2135 :
2136 : return false;
2137 283548 : }
2138 :
2139 : /* Fold function call to builtin strcpy with arguments DEST and SRC.
2140 : If LEN is not NULL, it represents the length of the string to be
2141 : copied. Return NULL_TREE if no simplification can be made. */
2142 :
2143 : static bool
2144 26129 : gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
2145 : tree dest, tree src)
2146 : {
2147 26129 : gimple *stmt = gsi_stmt (*gsi);
2148 26129 : location_t loc = gimple_location (stmt);
2149 26129 : tree fn;
2150 :
2151 : /* If SRC and DEST are the same (and not volatile), return DEST. */
2152 26129 : if (operand_equal_p (src, dest, 0))
2153 : {
2154 : /* Issue -Wrestrict unless the pointers are null (those do
2155 : not point to objects and so do not indicate an overlap;
2156 : such calls could be the result of sanitization and jump
2157 : threading). */
2158 86 : if (!integer_zerop (dest) && !warning_suppressed_p (stmt, OPT_Wrestrict))
2159 : {
2160 51 : tree func = gimple_call_fndecl (stmt);
2161 :
2162 51 : warning_at (loc, OPT_Wrestrict,
2163 : "%qD source argument is the same as destination",
2164 : func);
2165 : }
2166 :
2167 86 : replace_call_with_value (gsi, dest);
2168 86 : return true;
2169 : }
2170 :
2171 26043 : if (optimize_function_for_size_p (cfun))
2172 : return false;
2173 :
2174 24067 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2175 24067 : if (!fn)
2176 : return false;
2177 :
2178 : /* Set to non-null if ARG refers to an unterminated array. */
2179 24067 : tree nonstr = NULL;
2180 24067 : tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);
2181 :
2182 24067 : if (nonstr)
2183 : {
2184 : /* Avoid folding calls with unterminated arrays. */
2185 531 : if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
2186 69 : warn_string_no_nul (loc, stmt, "strcpy", src, nonstr);
2187 531 : suppress_warning (stmt, OPT_Wstringop_overread);
2188 531 : return false;
2189 : }
2190 :
2191 26436 : if (!len || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
2192 : return false;
2193 :
2194 2900 : len = fold_convert_loc (loc, size_type_node, len);
2195 2900 : len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
2196 2900 : len = force_gimple_operand_gsi (gsi, len, true,
2197 : NULL_TREE, true, GSI_SAME_STMT);
2198 2900 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2199 2900 : replace_call_with_call_and_fold (gsi, repl);
2200 2900 : return true;
2201 : }
2202 :
2203 : /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
2204 : If SLEN is not NULL, it represents the length of the source string.
2205 : Return NULL_TREE if no simplification can be made. */
2206 :
2207 : static bool
2208 17274 : gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
2209 : tree dest, tree src, tree len)
2210 : {
2211 17274 : gimple *stmt = gsi_stmt (*gsi);
2212 17274 : location_t loc = gimple_location (stmt);
2213 17274 : bool nonstring = get_attr_nonstring_decl (dest) != NULL_TREE;
2214 :
2215 : /* If the LEN parameter is zero, return DEST. */
2216 17274 : if (integer_zerop (len))
2217 : {
2218 : /* Avoid warning if the destination refers to an array/pointer
2219 : decorate with attribute nonstring. */
2220 167 : if (!nonstring)
2221 : {
2222 155 : tree fndecl = gimple_call_fndecl (stmt);
2223 :
2224 : /* Warn about the lack of nul termination: the result is not
2225 : a (nul-terminated) string. */
2226 155 : tree slen = get_maxval_strlen (src, SRK_STRLEN);
2227 155 : if (slen && !integer_zerop (slen))
2228 24 : warning_at (loc, OPT_Wstringop_truncation,
2229 : "%qD destination unchanged after copying no bytes "
2230 : "from a string of length %E",
2231 : fndecl, slen);
2232 : else
2233 131 : warning_at (loc, OPT_Wstringop_truncation,
2234 : "%qD destination unchanged after copying no bytes",
2235 : fndecl);
2236 : }
2237 :
2238 167 : replace_call_with_value (gsi, dest);
2239 167 : return true;
2240 : }
2241 :
2242 : /* We can't compare slen with len as constants below if len is not a
2243 : constant. */
2244 17107 : if (TREE_CODE (len) != INTEGER_CST)
2245 : return false;
2246 :
2247 : /* Now, we must be passed a constant src ptr parameter. */
2248 10748 : tree slen = get_maxval_strlen (src, SRK_STRLEN);
2249 10748 : if (!slen || TREE_CODE (slen) != INTEGER_CST)
2250 : return false;
2251 :
2252 : /* The size of the source string including the terminating nul. */
2253 1780 : tree ssize = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
2254 :
2255 : /* We do not support simplification of this case, though we do
2256 : support it when expanding trees into RTL. */
2257 : /* FIXME: generate a call to __builtin_memset. */
2258 1780 : if (tree_int_cst_lt (ssize, len))
2259 : return false;
2260 :
2261 : /* Diagnose truncation that leaves the copy unterminated. */
2262 695 : maybe_diag_stxncpy_trunc (*gsi, src, len);
2263 :
2264 : /* OK transform into builtin memcpy. */
2265 695 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2266 1390 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
2267 : return false;
2268 :
2269 695 : len = fold_convert_loc (loc, size_type_node, len);
2270 695 : len = force_gimple_operand_gsi (gsi, len, true,
2271 : NULL_TREE, true, GSI_SAME_STMT);
2272 695 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2273 695 : replace_call_with_call_and_fold (gsi, repl);
2274 :
2275 695 : return true;
2276 : }
2277 :
2278 : /* Fold function call to builtin strchr or strrchr.
2279 : If both arguments are constant, evaluate and fold the result,
2280 : otherwise simplify str(r)chr (str, 0) into str + strlen (str).
2281 : In general strlen is significantly faster than strchr
2282 : due to being a simpler operation. */
2283 : static bool
2284 5470 : gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
2285 : {
2286 5470 : gimple *stmt = gsi_stmt (*gsi);
2287 5470 : tree str = gimple_call_arg (stmt, 0);
2288 5470 : tree c = gimple_call_arg (stmt, 1);
2289 5470 : location_t loc = gimple_location (stmt);
2290 5470 : const char *p;
2291 5470 : char ch;
2292 :
2293 5470 : if (!gimple_call_lhs (stmt))
2294 : return false;
2295 :
2296 : /* Avoid folding if the first argument is not a nul-terminated array.
2297 : Defer warning until later. */
2298 5460 : if (!check_nul_terminated_array (NULL_TREE, str))
2299 : return false;
2300 :
2301 5376 : if ((p = c_getstr (str)) && target_char_cst_p (c, &ch))
2302 : {
2303 41 : const char *p1 = is_strrchr ? strrchr (p, ch) : strchr (p, ch);
2304 :
2305 41 : if (p1 == NULL)
2306 : {
2307 1 : replace_call_with_value (gsi, integer_zero_node);
2308 1 : return true;
2309 : }
2310 :
2311 40 : tree len = build_int_cst (size_type_node, p1 - p);
2312 40 : gimple_seq stmts = NULL;
2313 40 : gimple *new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
2314 : POINTER_PLUS_EXPR, str, len);
2315 40 : gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2316 40 : gsi_replace_with_seq_vops (gsi, stmts);
2317 40 : return true;
2318 : }
2319 :
2320 5417 : if (!integer_zerop (c) || (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)))
2321 : return false;
2322 :
2323 : /* Transform strrchr (s, 0) to strchr (s, 0) when optimizing for size. */
2324 82 : if (is_strrchr && optimize_function_for_size_p (cfun))
2325 : {
2326 3 : tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
2327 :
2328 3 : if (strchr_fn)
2329 : {
2330 3 : gimple *repl = gimple_build_call (strchr_fn, 2, str, c);
2331 3 : replace_call_with_call_and_fold (gsi, repl);
2332 3 : return true;
2333 : }
2334 :
2335 : return false;
2336 : }
2337 :
2338 79 : tree len;
2339 79 : tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2340 :
2341 79 : if (!strlen_fn)
2342 : return false;
2343 :
2344 : /* Create newstr = strlen (str). */
2345 79 : gimple_seq stmts = NULL;
2346 79 : gimple *new_stmt = gimple_build_call (strlen_fn, 1, str);
2347 79 : gimple_set_location (new_stmt, loc);
2348 79 : len = make_ssa_name (size_type_node);
2349 79 : gimple_call_set_lhs (new_stmt, len);
2350 79 : gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2351 :
2352 : /* Create (str p+ strlen (str)). */
2353 79 : new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
2354 : POINTER_PLUS_EXPR, str, len);
2355 79 : gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2356 79 : gsi_replace_with_seq_vops (gsi, stmts);
2357 : /* gsi now points at the assignment to the lhs, get a
2358 : stmt iterator to the strlen.
2359 : ??? We can't use gsi_for_stmt as that doesn't work when the
2360 : CFG isn't built yet. */
2361 79 : gimple_stmt_iterator gsi2 = *gsi;
2362 79 : gsi_prev (&gsi2);
2363 79 : fold_stmt (&gsi2);
2364 79 : return true;
2365 : }
2366 :
2367 : /* Fold function call to builtin strstr.
2368 : If both arguments are constant, evaluate and fold the result,
2369 : additionally fold strstr (x, "") into x and strstr (x, "c")
2370 : into strchr (x, 'c'). */
2371 : static bool
2372 4372 : gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
2373 : {
2374 4372 : gimple *stmt = gsi_stmt (*gsi);
2375 4372 : if (!gimple_call_lhs (stmt))
2376 : return false;
2377 :
2378 4369 : tree haystack = gimple_call_arg (stmt, 0);
2379 4369 : tree needle = gimple_call_arg (stmt, 1);
2380 :
2381 : /* Avoid folding if either argument is not a nul-terminated array.
2382 : Defer warning until later. */
2383 4369 : if (!check_nul_terminated_array (NULL_TREE, haystack)
2384 4369 : || !check_nul_terminated_array (NULL_TREE, needle))
2385 : return false;
2386 :
2387 4350 : const char *q = c_getstr (needle);
2388 4350 : if (q == NULL)
2389 : return false;
2390 :
2391 3173 : if (const char *p = c_getstr (haystack))
2392 : {
2393 14 : const char *r = strstr (p, q);
2394 :
2395 14 : if (r == NULL)
2396 : {
2397 1 : replace_call_with_value (gsi, integer_zero_node);
2398 1 : return true;
2399 : }
2400 :
2401 13 : tree len = build_int_cst (size_type_node, r - p);
2402 13 : gimple_seq stmts = NULL;
2403 13 : gimple *new_stmt
2404 13 : = gimple_build_assign (gimple_call_lhs (stmt), POINTER_PLUS_EXPR,
2405 : haystack, len);
2406 13 : gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2407 13 : gsi_replace_with_seq_vops (gsi, stmts);
2408 13 : return true;
2409 : }
2410 :
2411 : /* For strstr (x, "") return x. */
2412 3159 : if (q[0] == '\0')
2413 : {
2414 6 : replace_call_with_value (gsi, haystack);
2415 6 : return true;
2416 : }
2417 :
2418 6306 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
2419 : return false;
2420 :
2421 : /* Transform strstr (x, "c") into strchr (x, 'c'). */
2422 3153 : if (q[1] == '\0')
2423 : {
2424 22 : tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
2425 22 : if (strchr_fn)
2426 : {
2427 22 : tree c = build_int_cst (integer_type_node, q[0]);
2428 22 : gimple *repl = gimple_build_call (strchr_fn, 2, haystack, c);
2429 22 : replace_call_with_call_and_fold (gsi, repl);
2430 22 : return true;
2431 : }
2432 : }
2433 :
2434 : return false;
2435 : }
2436 :
2437 : /* Simplify a call to the strcat builtin. DST and SRC are the arguments
2438 : to the call.
2439 :
2440 : Return NULL_TREE if no simplification was possible, otherwise return the
2441 : simplified form of the call as a tree.
2442 :
2443 : The simplified form may be a constant or other expression which
2444 : computes the same value, but in a more efficient manner (including
2445 : calls to other builtin functions).
2446 :
2447 : The call may contain arguments which need to be evaluated, but
2448 : which are not useful to determine the result of the call. In
2449 : this case we return a chain of COMPOUND_EXPRs. The LHS of each
2450 : COMPOUND_EXPR will be an argument which must be evaluated.
2451 : COMPOUND_EXPRs are chained through their RHS. The RHS of the last
2452 : COMPOUND_EXPR in the chain will contain the tree for the simplified
2453 : form of the builtin function call. */
2454 :
2455 : static bool
2456 7331 : gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
2457 : {
2458 7331 : gimple *stmt = gsi_stmt (*gsi);
2459 7331 : location_t loc = gimple_location (stmt);
2460 :
2461 7331 : const char *p = c_getstr (src);
2462 :
2463 : /* If the string length is zero, return the dst parameter. */
2464 7331 : if (p && *p == '\0')
2465 : {
2466 72 : replace_call_with_value (gsi, dst);
2467 72 : return true;
2468 : }
2469 :
2470 7259 : if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
2471 : return false;
2472 :
2473 13344 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
2474 : return false;
2475 :
2476 : /* See if we can store by pieces into (dst + strlen(dst)). */
2477 6672 : tree newdst;
2478 6672 : tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2479 6672 : tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2480 :
2481 6672 : if (!strlen_fn || !memcpy_fn)
2482 : return false;
2483 :
2484 : /* If the length of the source string isn't computable don't
2485 : split strcat into strlen and memcpy. */
2486 6672 : tree len = get_maxval_strlen (src, SRK_STRLEN);
2487 6672 : if (! len)
2488 : return false;
2489 :
2490 : /* Create strlen (dst). */
2491 740 : gimple_seq stmts = NULL, stmts2;
2492 740 : gimple *repl = gimple_build_call (strlen_fn, 1, dst);
2493 740 : gimple_set_location (repl, loc);
2494 740 : newdst = make_ssa_name (size_type_node);
2495 740 : gimple_call_set_lhs (repl, newdst);
2496 740 : gimple_seq_add_stmt_without_update (&stmts, repl);
2497 :
2498 : /* Create (dst p+ strlen (dst)). */
2499 740 : newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
2500 740 : newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE);
2501 740 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2502 :
2503 740 : len = fold_convert_loc (loc, size_type_node, len);
2504 740 : len = size_binop_loc (loc, PLUS_EXPR, len,
2505 : build_int_cst (size_type_node, 1));
2506 740 : len = force_gimple_operand (len, &stmts2, true, NULL_TREE);
2507 740 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2508 :
2509 740 : repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
2510 740 : gimple_seq_add_stmt_without_update (&stmts, repl);
2511 740 : if (gimple_call_lhs (stmt))
2512 : {
2513 165 : repl = gimple_build_assign (gimple_call_lhs (stmt), dst);
2514 165 : gimple_seq_add_stmt_without_update (&stmts, repl);
2515 165 : gsi_replace_with_seq_vops (gsi, stmts);
2516 : /* gsi now points at the assignment to the lhs, get a
2517 : stmt iterator to the memcpy call.
2518 : ??? We can't use gsi_for_stmt as that doesn't work when the
2519 : CFG isn't built yet. */
2520 165 : gimple_stmt_iterator gsi2 = *gsi;
2521 165 : gsi_prev (&gsi2);
2522 165 : fold_stmt (&gsi2);
2523 : }
2524 : else
2525 : {
2526 575 : gsi_replace_with_seq_vops (gsi, stmts);
2527 575 : fold_stmt (gsi);
2528 : }
2529 : return true;
2530 : }
2531 :
2532 : /* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
2533 : are the arguments to the call. */
2534 :
2535 : static bool
2536 1493 : gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
2537 : {
2538 1493 : gimple *stmt = gsi_stmt (*gsi);
2539 1493 : tree dest = gimple_call_arg (stmt, 0);
2540 1493 : tree src = gimple_call_arg (stmt, 1);
2541 1493 : tree size = gimple_call_arg (stmt, 2);
2542 1493 : tree fn;
2543 1493 : const char *p;
2544 :
2545 1493 : p = c_getstr (src);
2546 : /* If the SRC parameter is "", return DEST. */
2547 1493 : if (p && *p == '\0')
2548 : {
2549 60 : replace_call_with_value (gsi, dest);
2550 60 : return true;
2551 : }
2552 :
2553 1433 : if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
2554 : return false;
2555 :
2556 164 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
2557 : return false;
2558 :
2559 : /* If __builtin_strcat_chk is used, assume strcat is available. */
2560 82 : fn = builtin_decl_explicit (BUILT_IN_STRCAT);
2561 82 : if (!fn)
2562 : return false;
2563 :
2564 82 : gimple *repl = gimple_build_call (fn, 2, dest, src);
2565 82 : replace_call_with_call_and_fold (gsi, repl);
2566 82 : return true;
2567 : }
2568 :
2569 : /* Simplify a call to the strncat builtin. */
2570 :
2571 : static bool
2572 6786 : gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
2573 : {
2574 6786 : gimple *stmt = gsi_stmt (*gsi);
2575 6786 : tree dst = gimple_call_arg (stmt, 0);
2576 6786 : tree src = gimple_call_arg (stmt, 1);
2577 6786 : tree len = gimple_call_arg (stmt, 2);
2578 6786 : tree src_len = c_strlen (src, 1);
2579 :
2580 : /* If the requested length is zero, or the src parameter string
2581 : length is zero, return the dst parameter. */
2582 6786 : if (integer_zerop (len) || (src_len && integer_zerop (src_len)))
2583 : {
2584 119 : replace_call_with_value (gsi, dst);
2585 119 : return true;
2586 : }
2587 :
2588 : /* Return early if the requested len is less than the string length.
2589 : Warnings will be issued elsewhere later. */
2590 6667 : if (!src_len || known_lower (stmt, len, src_len, true))
2591 : return false;
2592 :
2593 : /* Warn on constant LEN. */
2594 568 : if (TREE_CODE (len) == INTEGER_CST)
2595 : {
2596 131 : bool nowarn = warning_suppressed_p (stmt, OPT_Wstringop_overflow_);
2597 131 : tree dstsize;
2598 :
2599 131 : if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize)
2600 175 : && TREE_CODE (dstsize) == INTEGER_CST)
2601 : {
2602 44 : int cmpdst = tree_int_cst_compare (len, dstsize);
2603 :
2604 44 : if (cmpdst >= 0)
2605 : {
2606 19 : tree fndecl = gimple_call_fndecl (stmt);
2607 :
2608 : /* Strncat copies (at most) LEN bytes and always appends
2609 : the terminating NUL so the specified bound should never
2610 : be equal to (or greater than) the size of the destination.
2611 : If it is, the copy could overflow. */
2612 19 : location_t loc = gimple_location (stmt);
2613 37 : nowarn = warning_at (loc, OPT_Wstringop_overflow_,
2614 : cmpdst == 0
2615 : ? G_("%qD specified bound %E equals "
2616 : "destination size")
2617 : : G_("%qD specified bound %E exceeds "
2618 : "destination size %E"),
2619 : fndecl, len, dstsize);
2620 19 : if (nowarn)
2621 0 : suppress_warning (stmt, OPT_Wstringop_overflow_);
2622 : }
2623 : }
2624 :
2625 131 : if (!nowarn && TREE_CODE (src_len) == INTEGER_CST
2626 243 : && tree_int_cst_compare (src_len, len) == 0)
2627 : {
2628 20 : tree fndecl = gimple_call_fndecl (stmt);
2629 20 : location_t loc = gimple_location (stmt);
2630 :
2631 : /* To avoid possible overflow the specified bound should also
2632 : not be equal to the length of the source, even when the size
2633 : of the destination is unknown (it's not an uncommon mistake
2634 : to specify as the bound to strncpy the length of the source). */
2635 20 : if (warning_at (loc, OPT_Wstringop_overflow_,
2636 : "%qD specified bound %E equals source length",
2637 : fndecl, len))
2638 6 : suppress_warning (stmt, OPT_Wstringop_overflow_);
2639 : }
2640 : }
2641 :
2642 568 : if (!known_lower (stmt, src_len, len))
2643 : return false;
2644 :
2645 136 : tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
2646 :
2647 : /* If the replacement _DECL isn't initialized, don't do the
2648 : transformation. */
2649 272 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
2650 : return false;
2651 :
2652 : /* Otherwise, emit a call to strcat. */
2653 136 : gcall *repl = gimple_build_call (fn, 2, dst, src);
2654 136 : replace_call_with_call_and_fold (gsi, repl);
2655 136 : return true;
2656 : }
2657 :
2658 : /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
2659 : LEN, and SIZE. */
2660 :
2661 : static bool
2662 1116 : gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
2663 : {
2664 1116 : gimple *stmt = gsi_stmt (*gsi);
2665 1116 : tree dest = gimple_call_arg (stmt, 0);
2666 1116 : tree src = gimple_call_arg (stmt, 1);
2667 1116 : tree len = gimple_call_arg (stmt, 2);
2668 1116 : tree size = gimple_call_arg (stmt, 3);
2669 1116 : tree fn;
2670 1116 : const char *p;
2671 :
2672 1116 : p = c_getstr (src);
2673 : /* If the SRC parameter is "" or if LEN is 0, return DEST. */
2674 276 : if ((p && *p == '\0')
2675 1341 : || integer_zerop (len))
2676 : {
2677 78 : replace_call_with_value (gsi, dest);
2678 78 : return true;
2679 : }
2680 :
2681 2076 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
2682 : return false;
2683 :
2684 1038 : if (! integer_all_onesp (size))
2685 : {
2686 951 : tree src_len = c_strlen (src, 1);
2687 951 : if (known_lower (stmt, src_len, len))
2688 : {
2689 : /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
2690 39 : fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
2691 39 : if (!fn)
2692 : return false;
2693 :
2694 39 : gimple *repl = gimple_build_call (fn, 3, dest, src, size);
2695 39 : replace_call_with_call_and_fold (gsi, repl);
2696 39 : return true;
2697 : }
2698 : return false;
2699 : }
2700 :
2701 : /* If __builtin_strncat_chk is used, assume strncat is available. */
2702 87 : fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
2703 87 : if (!fn)
2704 : return false;
2705 :
2706 87 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2707 87 : replace_call_with_call_and_fold (gsi, repl);
2708 87 : return true;
2709 : }
2710 :
2711 : /* Build and append gimple statements to STMTS that would load a first
2712 : character of a memory location identified by STR. LOC is location
2713 : of the statement. */
2714 :
2715 : static tree
2716 482 : gimple_load_first_char (location_t loc, tree str, gimple_seq *stmts)
2717 : {
2718 482 : tree var;
2719 :
2720 482 : tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2721 482 : tree cst_uchar_ptr_node
2722 482 : = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
2723 482 : tree off0 = build_int_cst (cst_uchar_ptr_node, 0);
2724 :
2725 482 : tree temp = fold_build2_loc (loc, MEM_REF, cst_uchar_node, str, off0);
2726 482 : gassign *stmt = gimple_build_assign (NULL_TREE, temp);
2727 482 : var = make_ssa_name (cst_uchar_node, stmt);
2728 :
2729 482 : gimple_assign_set_lhs (stmt, var);
2730 482 : gimple_seq_add_stmt_without_update (stmts, stmt);
2731 :
2732 482 : return var;
2733 : }
2734 :
2735 : /* Fold a call to the str{n}{case}cmp builtin pointed by GSI iterator. */
2736 :
2737 : static bool
2738 1250699 : gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
2739 : {
2740 1250699 : gimple *stmt = gsi_stmt (*gsi);
2741 1250699 : tree callee = gimple_call_fndecl (stmt);
2742 1250699 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
2743 :
2744 1250699 : tree type = integer_type_node;
2745 1250699 : tree str1 = gimple_call_arg (stmt, 0);
2746 1250699 : tree str2 = gimple_call_arg (stmt, 1);
2747 1250699 : tree lhs = gimple_call_lhs (stmt);
2748 :
2749 1250699 : tree bound_node = NULL_TREE;
2750 1250699 : unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;
2751 :
2752 : /* Handle strncmp and strncasecmp functions. */
2753 1250699 : if (gimple_call_num_args (stmt) == 3)
2754 : {
2755 22970 : bound_node = gimple_call_arg (stmt, 2);
2756 22970 : if (tree_fits_uhwi_p (bound_node))
2757 17246 : bound = tree_to_uhwi (bound_node);
2758 : }
2759 :
2760 : /* If the BOUND parameter is zero, return zero. */
2761 17246 : if (bound == 0)
2762 : {
2763 4 : replace_call_with_value (gsi, integer_zero_node);
2764 4 : return true;
2765 : }
2766 :
2767 : /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
2768 1250695 : if (operand_equal_p (str1, str2, 0))
2769 : {
2770 41 : replace_call_with_value (gsi, integer_zero_node);
2771 41 : return true;
2772 : }
2773 :
2774 2501308 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
2775 : return false;
2776 :
2777 : /* Initially set to the number of characters, including the terminating
2778 : nul if each array has one. LENx == strnlen (Sx, LENx) implies that
2779 : the array Sx is not terminated by a nul.
2780 : For nul-terminated strings then adjusted to their length so that
2781 : LENx == NULPOSx holds. */
2782 1250654 : unsigned HOST_WIDE_INT len1 = HOST_WIDE_INT_MAX, len2 = len1;
2783 1250654 : const char *p1 = getbyterep (str1, &len1);
2784 1250654 : const char *p2 = getbyterep (str2, &len2);
2785 :
2786 : /* The position of the terminating nul character if one exists, otherwise
2787 : a value greater than LENx. */
2788 1250654 : unsigned HOST_WIDE_INT nulpos1 = HOST_WIDE_INT_MAX, nulpos2 = nulpos1;
2789 :
2790 1250654 : if (p1)
2791 : {
2792 42807 : size_t n = strnlen (p1, len1);
2793 42807 : if (n < len1)
2794 42700 : len1 = nulpos1 = n;
2795 : }
2796 :
2797 1250654 : if (p2)
2798 : {
2799 1219592 : size_t n = strnlen (p2, len2);
2800 1219592 : if (n < len2)
2801 1219533 : len2 = nulpos2 = n;
2802 : }
2803 :
2804 : /* For known strings, return an immediate value. */
2805 1250654 : if (p1 && p2)
2806 : {
2807 39245 : int r = 0;
2808 39245 : bool known_result = false;
2809 :
2810 39245 : switch (fcode)
2811 : {
2812 38169 : case BUILT_IN_STRCMP:
2813 38169 : case BUILT_IN_STRCMP_EQ:
2814 38169 : if (len1 != nulpos1 || len2 != nulpos2)
2815 : break;
2816 :
2817 38144 : r = strcmp (p1, p2);
2818 38144 : known_result = true;
2819 38144 : break;
2820 :
2821 1002 : case BUILT_IN_STRNCMP:
2822 1002 : case BUILT_IN_STRNCMP_EQ:
2823 1002 : {
2824 1002 : if (bound == HOST_WIDE_INT_M1U)
2825 : break;
2826 :
2827 : /* Reduce the bound to be no more than the length
2828 : of the shorter of the two strings, or the sizes
2829 : of the unterminated arrays. */
2830 38 : unsigned HOST_WIDE_INT n = bound;
2831 :
2832 38 : if (len1 == nulpos1 && len1 < n)
2833 4 : n = len1 + 1;
2834 38 : if (len2 == nulpos2 && len2 < n)
2835 11 : n = len2 + 1;
2836 :
2837 38 : if (MIN (nulpos1, nulpos2) + 1 < n)
2838 : break;
2839 :
2840 38 : r = strncmp (p1, p2, n);
2841 38 : known_result = true;
2842 38 : break;
2843 : }
2844 : /* Only handleable situation is where the string are equal (result 0),
2845 : which is already handled by operand_equal_p case. */
2846 : case BUILT_IN_STRCASECMP:
2847 : break;
2848 37 : case BUILT_IN_STRNCASECMP:
2849 37 : {
2850 37 : if (bound == HOST_WIDE_INT_M1U)
2851 : break;
2852 37 : r = strncmp (p1, p2, bound);
2853 37 : if (r == 0)
2854 : known_result = true;
2855 : break;
2856 : }
2857 0 : default:
2858 0 : gcc_unreachable ();
2859 : }
2860 :
2861 38182 : if (known_result)
2862 : {
2863 38182 : replace_call_with_value (gsi, build_cmp_result (type, r));
2864 38182 : return true;
2865 : }
2866 : }
2867 :
2868 2424944 : bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U)
2869 1195370 : || fcode == BUILT_IN_STRCMP
2870 1195370 : || fcode == BUILT_IN_STRCMP_EQ
2871 1218374 : || fcode == BUILT_IN_STRCASECMP;
2872 :
2873 1212472 : location_t loc = gimple_location (stmt);
2874 :
2875 : /* If the second arg is "", return *(const unsigned char*)arg1. */
2876 1212472 : if (p2 && *p2 == '\0' && nonzero_bound)
2877 : {
2878 150 : gimple_seq stmts = NULL;
2879 150 : tree var = gimple_load_first_char (loc, str1, &stmts);
2880 150 : if (lhs)
2881 : {
2882 150 : stmt = gimple_build_assign (lhs, NOP_EXPR, var);
2883 150 : gimple_seq_add_stmt_without_update (&stmts, stmt);
2884 : }
2885 :
2886 150 : gsi_replace_with_seq_vops (gsi, stmts);
2887 150 : return true;
2888 : }
2889 :
2890 : /* If the first arg is "", return -*(const unsigned char*)arg2. */
2891 1212322 : if (p1 && *p1 == '\0' && nonzero_bound)
2892 : {
2893 99 : gimple_seq stmts = NULL;
2894 99 : tree var = gimple_load_first_char (loc, str2, &stmts);
2895 :
2896 99 : if (lhs)
2897 : {
2898 99 : tree c = make_ssa_name (integer_type_node);
2899 99 : stmt = gimple_build_assign (c, NOP_EXPR, var);
2900 99 : gimple_seq_add_stmt_without_update (&stmts, stmt);
2901 :
2902 99 : stmt = gimple_build_assign (lhs, NEGATE_EXPR, c);
2903 99 : gimple_seq_add_stmt_without_update (&stmts, stmt);
2904 : }
2905 :
2906 99 : gsi_replace_with_seq_vops (gsi, stmts);
2907 99 : return true;
2908 : }
2909 :
2910 : /* If BOUND is one, return an expression corresponding to
2911 : (*(const unsigned char*)arg2 - *(const unsigned char*)arg1). */
2912 1212223 : if (fcode == BUILT_IN_STRNCMP && bound == 1)
2913 : {
2914 110 : gimple_seq stmts = NULL;
2915 110 : tree temp1 = gimple_load_first_char (loc, str1, &stmts);
2916 110 : tree temp2 = gimple_load_first_char (loc, str2, &stmts);
2917 :
2918 110 : if (lhs)
2919 : {
2920 107 : tree c1 = make_ssa_name (integer_type_node);
2921 107 : gassign *convert1 = gimple_build_assign (c1, NOP_EXPR, temp1);
2922 107 : gimple_seq_add_stmt_without_update (&stmts, convert1);
2923 :
2924 107 : tree c2 = make_ssa_name (integer_type_node);
2925 107 : gassign *convert2 = gimple_build_assign (c2, NOP_EXPR, temp2);
2926 107 : gimple_seq_add_stmt_without_update (&stmts, convert2);
2927 :
2928 107 : stmt = gimple_build_assign (lhs, MINUS_EXPR, c1, c2);
2929 107 : gimple_seq_add_stmt_without_update (&stmts, stmt);
2930 : }
2931 :
2932 110 : gsi_replace_with_seq_vops (gsi, stmts);
2933 110 : return true;
2934 : }
2935 :
2936 : /* If BOUND is greater than the length of one constant string,
2937 : and the other argument is also a nul-terminated string, replace
2938 : strncmp with strcmp. */
2939 1212113 : if (fcode == BUILT_IN_STRNCMP
2940 17708 : && bound > 0 && bound < HOST_WIDE_INT_M1U
2941 12116 : && ((p2 && len2 < bound && len2 == nulpos2)
2942 11884 : || (p1 && len1 < bound && len1 == nulpos1)))
2943 : {
2944 310 : tree fn = builtin_decl_implicit (BUILT_IN_STRCMP);
2945 310 : if (!fn)
2946 : return false;
2947 310 : gimple *repl = gimple_build_call (fn, 2, str1, str2);
2948 310 : replace_call_with_call_and_fold (gsi, repl);
2949 310 : return true;
2950 : }
2951 :
2952 : return false;
2953 : }
2954 :
2955 : /* Fold a call to the memchr pointed by GSI iterator. */
2956 :
2957 : static bool
2958 38310 : gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
2959 : {
2960 38310 : gimple *stmt = gsi_stmt (*gsi);
2961 38310 : tree lhs = gimple_call_lhs (stmt);
2962 38310 : tree arg1 = gimple_call_arg (stmt, 0);
2963 38310 : tree arg2 = gimple_call_arg (stmt, 1);
2964 38310 : tree len = gimple_call_arg (stmt, 2);
2965 :
2966 : /* If the LEN parameter is zero, return zero. */
2967 38310 : if (integer_zerop (len))
2968 : {
2969 1 : replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
2970 1 : return true;
2971 : }
2972 :
2973 38309 : char c;
2974 38309 : if (TREE_CODE (arg2) != INTEGER_CST
2975 22671 : || !tree_fits_uhwi_p (len)
2976 39023 : || !target_char_cst_p (arg2, &c))
2977 : return false;
2978 :
2979 714 : unsigned HOST_WIDE_INT length = tree_to_uhwi (len);
2980 714 : unsigned HOST_WIDE_INT string_length;
2981 714 : const char *p1 = getbyterep (arg1, &string_length);
2982 :
2983 714 : if (p1)
2984 : {
2985 96 : const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
2986 96 : if (r == NULL)
2987 : {
2988 14 : tree mem_size, offset_node;
2989 14 : byte_representation (arg1, &offset_node, &mem_size, NULL);
2990 14 : unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
2991 14 : ? 0 : tree_to_uhwi (offset_node);
2992 : /* MEM_SIZE is the size of the array the string literal
2993 : is stored in. */
2994 14 : unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
2995 14 : gcc_checking_assert (string_length <= string_size);
2996 14 : if (length <= string_size)
2997 : {
2998 4 : replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
2999 4 : return true;
3000 : }
3001 : }
3002 : else
3003 : {
3004 82 : unsigned HOST_WIDE_INT offset = r - p1;
3005 82 : gimple_seq stmts = NULL;
3006 82 : if (lhs != NULL_TREE)
3007 : {
3008 80 : tree offset_cst = build_int_cst (sizetype, offset);
3009 80 : gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
3010 : arg1, offset_cst);
3011 80 : gimple_seq_add_stmt_without_update (&stmts, stmt);
3012 : }
3013 : else
3014 2 : gimple_seq_add_stmt_without_update (&stmts,
3015 : gimple_build_nop ());
3016 :
3017 82 : gsi_replace_with_seq_vops (gsi, stmts);
3018 82 : return true;
3019 : }
3020 : }
3021 :
3022 : return false;
3023 : }
3024 :
3025 : /* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
3026 : to the call. IGNORE is true if the value returned
3027 : by the builtin will be ignored. UNLOCKED is true is true if this
3028 : actually a call to fputs_unlocked. If LEN in non-NULL, it represents
3029 : the known length of the string. Return NULL_TREE if no simplification
3030 : was possible. */
3031 :
3032 : static bool
3033 20730 : gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
3034 : tree arg0, tree arg1,
3035 : bool unlocked)
3036 : {
3037 20730 : gimple *stmt = gsi_stmt (*gsi);
3038 :
3039 : /* If we're using an unlocked function, assume the other unlocked
3040 : functions exist explicitly. */
3041 20730 : tree const fn_fputc = (unlocked
3042 20730 : ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
3043 20730 : : builtin_decl_implicit (BUILT_IN_FPUTC));
3044 20687 : tree const fn_fwrite = (unlocked
3045 43 : ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
3046 20730 : : builtin_decl_implicit (BUILT_IN_FWRITE));
3047 :
3048 : /* If the return value is used, don't do the transformation. */
3049 20730 : if (gimple_call_lhs (stmt))
3050 : return false;
3051 :
3052 : /* Get the length of the string passed to fputs. If the length
3053 : can't be determined, punt. */
3054 20659 : tree len = get_maxval_strlen (arg0, SRK_STRLEN);
3055 20659 : if (!len || TREE_CODE (len) != INTEGER_CST)
3056 : return false;
3057 :
3058 16223 : switch (compare_tree_int (len, 1))
3059 : {
3060 91 : case -1: /* length is 0, delete the call entirely . */
3061 91 : replace_call_with_value (gsi, integer_zero_node);
3062 91 : return true;
3063 :
3064 1064 : case 0: /* length is 1, call fputc. */
3065 1064 : {
3066 1064 : const char *p = c_getstr (arg0);
3067 1064 : if (p != NULL)
3068 : {
3069 2100 : if (!fn_fputc || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3070 : return false;
3071 :
3072 1050 : gimple *repl
3073 1050 : = gimple_build_call (fn_fputc, 2,
3074 1050 : build_int_cst (integer_type_node, p[0]),
3075 : arg1);
3076 1050 : replace_call_with_call_and_fold (gsi, repl);
3077 1050 : return true;
3078 : }
3079 : }
3080 : /* FALLTHROUGH */
3081 15082 : case 1: /* length is greater than 1, call fwrite. */
3082 15082 : {
3083 : /* If optimizing for size keep fputs. */
3084 15082 : if (optimize_function_for_size_p (cfun))
3085 : return false;
3086 : /* New argument list transforming fputs(string, stream) to
3087 : fwrite(string, 1, len, stream). */
3088 16478 : if (!fn_fwrite || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3089 : return false;
3090 :
3091 8239 : gimple *repl
3092 8239 : = gimple_build_call (fn_fwrite, 4, arg0, size_one_node,
3093 : fold_convert (size_type_node, len), arg1);
3094 8239 : replace_call_with_call_and_fold (gsi, repl);
3095 8239 : return true;
3096 : }
3097 0 : default:
3098 0 : gcc_unreachable ();
3099 : }
3100 : }
3101 :
3102 : /* Fold a call to fwrite (PTR, SIZE, N, STREAM) at *GSI. UNLOCKED says whether
3103 : the callee is fwrite_unlocked rather than fwrite. A call that transfers a
3104 : single byte and whose result is nobody's business writes the same byte as
3105 : fputc (*PTR, STREAM), which reaches the stream without going through the
3106 : generic buffered-write path. Return true if the call was folded. */
3107 :
3108 : static bool
3109 40942 : gimple_fold_builtin_fwrite (gimple_stmt_iterator *gsi, bool unlocked)
3110 : {
3111 40942 : gimple *stmt = gsi_stmt (*gsi);
3112 :
3113 : /* fwrite reports the number of items transferred and fputc the character
3114 : written, so only fold when nothing looks at the result. */
3115 40942 : if (gimple_call_lhs (stmt))
3116 : return false;
3117 :
3118 : /* fwrite transfers SIZE * N bytes, so writing a single byte needs both
3119 : counts to be one: no other pair of non-negative values multiplies to
3120 : one. */
3121 39804 : if (!integer_onep (gimple_call_arg (stmt, 1))
3122 39804 : || !integer_onep (gimple_call_arg (stmt, 2)))
3123 : return false;
3124 :
3125 : /* If we're using an unlocked function, assume the other unlocked
3126 : functions exist explicitly. */
3127 13 : tree const fn_fputc = (unlocked
3128 13 : ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
3129 40955 : : builtin_decl_implicit (BUILT_IN_FPUTC));
3130 26 : if (!fn_fputc || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3131 : return false;
3132 :
3133 13 : location_t loc = gimple_location (stmt);
3134 13 : gimple_seq stmts = NULL;
3135 13 : tree byte = gimple_load_first_char (loc, gimple_call_arg (stmt, 0), &stmts);
3136 13 : tree c = gimple_convert (&stmts, integer_type_node, byte);
3137 13 : tree stream = gimple_call_arg (stmt, 3);
3138 13 : gcall *repl = gimple_build_call (fn_fputc, 2, c, stream);
3139 13 : gimple_seq_add_stmt_without_update (&stmts, repl);
3140 13 : gsi_replace_with_seq_vops (gsi, stmts);
3141 13 : return true;
3142 : }
3143 :
3144 : /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
3145 : DEST, SRC, LEN, and SIZE are the arguments to the call.
3146 : IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
3147 : code of the builtin. If MAXLEN is not NULL, it is maximum length
3148 : passed as third argument. */
3149 :
3150 : static bool
3151 25701 : gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
3152 : tree dest, tree src, tree len, tree size,
3153 : enum built_in_function fcode)
3154 : {
3155 25701 : gimple *stmt = gsi_stmt (*gsi);
3156 25701 : location_t loc = gimple_location (stmt);
3157 25701 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3158 25701 : tree fn;
3159 :
3160 : /* If SRC and DEST are the same (and not volatile), return DEST
3161 : (resp. DEST+LEN for __mempcpy_chk). */
3162 25701 : if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
3163 : {
3164 13 : if (fcode != BUILT_IN_MEMPCPY_CHK)
3165 : {
3166 7 : replace_call_with_value (gsi, dest);
3167 7 : return true;
3168 : }
3169 : else
3170 : {
3171 6 : gimple_seq stmts = NULL;
3172 6 : len = gimple_convert_to_ptrofftype (&stmts, loc, len);
3173 6 : tree temp = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
3174 6 : TREE_TYPE (dest), dest, len);
3175 6 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3176 6 : replace_call_with_value (gsi, temp);
3177 6 : return true;
3178 : }
3179 : }
3180 :
3181 51376 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3182 : return false;
3183 :
3184 25688 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3185 25688 : if (! integer_all_onesp (size)
3186 24689 : && !known_lower (stmt, len, size)
3187 42927 : && !known_lower (stmt, maxlen, size))
3188 : {
3189 : /* MAXLEN and LEN both cannot be proved to be less than SIZE, at
3190 : least try to optimize (void) __mempcpy_chk () into
3191 : (void) __memcpy_chk () */
3192 17162 : if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
3193 : {
3194 43 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3195 43 : if (!fn)
3196 : return false;
3197 :
3198 43 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3199 43 : replace_call_with_call_and_fold (gsi, repl);
3200 43 : return true;
3201 : }
3202 : return false;
3203 : }
3204 :
3205 8526 : fn = NULL_TREE;
3206 : /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
3207 : mem{cpy,pcpy,move,set} is available. */
3208 8526 : switch (fcode)
3209 : {
3210 1781 : case BUILT_IN_MEMCPY_CHK:
3211 1781 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
3212 1781 : break;
3213 1068 : case BUILT_IN_MEMPCPY_CHK:
3214 1068 : fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
3215 1068 : break;
3216 1652 : case BUILT_IN_MEMMOVE_CHK:
3217 1652 : fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
3218 1652 : break;
3219 4025 : case BUILT_IN_MEMSET_CHK:
3220 4025 : fn = builtin_decl_explicit (BUILT_IN_MEMSET);
3221 4025 : break;
3222 : default:
3223 : break;
3224 : }
3225 :
3226 8526 : if (!fn)
3227 : return false;
3228 :
3229 8526 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
3230 8526 : replace_call_with_call_and_fold (gsi, repl);
3231 8526 : return true;
3232 : }
3233 :
3234 : /* Fold a call to the __st[rp]cpy_chk builtin.
3235 : DEST, SRC, and SIZE are the arguments to the call.
3236 : IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
3237 : code of the builtin. If MAXLEN is not NULL, it is maximum length of
3238 : strings passed as second argument. */
3239 :
3240 : static bool
3241 2566 : gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
3242 : tree dest,
3243 : tree src, tree size,
3244 : enum built_in_function fcode)
3245 : {
3246 2566 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3247 2566 : location_t loc = gimple_location (stmt);
3248 2566 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3249 2566 : tree len, fn;
3250 :
3251 : /* If SRC and DEST are the same (and not volatile), return DEST. */
3252 2566 : if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
3253 : {
3254 : /* Issue -Wrestrict unless the pointers are null (those do
3255 : not point to objects and so do not indicate an overlap;
3256 : such calls could be the result of sanitization and jump
3257 : threading). */
3258 0 : if (!integer_zerop (dest)
3259 0 : && !warning_suppressed_p (stmt, OPT_Wrestrict))
3260 : {
3261 0 : tree func = gimple_call_fndecl (stmt);
3262 :
3263 0 : warning_at (loc, OPT_Wrestrict,
3264 : "%qD source argument is the same as destination",
3265 : func);
3266 : }
3267 :
3268 0 : replace_call_with_value (gsi, dest);
3269 0 : return true;
3270 : }
3271 :
3272 5132 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3273 : return false;
3274 :
3275 2566 : tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
3276 2566 : if (! integer_all_onesp (size))
3277 : {
3278 2497 : len = c_strlen (src, 1);
3279 2497 : if (!known_lower (stmt, len, size, true)
3280 2497 : && !known_lower (stmt, maxlen, size, true))
3281 : {
3282 2185 : if (fcode == BUILT_IN_STPCPY_CHK)
3283 : {
3284 1077 : if (! ignore)
3285 : return false;
3286 :
3287 : /* If return value of __stpcpy_chk is ignored,
3288 : optimize into __strcpy_chk. */
3289 35 : fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
3290 35 : if (!fn)
3291 : return false;
3292 :
3293 35 : gimple *repl = gimple_build_call (fn, 3, dest, src, size);
3294 35 : replace_call_with_call_and_fold (gsi, repl);
3295 35 : return true;
3296 : }
3297 :
3298 1108 : if (! len || TREE_SIDE_EFFECTS (len))
3299 : return false;
3300 :
3301 : /* If c_strlen returned something, but not provably less than size,
3302 : transform __strcpy_chk into __memcpy_chk. */
3303 106 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3304 106 : if (!fn)
3305 : return false;
3306 :
3307 106 : gimple_seq stmts = NULL;
3308 106 : len = force_gimple_operand (len, &stmts, true, NULL_TREE);
3309 106 : len = gimple_convert (&stmts, loc, size_type_node, len);
3310 106 : len = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node, len,
3311 : build_int_cst (size_type_node, 1));
3312 106 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3313 106 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3314 106 : replace_call_with_call_and_fold (gsi, repl);
3315 106 : return true;
3316 : }
3317 : }
3318 :
3319 : /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
3320 618 : fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK && !ignore
3321 : ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
3322 381 : if (!fn)
3323 : return false;
3324 :
3325 381 : gcall *repl = gimple_build_call (fn, 2, dest, src);
3326 381 : replace_call_with_call_and_fold (gsi, repl);
3327 381 : return true;
3328 : }
3329 :
3330 : /* Fold a call to the __st{r,p}ncpy_chk builtin. DEST, SRC, LEN, and SIZE
3331 : are the arguments to the call. If MAXLEN is not NULL, it is maximum
3332 : length passed as third argument. IGNORE is true if return value can be
3333 : ignored. FCODE is the BUILT_IN_* code of the builtin. */
3334 :
3335 : static bool
3336 2721 : gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
3337 : tree dest, tree src,
3338 : tree len, tree size,
3339 : enum built_in_function fcode)
3340 : {
3341 2721 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3342 2721 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3343 2721 : tree fn;
3344 :
3345 2721 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3346 2721 : if (! integer_all_onesp (size)
3347 2721 : && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3348 : {
3349 2264 : if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
3350 : {
3351 : /* If return value of __stpncpy_chk is ignored,
3352 : optimize into __strncpy_chk. */
3353 39 : fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
3354 39 : if (fn)
3355 : {
3356 39 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3357 39 : replace_call_with_call_and_fold (gsi, repl);
3358 39 : return true;
3359 : }
3360 : }
3361 : return false;
3362 : }
3363 :
3364 : /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */
3365 717 : fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK && !ignore
3366 : ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
3367 914 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3368 : return false;
3369 :
3370 457 : gcall *repl = gimple_build_call (fn, 3, dest, src, len);
3371 457 : replace_call_with_call_and_fold (gsi, repl);
3372 457 : return true;
3373 : }
3374 :
3375 : /* Fold function call to builtin stpcpy with arguments DEST and SRC.
3376 : Return NULL_TREE if no simplification can be made. */
3377 :
3378 : static bool
3379 3674 : gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
3380 : {
3381 3674 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3382 3674 : location_t loc = gimple_location (stmt);
3383 3674 : tree dest = gimple_call_arg (stmt, 0);
3384 3674 : tree src = gimple_call_arg (stmt, 1);
3385 3674 : tree fn, lenp1;
3386 :
3387 7348 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3388 : return false;
3389 :
3390 : /* If the result is unused, replace stpcpy with strcpy. */
3391 3674 : if (gimple_call_lhs (stmt) == NULL_TREE)
3392 : {
3393 29 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3394 29 : if (!fn)
3395 : return false;
3396 29 : gimple_call_set_fndecl (stmt, fn);
3397 29 : fold_stmt (gsi);
3398 29 : return true;
3399 : }
3400 :
3401 : /* Set to non-null if ARG refers to an unterminated array. */
3402 3645 : c_strlen_data data = { };
3403 : /* The size of the unterminated array if SRC refers to one. */
3404 3645 : tree size;
3405 : /* True if the size is exact/constant, false if it's the lower bound
3406 : of a range. */
3407 3645 : bool exact;
3408 3645 : tree len = c_strlen (src, 1, &data, 1);
3409 3645 : if (!len
3410 703 : || TREE_CODE (len) != INTEGER_CST)
3411 : {
3412 3174 : data.decl = unterminated_array (src, &size, &exact);
3413 3174 : if (!data.decl)
3414 : return false;
3415 : }
3416 :
3417 1076 : if (data.decl)
3418 : {
3419 : /* Avoid folding calls with unterminated arrays. */
3420 605 : if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
3421 75 : warn_string_no_nul (loc, stmt, "stpcpy", src, data.decl, size,
3422 : exact);
3423 605 : suppress_warning (stmt, OPT_Wstringop_overread);
3424 605 : return false;
3425 : }
3426 :
3427 471 : if (optimize_function_for_size_p (cfun)
3428 : /* If length is zero it's small enough. */
3429 471 : && !integer_zerop (len))
3430 : return false;
3431 :
3432 : /* If the source has a known length replace stpcpy with memcpy. */
3433 287 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3434 287 : if (!fn)
3435 : return false;
3436 :
3437 287 : gimple_seq stmts = NULL;
3438 287 : tree tem = gimple_convert (&stmts, loc, size_type_node, len);
3439 287 : lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
3440 : tem, build_int_cst (size_type_node, 1));
3441 287 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3442 287 : gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
3443 287 : gimple_move_vops (repl, stmt);
3444 287 : gsi_insert_before (gsi, repl, GSI_SAME_STMT);
3445 : /* Replace the result with dest + len. */
3446 287 : stmts = NULL;
3447 287 : tem = gimple_convert (&stmts, loc, sizetype, len);
3448 287 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3449 287 : gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
3450 : POINTER_PLUS_EXPR, dest, tem);
3451 287 : gsi_replace (gsi, ret, false);
3452 : /* Finally fold the memcpy call. */
3453 287 : gimple_stmt_iterator gsi2 = *gsi;
3454 287 : gsi_prev (&gsi2);
3455 287 : fold_stmt (&gsi2);
3456 287 : return true;
3457 : }
3458 :
3459 : /* Simplify mempcpy call stmt at GSI, returning true if simplified.
3460 : Currently only handling mempcpy -> memcpy when the return value
3461 : is ignored. */
3462 :
3463 : static bool
3464 9536 : gimple_fold_builtin_mempcpy (gimple_stmt_iterator *gsi)
3465 : {
3466 9536 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3467 :
3468 9536 : if (gimple_call_lhs (stmt) != NULL_TREE)
3469 : return false;
3470 :
3471 385 : tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
3472 385 : if (!fn)
3473 : return false;
3474 :
3475 385 : tree dest = gimple_call_arg (stmt, 0);
3476 385 : tree src = gimple_call_arg (stmt, 1);
3477 385 : tree n = gimple_call_arg (stmt, 2);
3478 :
3479 385 : gcall *repl = gimple_build_call (fn, 3, dest, src, n);
3480 385 : replace_call_with_call_and_fold (gsi, repl);
3481 :
3482 385 : return true;
3483 : }
3484 :
3485 : /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS. Return
3486 : NULL_TREE if a normal call should be emitted rather than expanding
3487 : the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
3488 : BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
3489 : passed as second argument. */
3490 :
3491 : static bool
3492 2359 : gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
3493 : enum built_in_function fcode)
3494 : {
3495 2359 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3496 2359 : tree dest, size, len, fn, fmt, flag;
3497 2359 : const char *fmt_str;
3498 :
3499 : /* Verify the required arguments in the original call. */
3500 2359 : if (gimple_call_num_args (stmt) < 5)
3501 : return false;
3502 :
3503 2359 : dest = gimple_call_arg (stmt, 0);
3504 2359 : len = gimple_call_arg (stmt, 1);
3505 2359 : flag = gimple_call_arg (stmt, 2);
3506 2359 : size = gimple_call_arg (stmt, 3);
3507 2359 : fmt = gimple_call_arg (stmt, 4);
3508 :
3509 2359 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3510 2359 : if (! integer_all_onesp (size)
3511 2359 : && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3512 : return false;
3513 :
3514 308 : if (!init_target_chars ())
3515 : return false;
3516 :
3517 : /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
3518 : or if format doesn't contain % chars or is "%s". */
3519 308 : if (! integer_zerop (flag))
3520 : {
3521 52 : fmt_str = c_getstr (fmt);
3522 52 : if (fmt_str == NULL)
3523 : return false;
3524 52 : if (strchr (fmt_str, target_percent) != NULL
3525 51 : && strcmp (fmt_str, target_percent_s))
3526 : return false;
3527 : }
3528 :
3529 : /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
3530 : available. */
3531 415 : fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
3532 : ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
3533 518 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3534 : return false;
3535 :
3536 : /* Replace the called function and the first 5 argument by 3 retaining
3537 : trailing varargs. */
3538 259 : gimple_call_set_fndecl (stmt, fn);
3539 259 : gimple_call_set_fntype (stmt, TREE_TYPE (fn));
3540 259 : gimple_call_set_arg (stmt, 0, dest);
3541 259 : gimple_call_set_arg (stmt, 1, len);
3542 259 : gimple_call_set_arg (stmt, 2, fmt);
3543 546 : for (unsigned i = 3; i < gimple_call_num_args (stmt) - 2; ++i)
3544 287 : gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3545 259 : gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3546 259 : fold_stmt (gsi);
3547 259 : return true;
3548 : }
3549 :
3550 : /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
3551 : Return NULL_TREE if a normal call should be emitted rather than
3552 : expanding the function inline. FCODE is either BUILT_IN_SPRINTF_CHK
3553 : or BUILT_IN_VSPRINTF_CHK. */
3554 :
3555 : static bool
3556 4471 : gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
3557 : enum built_in_function fcode)
3558 : {
3559 4471 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3560 4471 : tree dest, size, len, fn, fmt, flag;
3561 4471 : const char *fmt_str;
3562 4471 : unsigned nargs = gimple_call_num_args (stmt);
3563 :
3564 : /* Verify the required arguments in the original call. */
3565 4471 : if (nargs < 4)
3566 : return false;
3567 4471 : dest = gimple_call_arg (stmt, 0);
3568 4471 : flag = gimple_call_arg (stmt, 1);
3569 4471 : size = gimple_call_arg (stmt, 2);
3570 4471 : fmt = gimple_call_arg (stmt, 3);
3571 :
3572 4471 : len = NULL_TREE;
3573 :
3574 4471 : if (!init_target_chars ())
3575 : return false;
3576 :
3577 : /* Check whether the format is a literal string constant. */
3578 4471 : fmt_str = c_getstr (fmt);
3579 4471 : if (fmt_str != NULL)
3580 : {
3581 : /* If the format doesn't contain % args or %%, we know the size. */
3582 4078 : if (strchr (fmt_str, target_percent) == 0)
3583 : {
3584 251 : if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
3585 251 : len = build_int_cstu (size_type_node, strlen (fmt_str));
3586 : }
3587 : /* If the format is "%s" and first ... argument is a string literal,
3588 : we know the size too. */
3589 3827 : else if (fcode == BUILT_IN_SPRINTF_CHK
3590 2971 : && strcmp (fmt_str, target_percent_s) == 0)
3591 : {
3592 395 : tree arg;
3593 :
3594 395 : if (nargs == 5)
3595 : {
3596 395 : arg = gimple_call_arg (stmt, 4);
3597 395 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
3598 363 : len = c_strlen (arg, 1);
3599 : }
3600 : }
3601 : }
3602 :
3603 4471 : if (! integer_all_onesp (size) && !known_lower (stmt, len, size, true))
3604 : return false;
3605 :
3606 : /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
3607 : or if format doesn't contain % chars or is "%s". */
3608 202 : if (! integer_zerop (flag))
3609 : {
3610 1 : if (fmt_str == NULL)
3611 : return false;
3612 1 : if (strchr (fmt_str, target_percent) != NULL
3613 0 : && strcmp (fmt_str, target_percent_s))
3614 : return false;
3615 : }
3616 :
3617 : /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
3618 347 : fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
3619 : ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
3620 404 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3621 : return false;
3622 :
3623 : /* Replace the called function and the first 4 argument by 2 retaining
3624 : trailing varargs. */
3625 202 : gimple_call_set_fndecl (stmt, fn);
3626 202 : gimple_call_set_fntype (stmt, TREE_TYPE (fn));
3627 202 : gimple_call_set_arg (stmt, 0, dest);
3628 202 : gimple_call_set_arg (stmt, 1, fmt);
3629 400 : for (unsigned i = 2; i < gimple_call_num_args (stmt) - 2; ++i)
3630 198 : gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3631 202 : gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3632 202 : fold_stmt (gsi);
3633 202 : return true;
3634 : }
3635 :
3636 : /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
3637 : ORIG may be null if this is a 2-argument call. We don't attempt to
3638 : simplify calls with more than 3 arguments.
3639 :
3640 : Return true if simplification was possible, otherwise false. */
3641 :
3642 : bool
3643 2284 : gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
3644 : {
3645 2284 : gimple *stmt = gsi_stmt (*gsi);
3646 :
3647 : /* Verify the required arguments in the original call. We deal with two
3648 : types of sprintf() calls: 'sprintf (str, fmt)' and
3649 : 'sprintf (dest, "%s", orig)'. */
3650 2284 : if (gimple_call_num_args (stmt) > 3)
3651 : return false;
3652 :
3653 1883 : tree orig = NULL_TREE;
3654 1883 : if (gimple_call_num_args (stmt) == 3)
3655 1785 : orig = gimple_call_arg (stmt, 2);
3656 :
3657 : /* Check whether the format is a literal string constant. */
3658 1883 : tree fmt = gimple_call_arg (stmt, 1);
3659 1883 : const char *fmt_str = c_getstr (fmt);
3660 1883 : if (fmt_str == NULL)
3661 : return false;
3662 :
3663 1883 : tree dest = gimple_call_arg (stmt, 0);
3664 :
3665 1883 : if (!init_target_chars ())
3666 : return false;
3667 :
3668 1883 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3669 3766 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3670 : return false;
3671 :
3672 : /* If the format doesn't contain % args or %%, use strcpy. */
3673 1883 : if (strchr (fmt_str, target_percent) == NULL)
3674 : {
3675 : /* Don't optimize sprintf (buf, "abc", ptr++). */
3676 110 : if (orig)
3677 : return false;
3678 :
3679 : /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
3680 : 'format' is known to contain no % formats. */
3681 97 : gimple_seq stmts = NULL;
3682 97 : gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3683 :
3684 : /* Propagate the NO_WARNING bit to avoid issuing the same
3685 : warning more than once. */
3686 97 : copy_warning (repl, stmt);
3687 :
3688 97 : gimple_seq_add_stmt_without_update (&stmts, repl);
3689 97 : if (tree lhs = gimple_call_lhs (stmt))
3690 : {
3691 0 : repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs),
3692 0 : strlen (fmt_str)));
3693 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3694 0 : gsi_replace_with_seq_vops (gsi, stmts);
3695 : /* gsi now points at the assignment to the lhs, get a
3696 : stmt iterator to the memcpy call.
3697 : ??? We can't use gsi_for_stmt as that doesn't work when the
3698 : CFG isn't built yet. */
3699 0 : gimple_stmt_iterator gsi2 = *gsi;
3700 0 : gsi_prev (&gsi2);
3701 0 : fold_stmt (&gsi2);
3702 : }
3703 : else
3704 : {
3705 97 : gsi_replace_with_seq_vops (gsi, stmts);
3706 97 : fold_stmt (gsi);
3707 : }
3708 : return true;
3709 : }
3710 :
3711 : /* If the format is "%s", use strcpy if the result isn't used. */
3712 1773 : else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3713 : {
3714 : /* Don't crash on sprintf (str1, "%s"). */
3715 748 : if (!orig)
3716 : return false;
3717 :
3718 : /* Don't fold calls with source arguments of invalid (nonpointer)
3719 : types. */
3720 747 : if (!POINTER_TYPE_P (TREE_TYPE (orig)))
3721 : return false;
3722 :
3723 741 : tree orig_len = NULL_TREE;
3724 741 : if (gimple_call_lhs (stmt))
3725 : {
3726 17 : orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3727 17 : if (!orig_len)
3728 : return false;
3729 : }
3730 :
3731 : /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
3732 724 : gimple_seq stmts = NULL;
3733 724 : gimple *repl = gimple_build_call (fn, 2, dest, orig);
3734 :
3735 : /* Propagate the NO_WARNING bit to avoid issuing the same
3736 : warning more than once. */
3737 724 : copy_warning (repl, stmt);
3738 :
3739 724 : gimple_seq_add_stmt_without_update (&stmts, repl);
3740 724 : if (tree lhs = gimple_call_lhs (stmt))
3741 : {
3742 0 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
3743 0 : TREE_TYPE (orig_len)))
3744 0 : orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
3745 0 : repl = gimple_build_assign (lhs, orig_len);
3746 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3747 0 : gsi_replace_with_seq_vops (gsi, stmts);
3748 : /* gsi now points at the assignment to the lhs, get a
3749 : stmt iterator to the memcpy call.
3750 : ??? We can't use gsi_for_stmt as that doesn't work when the
3751 : CFG isn't built yet. */
3752 0 : gimple_stmt_iterator gsi2 = *gsi;
3753 0 : gsi_prev (&gsi2);
3754 0 : fold_stmt (&gsi2);
3755 : }
3756 : else
3757 : {
3758 724 : gsi_replace_with_seq_vops (gsi, stmts);
3759 724 : fold_stmt (gsi);
3760 : }
3761 : return true;
3762 : }
3763 : return false;
3764 : }
3765 :
3766 : /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
3767 : FMT, and ORIG. ORIG may be null if this is a 3-argument call. We don't
3768 : attempt to simplify calls with more than 4 arguments.
3769 :
3770 : Return true if simplification was possible, otherwise false. */
3771 :
3772 : bool
3773 1817 : gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
3774 : {
3775 1817 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3776 1817 : tree dest = gimple_call_arg (stmt, 0);
3777 1817 : tree destsize = gimple_call_arg (stmt, 1);
3778 1817 : tree fmt = gimple_call_arg (stmt, 2);
3779 1817 : tree orig = NULL_TREE;
3780 1817 : const char *fmt_str = NULL;
3781 :
3782 1817 : if (gimple_call_num_args (stmt) > 4
3783 2716 : || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3784 : return false;
3785 :
3786 896 : if (gimple_call_num_args (stmt) == 4)
3787 697 : orig = gimple_call_arg (stmt, 3);
3788 :
3789 : /* Check whether the format is a literal string constant. */
3790 896 : fmt_str = c_getstr (fmt);
3791 896 : if (fmt_str == NULL)
3792 : return false;
3793 :
3794 896 : if (!init_target_chars ())
3795 : return false;
3796 :
3797 : /* If the format doesn't contain % args or %%, use strcpy. */
3798 896 : if (strchr (fmt_str, target_percent) == NULL)
3799 : {
3800 396 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3801 198 : if (!fn)
3802 : return false;
3803 :
3804 : /* Don't optimize snprintf (buf, 4, "abc", ptr++). */
3805 198 : if (orig)
3806 : return false;
3807 :
3808 198 : tree len = build_int_cstu (TREE_TYPE (destsize), strlen (fmt_str));
3809 :
3810 : /* We could expand this as
3811 : memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
3812 : or to
3813 : memcpy (str, fmt_with_nul_at_cstm1, cst);
3814 : but in the former case that might increase code size
3815 : and in the latter case grow .rodata section too much.
3816 : So punt for now. */
3817 198 : if (!known_lower (stmt, len, destsize, true))
3818 : return false;
3819 :
3820 168 : gimple_seq stmts = NULL;
3821 168 : gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3822 168 : gimple_seq_add_stmt_without_update (&stmts, repl);
3823 168 : if (tree lhs = gimple_call_lhs (stmt))
3824 : {
3825 0 : repl = gimple_build_assign (lhs,
3826 0 : fold_convert (TREE_TYPE (lhs), len));
3827 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3828 0 : gsi_replace_with_seq_vops (gsi, stmts);
3829 : /* gsi now points at the assignment to the lhs, get a
3830 : stmt iterator to the memcpy call.
3831 : ??? We can't use gsi_for_stmt as that doesn't work when the
3832 : CFG isn't built yet. */
3833 0 : gimple_stmt_iterator gsi2 = *gsi;
3834 0 : gsi_prev (&gsi2);
3835 0 : fold_stmt (&gsi2);
3836 : }
3837 : else
3838 : {
3839 168 : gsi_replace_with_seq_vops (gsi, stmts);
3840 168 : fold_stmt (gsi);
3841 : }
3842 : return true;
3843 : }
3844 :
3845 : /* If the format is "%s", use strcpy if the result isn't used. */
3846 698 : else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3847 : {
3848 516 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3849 258 : if (!fn)
3850 : return false;
3851 :
3852 : /* Don't crash on snprintf (str1, cst, "%s"). */
3853 258 : if (!orig)
3854 : return false;
3855 :
3856 258 : tree orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3857 :
3858 : /* We could expand this as
3859 : memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
3860 : or to
3861 : memcpy (str1, str2_with_nul_at_cstm1, cst);
3862 : but in the former case that might increase code size
3863 : and in the latter case grow .rodata section too much.
3864 : So punt for now. */
3865 258 : if (!known_lower (stmt, orig_len, destsize, true))
3866 : return false;
3867 :
3868 : /* Convert snprintf (str1, cst, "%s", str2) into
3869 : strcpy (str1, str2) if strlen (str2) < cst. */
3870 64 : gimple_seq stmts = NULL;
3871 64 : gimple *repl = gimple_build_call (fn, 2, dest, orig);
3872 64 : gimple_seq_add_stmt_without_update (&stmts, repl);
3873 64 : if (tree lhs = gimple_call_lhs (stmt))
3874 : {
3875 0 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
3876 0 : TREE_TYPE (orig_len)))
3877 0 : orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
3878 0 : repl = gimple_build_assign (lhs, orig_len);
3879 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3880 0 : gsi_replace_with_seq_vops (gsi, stmts);
3881 : /* gsi now points at the assignment to the lhs, get a
3882 : stmt iterator to the memcpy call.
3883 : ??? We can't use gsi_for_stmt as that doesn't work when the
3884 : CFG isn't built yet. */
3885 0 : gimple_stmt_iterator gsi2 = *gsi;
3886 0 : gsi_prev (&gsi2);
3887 0 : fold_stmt (&gsi2);
3888 : }
3889 : else
3890 : {
3891 64 : gsi_replace_with_seq_vops (gsi, stmts);
3892 64 : fold_stmt (gsi);
3893 : }
3894 : return true;
3895 : }
3896 : return false;
3897 : }
3898 :
3899 : /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
3900 : FP, FMT, and ARG are the arguments to the call. We don't fold calls with
3901 : more than 3 arguments, and ARG may be null in the 2-argument case.
3902 :
3903 : Return NULL_TREE if no simplification was possible, otherwise return the
3904 : simplified form of the call as a tree. FCODE is the BUILT_IN_*
3905 : code of the function to be simplified. */
3906 :
3907 : static bool
3908 54587 : gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
3909 : tree fp, tree fmt, tree arg,
3910 : enum built_in_function fcode)
3911 : {
3912 54587 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3913 54587 : tree fn_fputc, fn_fputs;
3914 54587 : const char *fmt_str = NULL;
3915 :
3916 : /* If the return value is used, don't do the transformation. */
3917 54587 : if (gimple_call_lhs (stmt) != NULL_TREE)
3918 : return false;
3919 :
3920 : /* Check whether the format is a literal string constant. */
3921 50410 : fmt_str = c_getstr (fmt);
3922 50410 : if (fmt_str == NULL)
3923 : return false;
3924 :
3925 50080 : if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
3926 : {
3927 : /* If we're using an unlocked function, assume the other
3928 : unlocked functions exist explicitly. */
3929 80 : fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
3930 80 : fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
3931 : }
3932 : else
3933 : {
3934 50000 : fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
3935 50000 : fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
3936 : }
3937 :
3938 50080 : if (!init_target_chars ())
3939 : return false;
3940 :
3941 100160 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3942 : return false;
3943 :
3944 : /* If the format doesn't contain % args or %%, use strcpy. */
3945 50080 : if (strchr (fmt_str, target_percent) == NULL)
3946 : {
3947 9624 : if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
3948 9554 : && arg)
3949 : return false;
3950 :
3951 : /* If the format specifier was "", fprintf does nothing. */
3952 9624 : if (fmt_str[0] == '\0')
3953 : {
3954 58 : replace_call_with_value (gsi, NULL_TREE);
3955 58 : return true;
3956 : }
3957 :
3958 : /* When "string" doesn't contain %, replace all cases of
3959 : fprintf (fp, string) with fputs (string, fp). The fputs
3960 : builtin will take care of special cases like length == 1. */
3961 9566 : if (fn_fputs)
3962 : {
3963 9566 : gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
3964 9566 : replace_call_with_call_and_fold (gsi, repl);
3965 9566 : return true;
3966 : }
3967 : }
3968 :
3969 : /* The other optimizations can be done only on the non-va_list variants. */
3970 40456 : else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
3971 : return false;
3972 :
3973 : /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
3974 39407 : else if (strcmp (fmt_str, target_percent_s) == 0)
3975 : {
3976 643 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
3977 : return false;
3978 643 : if (fn_fputs)
3979 : {
3980 643 : gcall *repl = gimple_build_call (fn_fputs, 2, arg, fp);
3981 643 : replace_call_with_call_and_fold (gsi, repl);
3982 643 : return true;
3983 : }
3984 : }
3985 :
3986 : /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
3987 38764 : else if (strcmp (fmt_str, target_percent_c) == 0)
3988 : {
3989 49 : if (!arg
3990 49 : || ! useless_type_conversion_p (integer_type_node, TREE_TYPE (arg)))
3991 : return false;
3992 49 : if (fn_fputc)
3993 : {
3994 49 : gcall *repl = gimple_build_call (fn_fputc, 2, arg, fp);
3995 49 : replace_call_with_call_and_fold (gsi, repl);
3996 49 : return true;
3997 : }
3998 : }
3999 :
4000 : return false;
4001 : }
4002 :
4003 : /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
4004 : FMT and ARG are the arguments to the call; we don't fold cases with
4005 : more than 2 arguments, and ARG may be null if this is a 1-argument case.
4006 :
4007 : Return NULL_TREE if no simplification was possible, otherwise return the
4008 : simplified form of the call as a tree. FCODE is the BUILT_IN_*
4009 : code of the function to be simplified. */
4010 :
4011 : static bool
4012 124077 : gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
4013 : tree arg, enum built_in_function fcode)
4014 : {
4015 124077 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
4016 124077 : tree fn_putchar, fn_puts, newarg;
4017 124077 : const char *fmt_str = NULL;
4018 :
4019 : /* If the return value is used, don't do the transformation. */
4020 124077 : if (gimple_call_lhs (stmt) != NULL_TREE)
4021 : return false;
4022 :
4023 241638 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
4024 : return false;
4025 :
4026 : /* Check whether the format is a literal string constant. */
4027 120819 : fmt_str = c_getstr (fmt);
4028 120819 : if (fmt_str == NULL)
4029 : return false;
4030 :
4031 117782 : if (fcode == BUILT_IN_PRINTF_UNLOCKED)
4032 : {
4033 : /* If we're using an unlocked function, assume the other
4034 : unlocked functions exist explicitly. */
4035 80 : fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
4036 80 : fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
4037 : }
4038 : else
4039 : {
4040 117702 : fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
4041 117702 : fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
4042 : }
4043 :
4044 117782 : if (!init_target_chars ())
4045 : return false;
4046 :
4047 117782 : if (strcmp (fmt_str, target_percent_s) == 0
4048 111396 : || strchr (fmt_str, target_percent) == NULL)
4049 : {
4050 14227 : const char *str;
4051 :
4052 14227 : if (strcmp (fmt_str, target_percent_s) == 0)
4053 : {
4054 6386 : if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
4055 : return false;
4056 :
4057 6098 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
4058 : return false;
4059 :
4060 6093 : str = c_getstr (arg);
4061 6093 : if (str == NULL)
4062 : return false;
4063 : }
4064 : else
4065 : {
4066 : /* The format specifier doesn't contain any '%' characters. */
4067 7841 : if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
4068 7709 : && arg)
4069 : return false;
4070 : str = fmt_str;
4071 : }
4072 :
4073 : /* If the string was "", printf does nothing. */
4074 5792 : if (str[0] == '\0')
4075 : {
4076 109 : replace_call_with_value (gsi, NULL_TREE);
4077 109 : return true;
4078 : }
4079 :
4080 : /* If the string has length of 1, call putchar. */
4081 5683 : if (str[1] == '\0')
4082 : {
4083 : /* Given printf("c"), (where c is any one character,)
4084 : convert "c"[0] to an int and pass that to the replacement
4085 : function. */
4086 559 : newarg = build_int_cst (integer_type_node, str[0]);
4087 559 : if (fn_putchar)
4088 : {
4089 559 : gcall *repl = gimple_build_call (fn_putchar, 1, newarg);
4090 559 : replace_call_with_call_and_fold (gsi, repl);
4091 559 : return true;
4092 : }
4093 : }
4094 : else
4095 : {
4096 : /* If the string was "string\n", call puts("string"). */
4097 5124 : size_t len = strlen (str);
4098 5124 : if ((unsigned char)str[len - 1] == target_newline
4099 4024 : && (size_t) (int) len == len
4100 4024 : && (int) len > 0)
4101 : {
4102 4024 : char *newstr;
4103 :
4104 : /* Create a NUL-terminated string that's one char shorter
4105 : than the original, stripping off the trailing '\n'. */
4106 4024 : newstr = xstrdup (str);
4107 4024 : newstr[len - 1] = '\0';
4108 4024 : newarg = build_string_literal (len, newstr);
4109 4024 : free (newstr);
4110 4024 : if (fn_puts)
4111 : {
4112 4024 : gcall *repl = gimple_build_call (fn_puts, 1, newarg);
4113 4024 : replace_call_with_call_and_fold (gsi, repl);
4114 4024 : return true;
4115 : }
4116 : }
4117 : else
4118 : /* We'd like to arrange to call fputs(string,stdout) here,
4119 : but we need stdout and don't have a way to get it yet. */
4120 : return false;
4121 : }
4122 : }
4123 :
4124 : /* The other optimizations can be done only on the non-va_list variants. */
4125 103555 : else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
4126 : return false;
4127 :
4128 : /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4129 103305 : else if (strcmp (fmt_str, target_percent_s_newline) == 0)
4130 : {
4131 180 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
4132 : return false;
4133 180 : if (fn_puts)
4134 : {
4135 180 : gcall *repl = gimple_build_call (fn_puts, 1, arg);
4136 180 : replace_call_with_call_and_fold (gsi, repl);
4137 180 : return true;
4138 : }
4139 : }
4140 :
4141 : /* If the format specifier was "%c", call __builtin_putchar(arg). */
4142 103125 : else if (strcmp (fmt_str, target_percent_c) == 0)
4143 : {
4144 94 : if (!arg || ! useless_type_conversion_p (integer_type_node,
4145 47 : TREE_TYPE (arg)))
4146 : return false;
4147 47 : if (fn_putchar)
4148 : {
4149 47 : gcall *repl = gimple_build_call (fn_putchar, 1, arg);
4150 47 : replace_call_with_call_and_fold (gsi, repl);
4151 47 : return true;
4152 : }
4153 : }
4154 :
4155 : return false;
4156 : }
4157 :
4158 :
4159 :
4160 : /* Fold a call to __builtin_strlen with known length LEN. */
4161 :
4162 : static bool
4163 149308 : gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
4164 : {
4165 149308 : gimple *stmt = gsi_stmt (*gsi);
4166 149308 : tree arg = gimple_call_arg (stmt, 0);
4167 :
4168 149308 : wide_int minlen;
4169 149308 : wide_int maxlen;
4170 :
4171 149308 : c_strlen_data lendata = { };
4172 149308 : if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
4173 34912 : && !lendata.decl
4174 31949 : && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
4175 181152 : && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
4176 : {
4177 : /* The range of lengths refers to either a single constant
4178 : string or to the longest and shortest constant string
4179 : referenced by the argument of the strlen() call, or to
4180 : the strings that can possibly be stored in the arrays
4181 : the argument refers to. */
4182 31844 : minlen = wi::to_wide (lendata.minlen);
4183 31844 : maxlen = wi::to_wide (lendata.maxlen);
4184 : }
4185 : else
4186 : {
4187 117464 : unsigned prec = TYPE_PRECISION (sizetype);
4188 :
4189 117464 : minlen = wi::shwi (0, prec);
4190 117464 : maxlen = wi::to_wide (max_object_size (), prec) - 2;
4191 : }
4192 :
4193 : /* For -fsanitize=address, don't optimize the upper bound of the
4194 : length to be able to diagnose UB on non-zero terminated arrays. */
4195 149308 : if (sanitize_flags_p (SANITIZE_ADDRESS))
4196 278 : maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED);
4197 :
4198 149308 : if (minlen == maxlen)
4199 : {
4200 : /* Fold the strlen call to a constant. */
4201 1622 : tree type = TREE_TYPE (lendata.minlen);
4202 3244 : tree len = force_gimple_operand_gsi (gsi,
4203 1622 : wide_int_to_tree (type, minlen),
4204 : true, NULL, true, GSI_SAME_STMT);
4205 1622 : replace_call_with_value (gsi, len);
4206 1622 : return true;
4207 : }
4208 :
4209 : /* Set the strlen() range to [0, MAXLEN]. */
4210 147686 : if (tree lhs = gimple_call_lhs (stmt))
4211 147681 : set_strlen_range (lhs, minlen, maxlen);
4212 :
4213 : return false;
4214 149308 : }
4215 :
4216 : static bool
4217 245 : gimple_fold_builtin_omp_is_initial_device (gimple_stmt_iterator *gsi)
4218 : {
4219 : #if ACCEL_COMPILER
4220 : replace_call_with_value (gsi, integer_zero_node);
4221 : return true;
4222 : #else
4223 245 : if (!ENABLE_OFFLOADING || symtab->state == EXPANSION)
4224 : {
4225 0 : replace_call_with_value (gsi, integer_one_node);
4226 245 : return true;
4227 : }
4228 : #endif
4229 : return false;
4230 : }
4231 :
4232 : /* omp_get_initial_device was in OpenMP 5.0/5.1 explicitly and in
4233 : 5.0 implicitly the same as omp_get_num_devices; since 6.0 it is
4234 : unspecified whether -1 or omp_get_num_devices() is returned. For
4235 : better backward compatibility, use omp_get_num_devices() on the
4236 : host - and -1 on the device (where the result is unspecified). */
4237 :
4238 : static bool
4239 103 : gimple_fold_builtin_omp_get_initial_device (gimple_stmt_iterator *gsi)
4240 : {
4241 : #if ACCEL_COMPILER
4242 : replace_call_with_value (gsi, build_int_cst (integer_type_node, -1));
4243 : #else
4244 103 : if (!ENABLE_OFFLOADING)
4245 0 : replace_call_with_value (gsi, integer_zero_node);
4246 : else
4247 : {
4248 : tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_DEVICES);
4249 : gcall *repl = gimple_build_call (fn, 0);
4250 : replace_call_with_call_and_fold (gsi, repl);
4251 : }
4252 : #endif
4253 103 : return true;
4254 : }
4255 :
4256 : static bool
4257 321 : gimple_fold_builtin_omp_get_num_devices (gimple_stmt_iterator *gsi)
4258 : {
4259 321 : if (!ENABLE_OFFLOADING)
4260 : {
4261 0 : replace_call_with_value (gsi, integer_zero_node);
4262 321 : return true;
4263 : }
4264 : return false;
4265 : }
4266 :
4267 : /* Fold a call to __builtin_acc_on_device. */
4268 :
4269 : static bool
4270 2866 : gimple_fold_builtin_acc_on_device (gimple_stmt_iterator *gsi, tree arg0)
4271 : {
4272 : /* Defer folding until we know which compiler we're in. */
4273 2866 : if (symtab->state != EXPANSION)
4274 : return false;
4275 :
4276 554 : unsigned val_host = GOMP_DEVICE_HOST;
4277 554 : unsigned val_dev = GOMP_DEVICE_NONE;
4278 :
4279 : #ifdef ACCEL_COMPILER
4280 : val_host = GOMP_DEVICE_NOT_HOST;
4281 : val_dev = ACCEL_COMPILER_acc_device;
4282 : #endif
4283 :
4284 554 : location_t loc = gimple_location (gsi_stmt (*gsi));
4285 :
4286 554 : tree host_eq = make_ssa_name (boolean_type_node);
4287 554 : gimple *host_ass = gimple_build_assign
4288 554 : (host_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_host));
4289 554 : gimple_set_location (host_ass, loc);
4290 554 : gsi_insert_before (gsi, host_ass, GSI_SAME_STMT);
4291 :
4292 554 : tree dev_eq = make_ssa_name (boolean_type_node);
4293 554 : gimple *dev_ass = gimple_build_assign
4294 554 : (dev_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_dev));
4295 554 : gimple_set_location (dev_ass, loc);
4296 554 : gsi_insert_before (gsi, dev_ass, GSI_SAME_STMT);
4297 :
4298 554 : tree result = make_ssa_name (boolean_type_node);
4299 554 : gimple *result_ass = gimple_build_assign
4300 554 : (result, BIT_IOR_EXPR, host_eq, dev_eq);
4301 554 : gimple_set_location (result_ass, loc);
4302 554 : gsi_insert_before (gsi, result_ass, GSI_SAME_STMT);
4303 :
4304 554 : replace_call_with_value (gsi, result);
4305 :
4306 554 : return true;
4307 : }
4308 :
4309 : /* Fold realloc (0, n) -> malloc (n). */
4310 :
4311 : static bool
4312 49817 : gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
4313 : {
4314 49817 : gimple *stmt = gsi_stmt (*gsi);
4315 49817 : tree arg = gimple_call_arg (stmt, 0);
4316 49817 : tree size = gimple_call_arg (stmt, 1);
4317 :
4318 99634 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
4319 : return false;
4320 :
4321 49817 : if (operand_equal_p (arg, null_pointer_node, 0))
4322 : {
4323 1393 : tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
4324 1393 : if (fn_malloc)
4325 : {
4326 1393 : gcall *repl = gimple_build_call (fn_malloc, 1, size);
4327 1393 : replace_call_with_call_and_fold (gsi, repl);
4328 1393 : return true;
4329 : }
4330 : }
4331 : return false;
4332 : }
4333 :
4334 : /* Number of bytes into which any type but aggregate, vector or
4335 : _BitInt types should fit. */
4336 : static constexpr size_t clear_padding_unit
4337 : = MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT;
4338 : /* Buffer size on which __builtin_clear_padding folding code works. */
4339 : static const size_t clear_padding_buf_size = 32 * clear_padding_unit;
4340 :
4341 : /* Data passed through __builtin_clear_padding folding. */
4342 : struct clear_padding_struct {
4343 : location_t loc;
4344 : /* 0 during __builtin_clear_padding folding, nonzero during
4345 : clear_type_padding_in_mask. In that case, instead of clearing the
4346 : non-padding bits in union_ptr array clear the padding bits in there. */
4347 : bool clear_in_mask;
4348 : tree base;
4349 : tree alias_type;
4350 : gimple_stmt_iterator *gsi;
4351 : /* Alignment of buf->base + 0. */
4352 : unsigned align;
4353 : /* Offset from buf->base. Should be always a multiple of UNITS_PER_WORD. */
4354 : HOST_WIDE_INT off;
4355 : /* Number of padding bytes before buf->off that don't have padding clear
4356 : code emitted yet. */
4357 : HOST_WIDE_INT padding_bytes;
4358 : /* The size of the whole object. Never emit code to touch
4359 : buf->base + buf->sz or following bytes. */
4360 : HOST_WIDE_INT sz;
4361 : /* Number of bytes recorded in buf->buf. */
4362 : size_t size;
4363 : /* When inside union, instead of emitting code we and bits inside of
4364 : the union_ptr array. */
4365 : unsigned char *union_ptr;
4366 : /* Set bits mean padding bits that need to be cleared by the builtin. */
4367 : unsigned char buf[clear_padding_buf_size + clear_padding_unit];
4368 : };
4369 :
4370 : /* Emit code to clear padding requested in BUF->buf - set bits
4371 : in there stand for padding that should be cleared. FULL is true
4372 : if everything from the buffer should be flushed, otherwise
4373 : it can leave up to 2 * clear_padding_unit bytes for further
4374 : processing. */
4375 :
4376 : static void
4377 38959 : clear_padding_flush (clear_padding_struct *buf, bool full)
4378 : {
4379 38959 : gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0);
4380 38959 : if (!full && buf->size < 2 * clear_padding_unit)
4381 : return;
4382 40004 : gcc_assert ((buf->off % UNITS_PER_WORD) == 0);
4383 38917 : size_t end = buf->size;
4384 38917 : if (!full)
4385 42 : end = ((end - clear_padding_unit - 1) / clear_padding_unit
4386 : * clear_padding_unit);
4387 38917 : size_t padding_bytes = buf->padding_bytes;
4388 38917 : if (buf->union_ptr)
4389 : {
4390 38150 : if (buf->clear_in_mask)
4391 : {
4392 : /* During clear_type_padding_in_mask, clear the padding
4393 : bits set in buf->buf in the buf->union_ptr mask. */
4394 333748 : for (size_t i = 0; i < end; i++)
4395 : {
4396 295991 : if (buf->buf[i] == (unsigned char) ~0)
4397 9052 : padding_bytes++;
4398 : else
4399 : {
4400 286939 : memset (&buf->union_ptr[buf->off + i - padding_bytes],
4401 : 0, padding_bytes);
4402 286939 : padding_bytes = 0;
4403 286939 : buf->union_ptr[buf->off + i] &= ~buf->buf[i];
4404 : }
4405 : }
4406 37757 : if (full)
4407 : {
4408 37757 : memset (&buf->union_ptr[buf->off + end - padding_bytes],
4409 : 0, padding_bytes);
4410 37757 : buf->off = 0;
4411 37757 : buf->size = 0;
4412 37757 : buf->padding_bytes = 0;
4413 : }
4414 : else
4415 : {
4416 0 : memmove (buf->buf, buf->buf + end, buf->size - end);
4417 0 : buf->off += end;
4418 0 : buf->size -= end;
4419 0 : buf->padding_bytes = padding_bytes;
4420 : }
4421 37757 : return;
4422 : }
4423 : /* Inside of a union, instead of emitting any code, instead
4424 : clear all bits in the union_ptr buffer that are clear
4425 : in buf. Whole padding bytes don't clear anything. */
4426 3017 : for (size_t i = 0; i < end; i++)
4427 : {
4428 2624 : if (buf->buf[i] == (unsigned char) ~0)
4429 1424 : padding_bytes++;
4430 : else
4431 : {
4432 1200 : padding_bytes = 0;
4433 1200 : buf->union_ptr[buf->off + i] &= buf->buf[i];
4434 : }
4435 : }
4436 393 : if (full)
4437 : {
4438 : buf->off = 0;
4439 : buf->size = 0;
4440 : buf->padding_bytes = 0;
4441 : }
4442 : else
4443 : {
4444 0 : memmove (buf->buf, buf->buf + end, buf->size - end);
4445 0 : buf->off += end;
4446 0 : buf->size -= end;
4447 0 : buf->padding_bytes = padding_bytes;
4448 : }
4449 393 : return;
4450 : }
4451 767 : size_t wordsize = UNITS_PER_WORD;
4452 23514 : for (size_t i = 0; i < end; i += wordsize)
4453 : {
4454 22747 : size_t nonzero_first = wordsize;
4455 22747 : size_t nonzero_last = 0;
4456 22747 : size_t zero_first = wordsize;
4457 22747 : size_t zero_last = 0;
4458 22747 : bool all_ones = true, bytes_only = true;
4459 23033 : if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize)
4460 22747 : > (unsigned HOST_WIDE_INT) buf->sz)
4461 : {
4462 286 : gcc_assert (wordsize > 1);
4463 286 : wordsize /= 2;
4464 286 : i -= wordsize;
4465 286 : continue;
4466 : }
4467 22461 : size_t endsize = end - i > wordsize ? wordsize : end - i;
4468 200904 : for (size_t j = i; j < i + endsize; j++)
4469 : {
4470 178443 : if (buf->buf[j])
4471 : {
4472 168410 : if (nonzero_first == wordsize)
4473 : {
4474 21519 : nonzero_first = j - i;
4475 21519 : nonzero_last = j - i;
4476 : }
4477 168410 : if (nonzero_last != j - i)
4478 166 : all_ones = false;
4479 168410 : nonzero_last = j + 1 - i;
4480 : }
4481 : else
4482 : {
4483 10033 : if (zero_first == wordsize)
4484 1946 : zero_first = j - i;
4485 10033 : zero_last = j + 1 - i;
4486 : }
4487 178443 : if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
4488 : {
4489 101 : all_ones = false;
4490 101 : bytes_only = false;
4491 : }
4492 : }
4493 22461 : size_t padding_end = i;
4494 22461 : if (padding_bytes)
4495 : {
4496 20849 : if (nonzero_first == 0
4497 20849 : && nonzero_last == endsize
4498 20400 : && all_ones)
4499 : {
4500 : /* All bits are padding and we had some padding
4501 : before too. Just extend it. */
4502 20400 : padding_bytes += endsize;
4503 20400 : continue;
4504 : }
4505 449 : if (all_ones && nonzero_first == 0)
4506 : {
4507 4 : padding_bytes += nonzero_last;
4508 4 : padding_end += nonzero_last;
4509 4 : nonzero_first = wordsize;
4510 4 : nonzero_last = 0;
4511 : }
4512 445 : else if (bytes_only && nonzero_first == 0)
4513 : {
4514 0 : gcc_assert (zero_first && zero_first != wordsize);
4515 0 : padding_bytes += zero_first;
4516 0 : padding_end += zero_first;
4517 : }
4518 449 : tree atype, src;
4519 449 : if (padding_bytes == 1)
4520 : {
4521 33 : atype = char_type_node;
4522 33 : src = build_zero_cst (char_type_node);
4523 : }
4524 : else
4525 : {
4526 416 : atype = build_array_type_nelts (char_type_node, padding_bytes);
4527 416 : src = build_constructor (atype, NULL);
4528 : }
4529 449 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4530 : build_int_cst (buf->alias_type,
4531 449 : buf->off + padding_end
4532 449 : - padding_bytes));
4533 449 : gimple *g = gimple_build_assign (dst, src);
4534 449 : gimple_set_location (g, buf->loc);
4535 449 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4536 449 : padding_bytes = 0;
4537 449 : buf->padding_bytes = 0;
4538 : }
4539 2061 : if (nonzero_first == wordsize)
4540 : /* All bits in a word are 0, there are no padding bits. */
4541 946 : continue;
4542 1115 : if (all_ones && nonzero_last == endsize)
4543 : {
4544 : /* All bits between nonzero_first and end of word are padding
4545 : bits, start counting padding_bytes. */
4546 841 : padding_bytes = nonzero_last - nonzero_first;
4547 841 : continue;
4548 : }
4549 274 : if (bytes_only)
4550 : {
4551 : /* If bitfields aren't involved in this word, prefer storing
4552 : individual bytes or groups of them over performing a RMW
4553 : operation on the whole word. */
4554 227 : gcc_assert (i + zero_last <= end);
4555 1117 : for (size_t j = padding_end; j < i + zero_last; j++)
4556 : {
4557 890 : if (buf->buf[j])
4558 : {
4559 : size_t k;
4560 606 : for (k = j; k < i + zero_last; k++)
4561 606 : if (buf->buf[k] == 0)
4562 : break;
4563 259 : HOST_WIDE_INT off = buf->off + j;
4564 259 : tree atype, src;
4565 259 : if (k - j == 1)
4566 : {
4567 215 : atype = char_type_node;
4568 215 : src = build_zero_cst (char_type_node);
4569 : }
4570 : else
4571 : {
4572 44 : atype = build_array_type_nelts (char_type_node, k - j);
4573 44 : src = build_constructor (atype, NULL);
4574 : }
4575 259 : tree dst = build2_loc (buf->loc, MEM_REF, atype,
4576 : buf->base,
4577 259 : build_int_cst (buf->alias_type, off));
4578 259 : gimple *g = gimple_build_assign (dst, src);
4579 259 : gimple_set_location (g, buf->loc);
4580 259 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4581 259 : j = k;
4582 : }
4583 : }
4584 227 : if (nonzero_last == endsize)
4585 98 : padding_bytes = nonzero_last - zero_last;
4586 227 : continue;
4587 227 : }
4588 158 : for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
4589 : {
4590 158 : if (nonzero_last - nonzero_first <= eltsz
4591 47 : && ((nonzero_first & ~(eltsz - 1))
4592 47 : == ((nonzero_last - 1) & ~(eltsz - 1))))
4593 : {
4594 47 : tree type;
4595 47 : if (eltsz == 1)
4596 2 : type = char_type_node;
4597 : else
4598 45 : type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT,
4599 : 0);
4600 47 : size_t start = nonzero_first & ~(eltsz - 1);
4601 47 : HOST_WIDE_INT off = buf->off + i + start;
4602 47 : tree atype = type;
4603 47 : if (eltsz > 1 && buf->align < TYPE_ALIGN (type))
4604 8 : atype = build_aligned_type (type, buf->align);
4605 47 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4606 47 : build_int_cst (buf->alias_type, off));
4607 47 : tree src;
4608 47 : gimple *g;
4609 47 : if (all_ones
4610 47 : && nonzero_first == start
4611 0 : && nonzero_last == start + eltsz)
4612 0 : src = build_zero_cst (type);
4613 : else
4614 : {
4615 47 : src = make_ssa_name (type);
4616 47 : tree tmp_dst = unshare_expr (dst);
4617 : /* The folding introduces a read from the tmp_dst, we should
4618 : prevent uninitialized warning analysis from issuing warning
4619 : for such fake read. In order to suppress warning only for
4620 : this expr, we should set the location of tmp_dst to
4621 : UNKNOWN_LOCATION first, then suppress_warning will call
4622 : set_no_warning_bit to set the no_warning flag only for
4623 : tmp_dst. */
4624 47 : SET_EXPR_LOCATION (tmp_dst, UNKNOWN_LOCATION);
4625 47 : suppress_warning (tmp_dst, OPT_Wuninitialized);
4626 47 : g = gimple_build_assign (src, tmp_dst);
4627 47 : gimple_set_location (g, buf->loc);
4628 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4629 94 : tree mask = native_interpret_expr (type,
4630 47 : buf->buf + i + start,
4631 : eltsz);
4632 47 : gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
4633 47 : mask = fold_build1 (BIT_NOT_EXPR, type, mask);
4634 47 : tree src_masked = make_ssa_name (type);
4635 47 : g = gimple_build_assign (src_masked, BIT_AND_EXPR,
4636 : src, mask);
4637 47 : gimple_set_location (g, buf->loc);
4638 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4639 47 : src = src_masked;
4640 : }
4641 47 : g = gimple_build_assign (dst, src);
4642 47 : gimple_set_location (g, buf->loc);
4643 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4644 47 : break;
4645 : }
4646 : }
4647 : }
4648 767 : if (full)
4649 : {
4650 725 : if (padding_bytes)
4651 : {
4652 490 : tree atype, src;
4653 490 : if (padding_bytes == 1)
4654 : {
4655 110 : atype = char_type_node;
4656 110 : src = build_zero_cst (char_type_node);
4657 : }
4658 : else
4659 : {
4660 380 : atype = build_array_type_nelts (char_type_node, padding_bytes);
4661 380 : src = build_constructor (atype, NULL);
4662 : }
4663 490 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4664 : build_int_cst (buf->alias_type,
4665 490 : buf->off + end
4666 490 : - padding_bytes));
4667 490 : gimple *g = gimple_build_assign (dst, src);
4668 490 : gimple_set_location (g, buf->loc);
4669 490 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4670 : }
4671 725 : size_t end_rem = end % UNITS_PER_WORD;
4672 725 : buf->off += end - end_rem;
4673 725 : buf->size = end_rem;
4674 725 : memset (buf->buf, 0, buf->size);
4675 725 : buf->padding_bytes = 0;
4676 : }
4677 : else
4678 : {
4679 42 : memmove (buf->buf, buf->buf + end, buf->size - end);
4680 42 : buf->off += end;
4681 42 : buf->size -= end;
4682 42 : buf->padding_bytes = padding_bytes;
4683 : }
4684 : }
4685 :
4686 : /* Append PADDING_BYTES padding bytes. */
4687 :
4688 : static void
4689 26529 : clear_padding_add_padding (clear_padding_struct *buf,
4690 : HOST_WIDE_INT padding_bytes)
4691 : {
4692 26529 : if (padding_bytes == 0)
4693 : return;
4694 1713 : if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
4695 : > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
4696 42 : clear_padding_flush (buf, false);
4697 1713 : if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
4698 : > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
4699 : {
4700 42 : memset (buf->buf + buf->size, ~0, clear_padding_buf_size - buf->size);
4701 42 : padding_bytes -= clear_padding_buf_size - buf->size;
4702 42 : buf->size = clear_padding_buf_size;
4703 42 : clear_padding_flush (buf, false);
4704 42 : gcc_assert (buf->padding_bytes);
4705 : /* At this point buf->buf[0] through buf->buf[buf->size - 1]
4706 : is guaranteed to be all ones. */
4707 42 : padding_bytes += buf->size;
4708 42 : buf->size = padding_bytes % UNITS_PER_WORD;
4709 42 : memset (buf->buf, ~0, buf->size);
4710 42 : buf->off += padding_bytes - buf->size;
4711 42 : buf->padding_bytes += padding_bytes - buf->size;
4712 : }
4713 : else
4714 : {
4715 1671 : memset (buf->buf + buf->size, ~0, padding_bytes);
4716 1671 : buf->size += padding_bytes;
4717 : }
4718 : }
4719 :
4720 : static void clear_padding_type (clear_padding_struct *, tree,
4721 : HOST_WIDE_INT, bool);
4722 :
4723 : /* Clear padding bits of union type TYPE. */
4724 :
4725 : static void
4726 128 : clear_padding_union (clear_padding_struct *buf, tree type,
4727 : HOST_WIDE_INT sz, bool for_auto_init)
4728 : {
4729 128 : clear_padding_struct *union_buf;
4730 128 : HOST_WIDE_INT start_off = 0, next_off = 0;
4731 128 : size_t start_size = 0;
4732 128 : if (buf->union_ptr)
4733 : {
4734 42 : start_off = buf->off + buf->size;
4735 42 : next_off = start_off + sz;
4736 42 : start_size = start_off % UNITS_PER_WORD;
4737 42 : start_off -= start_size;
4738 42 : clear_padding_flush (buf, true);
4739 42 : union_buf = buf;
4740 : }
4741 : else
4742 : {
4743 86 : if (sz + buf->size > clear_padding_buf_size)
4744 0 : clear_padding_flush (buf, false);
4745 86 : union_buf = XALLOCA (clear_padding_struct);
4746 86 : union_buf->loc = buf->loc;
4747 86 : union_buf->clear_in_mask = buf->clear_in_mask;
4748 86 : union_buf->base = NULL_TREE;
4749 86 : union_buf->alias_type = NULL_TREE;
4750 86 : union_buf->gsi = NULL;
4751 86 : union_buf->align = 0;
4752 86 : union_buf->off = 0;
4753 86 : union_buf->padding_bytes = 0;
4754 86 : union_buf->sz = sz;
4755 86 : union_buf->size = 0;
4756 86 : if (sz + buf->size <= clear_padding_buf_size)
4757 86 : union_buf->union_ptr = buf->buf + buf->size;
4758 : else
4759 0 : union_buf->union_ptr = XNEWVEC (unsigned char, sz);
4760 86 : memset (union_buf->union_ptr, ~0, sz);
4761 : }
4762 :
4763 1193 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
4764 1065 : if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
4765 : {
4766 359 : if (DECL_SIZE_UNIT (field) == NULL_TREE)
4767 : {
4768 8 : if (TREE_TYPE (field) == error_mark_node)
4769 0 : continue;
4770 8 : gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
4771 : && !COMPLETE_TYPE_P (TREE_TYPE (field)));
4772 8 : if (!buf->clear_in_mask && !for_auto_init)
4773 8 : error_at (buf->loc, "flexible array member %qD does not have "
4774 : "well defined padding bits for %qs",
4775 : field, "__builtin_clear_padding");
4776 8 : continue;
4777 : }
4778 351 : HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
4779 351 : gcc_assert (union_buf->size == 0);
4780 351 : union_buf->off = start_off;
4781 351 : union_buf->size = start_size;
4782 351 : memset (union_buf->buf, ~0, start_size);
4783 351 : clear_padding_type (union_buf, TREE_TYPE (field), fldsz, for_auto_init);
4784 351 : clear_padding_add_padding (union_buf, sz - fldsz);
4785 351 : clear_padding_flush (union_buf, true);
4786 : }
4787 :
4788 128 : if (buf == union_buf)
4789 : {
4790 42 : buf->off = next_off;
4791 42 : buf->size = next_off % UNITS_PER_WORD;
4792 42 : buf->off -= buf->size;
4793 42 : memset (buf->buf, ~0, buf->size);
4794 : }
4795 86 : else if (sz + buf->size <= clear_padding_buf_size)
4796 86 : buf->size += sz;
4797 : else
4798 : {
4799 0 : unsigned char *union_ptr = union_buf->union_ptr;
4800 0 : while (sz)
4801 : {
4802 0 : clear_padding_flush (buf, false);
4803 0 : HOST_WIDE_INT this_sz
4804 0 : = MIN ((unsigned HOST_WIDE_INT) sz,
4805 : clear_padding_buf_size - buf->size);
4806 0 : memcpy (buf->buf + buf->size, union_ptr, this_sz);
4807 0 : buf->size += this_sz;
4808 0 : union_ptr += this_sz;
4809 0 : sz -= this_sz;
4810 : }
4811 0 : XDELETE (union_buf->union_ptr);
4812 : }
4813 128 : }
4814 :
4815 : /* The only known floating point formats with padding bits are the
4816 : IEEE extended ones. */
4817 :
4818 : static bool
4819 38229 : clear_padding_real_needs_padding_p (tree type)
4820 : {
4821 38229 : const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
4822 38229 : return (fmt->b == 2
4823 37618 : && fmt->signbit_ro == fmt->signbit_rw
4824 75847 : && (fmt->signbit_ro == 79 || fmt->signbit_ro == 95));
4825 : }
4826 :
4827 : /* _BitInt has padding bits if it isn't extended in the ABI and has smaller
4828 : precision than bits in limb or corresponding number of limbs. */
4829 :
4830 : static bool
4831 54 : clear_padding_bitint_needs_padding_p (tree type)
4832 : {
4833 54 : struct bitint_info info;
4834 54 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
4835 54 : gcc_assert (ok);
4836 54 : if (info.extended)
4837 : return false;
4838 54 : scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.abi_limb_mode);
4839 54 : if (TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
4840 : return true;
4841 4 : else if (TYPE_PRECISION (type) == GET_MODE_PRECISION (limb_mode))
4842 : return false;
4843 : else
4844 4 : return (((unsigned) TYPE_PRECISION (type))
4845 4 : % GET_MODE_PRECISION (limb_mode)) != 0;
4846 : }
4847 :
4848 : /* Return true if TYPE might contain any padding bits. */
4849 :
4850 : bool
4851 948064 : clear_padding_type_may_have_padding_p (tree type)
4852 : {
4853 1087554 : switch (TREE_CODE (type))
4854 : {
4855 : case RECORD_TYPE:
4856 : case UNION_TYPE:
4857 : return true;
4858 139490 : case ARRAY_TYPE:
4859 139490 : case COMPLEX_TYPE:
4860 139490 : case VECTOR_TYPE:
4861 139490 : return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
4862 1930 : case REAL_TYPE:
4863 1930 : return clear_padding_real_needs_padding_p (type);
4864 63 : case ENUMERAL_TYPE:
4865 63 : if (BITINT_TYPE_P (type))
4866 0 : return clear_padding_bitint_needs_padding_p (type);
4867 : return false;
4868 54 : case BITINT_TYPE:
4869 54 : return clear_padding_bitint_needs_padding_p (type);
4870 : default:
4871 : return false;
4872 : }
4873 : }
4874 :
4875 : /* Return true if TYPE has padding bits aside from those in fields,
4876 : elements, etc. */
4877 :
4878 : bool
4879 1202484 : type_has_padding_at_level_p (tree type)
4880 : {
4881 1202484 : switch (TREE_CODE (type))
4882 : {
4883 1059740 : case RECORD_TYPE:
4884 1059740 : {
4885 1059740 : tree bitpos = size_zero_node;
4886 : /* Expect fields to be sorted by bit position. */
4887 8667347 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4888 7613090 : if (TREE_CODE (f) == FIELD_DECL)
4889 : {
4890 2306443 : if (DECL_PADDING_P (f))
4891 : return true;
4892 2306440 : tree pos = bit_position (f);
4893 2306440 : if (simple_cst_equal (bitpos, pos) != 1)
4894 : return true;
4895 2300983 : if (!DECL_SIZE (f))
4896 : return true;
4897 2300960 : bitpos = int_const_binop (PLUS_EXPR, pos, DECL_SIZE (f));
4898 : }
4899 1054257 : if (simple_cst_equal (bitpos, TYPE_SIZE (type)) != 1)
4900 12177 : return true;
4901 : return false;
4902 : }
4903 3 : case UNION_TYPE:
4904 3 : case QUAL_UNION_TYPE:
4905 3 : bool any_fields;
4906 3 : any_fields = false;
4907 : /* If any of the fields is smaller than the whole, there is padding. */
4908 6 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4909 3 : if (TREE_CODE (f) != FIELD_DECL || TREE_TYPE (f) == error_mark_node)
4910 3 : continue;
4911 0 : else if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
4912 0 : TYPE_SIZE (type)) != 1)
4913 : return true;
4914 : else
4915 : any_fields = true;
4916 : /* If the union doesn't have any fields and still has non-zero size,
4917 : all of it is padding. */
4918 3 : if (!any_fields && !integer_zerop (TYPE_SIZE (type)))
4919 3 : return true;
4920 : return false;
4921 : case ARRAY_TYPE:
4922 : case COMPLEX_TYPE:
4923 : case VECTOR_TYPE:
4924 : /* No recursing here, no padding at this level. */
4925 : return false;
4926 0 : case REAL_TYPE:
4927 0 : return clear_padding_real_needs_padding_p (type);
4928 0 : case ENUMERAL_TYPE:
4929 0 : if (BITINT_TYPE_P (type))
4930 0 : return clear_padding_bitint_needs_padding_p (type);
4931 : return false;
4932 0 : case BITINT_TYPE:
4933 0 : return clear_padding_bitint_needs_padding_p (type);
4934 : default:
4935 : return false;
4936 : }
4937 : }
4938 :
4939 : /* Emit a runtime loop:
4940 : for (; buf.base != end; buf.base += sz)
4941 : __builtin_clear_padding (buf.base); */
4942 :
4943 : static void
4944 114 : clear_padding_emit_loop (clear_padding_struct *buf, tree type,
4945 : tree end, bool for_auto_init)
4946 : {
4947 114 : tree l1 = create_artificial_label (buf->loc);
4948 114 : tree l2 = create_artificial_label (buf->loc);
4949 114 : tree l3 = create_artificial_label (buf->loc);
4950 114 : gimple *g = gimple_build_goto (l2);
4951 114 : gimple_set_location (g, buf->loc);
4952 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4953 114 : g = gimple_build_label (l1);
4954 114 : gimple_set_location (g, buf->loc);
4955 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4956 114 : clear_padding_type (buf, type, buf->sz, for_auto_init);
4957 114 : clear_padding_flush (buf, true);
4958 114 : g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
4959 114 : size_int (buf->sz));
4960 114 : gimple_set_location (g, buf->loc);
4961 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4962 114 : g = gimple_build_label (l2);
4963 114 : gimple_set_location (g, buf->loc);
4964 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4965 114 : g = gimple_build_cond (NE_EXPR, buf->base, end, l1, l3);
4966 114 : gimple_set_location (g, buf->loc);
4967 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4968 114 : g = gimple_build_label (l3);
4969 114 : gimple_set_location (g, buf->loc);
4970 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4971 114 : }
4972 :
4973 : /* Clear padding bits for TYPE. Called recursively from
4974 : gimple_fold_builtin_clear_padding. If FOR_AUTO_INIT is true,
4975 : the __builtin_clear_padding is not called by the end user,
4976 : instead, it's inserted by the compiler to initialize the
4977 : paddings of automatic variable. Therefore, we should not
4978 : emit the error messages for flexible array members to confuse
4979 : the end user. */
4980 :
4981 : static void
4982 73837 : clear_padding_type (clear_padding_struct *buf, tree type,
4983 : HOST_WIDE_INT sz, bool for_auto_init)
4984 : {
4985 73837 : switch (TREE_CODE (type))
4986 : {
4987 10304 : case RECORD_TYPE:
4988 10304 : HOST_WIDE_INT cur_pos;
4989 10304 : cur_pos = 0;
4990 793667 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
4991 783363 : if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
4992 : {
4993 24977 : tree ftype = TREE_TYPE (field);
4994 24977 : if (DECL_BIT_FIELD (field))
4995 : {
4996 292 : HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype);
4997 292 : if (fldsz == 0)
4998 0 : continue;
4999 292 : HOST_WIDE_INT pos = int_byte_position (field);
5000 292 : if (pos >= sz)
5001 0 : continue;
5002 292 : HOST_WIDE_INT bpos
5003 292 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
5004 292 : bpos %= BITS_PER_UNIT;
5005 292 : HOST_WIDE_INT end
5006 292 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
5007 292 : if (pos + end > cur_pos)
5008 : {
5009 215 : clear_padding_add_padding (buf, pos + end - cur_pos);
5010 215 : cur_pos = pos + end;
5011 : }
5012 292 : gcc_assert (cur_pos > pos
5013 : && ((unsigned HOST_WIDE_INT) buf->size
5014 : >= (unsigned HOST_WIDE_INT) cur_pos - pos));
5015 292 : unsigned char *p = buf->buf + buf->size - (cur_pos - pos);
5016 292 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5017 : sorry_at (buf->loc, "PDP11 bit-field handling unsupported"
5018 : " in %qs", "__builtin_clear_padding");
5019 292 : else if (BYTES_BIG_ENDIAN)
5020 : {
5021 : /* Big endian. */
5022 : if (bpos + fldsz <= BITS_PER_UNIT)
5023 : *p &= ~(((1 << fldsz) - 1)
5024 : << (BITS_PER_UNIT - bpos - fldsz));
5025 : else
5026 : {
5027 : if (bpos)
5028 : {
5029 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
5030 : p++;
5031 : fldsz -= BITS_PER_UNIT - bpos;
5032 : }
5033 : memset (p, 0, fldsz / BITS_PER_UNIT);
5034 : p += fldsz / BITS_PER_UNIT;
5035 : fldsz %= BITS_PER_UNIT;
5036 : if (fldsz)
5037 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
5038 : }
5039 : }
5040 : else
5041 : {
5042 : /* Little endian. */
5043 292 : if (bpos + fldsz <= BITS_PER_UNIT)
5044 175 : *p &= ~(((1 << fldsz) - 1) << bpos);
5045 : else
5046 : {
5047 117 : if (bpos)
5048 : {
5049 33 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
5050 33 : p++;
5051 33 : fldsz -= BITS_PER_UNIT - bpos;
5052 : }
5053 117 : memset (p, 0, fldsz / BITS_PER_UNIT);
5054 117 : p += fldsz / BITS_PER_UNIT;
5055 117 : fldsz %= BITS_PER_UNIT;
5056 117 : if (fldsz)
5057 72 : *p &= ~((1 << fldsz) - 1);
5058 : }
5059 : }
5060 : }
5061 24685 : else if (DECL_SIZE_UNIT (field) == NULL_TREE)
5062 : {
5063 32 : if (ftype == error_mark_node)
5064 0 : continue;
5065 32 : gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
5066 : && !COMPLETE_TYPE_P (ftype));
5067 32 : if (!buf->clear_in_mask && !for_auto_init)
5068 24 : error_at (buf->loc, "flexible array member %qD does not "
5069 : "have well defined padding bits for %qs",
5070 : field, "__builtin_clear_padding");
5071 : }
5072 24653 : else if (is_empty_type (ftype))
5073 8994 : continue;
5074 : else
5075 : {
5076 15659 : HOST_WIDE_INT pos = int_byte_position (field);
5077 15659 : if (pos >= sz)
5078 0 : continue;
5079 15659 : HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
5080 15659 : gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
5081 15659 : clear_padding_add_padding (buf, pos - cur_pos);
5082 15659 : cur_pos = pos;
5083 15659 : if (tree asbase = lang_hooks.types.classtype_as_base (field))
5084 300 : ftype = asbase;
5085 15659 : clear_padding_type (buf, ftype, fldsz, for_auto_init);
5086 15659 : cur_pos += fldsz;
5087 : }
5088 : }
5089 10304 : gcc_assert (sz >= cur_pos);
5090 10304 : clear_padding_add_padding (buf, sz - cur_pos);
5091 10304 : break;
5092 326 : case ARRAY_TYPE:
5093 326 : HOST_WIDE_INT nelts, fldsz;
5094 326 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5095 326 : if (fldsz == 0)
5096 : break;
5097 312 : nelts = sz / fldsz;
5098 312 : if (nelts > 1
5099 305 : && sz > 8 * UNITS_PER_WORD
5100 78 : && buf->union_ptr == NULL
5101 390 : && clear_padding_type_may_have_padding_p (TREE_TYPE (type)))
5102 : {
5103 : /* For sufficiently large array of more than one elements,
5104 : emit a runtime loop to keep code size manageable. */
5105 66 : tree base = buf->base;
5106 66 : unsigned int prev_align = buf->align;
5107 66 : HOST_WIDE_INT off = buf->off + buf->size;
5108 66 : HOST_WIDE_INT prev_sz = buf->sz;
5109 66 : clear_padding_flush (buf, true);
5110 66 : tree elttype = TREE_TYPE (type);
5111 66 : buf->base = create_tmp_var (build_pointer_type (elttype));
5112 66 : tree end = make_ssa_name (TREE_TYPE (buf->base));
5113 66 : gimple *g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR,
5114 66 : base, size_int (off));
5115 66 : gimple_set_location (g, buf->loc);
5116 66 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
5117 66 : g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf->base,
5118 66 : size_int (sz));
5119 66 : gimple_set_location (g, buf->loc);
5120 66 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
5121 66 : buf->sz = fldsz;
5122 66 : buf->align = TYPE_ALIGN (elttype);
5123 66 : buf->off = 0;
5124 66 : buf->size = 0;
5125 66 : clear_padding_emit_loop (buf, elttype, end, for_auto_init);
5126 66 : off += sz;
5127 66 : buf->base = base;
5128 66 : buf->sz = prev_sz;
5129 66 : buf->align = prev_align;
5130 66 : buf->size = off % UNITS_PER_WORD;
5131 66 : buf->off = off - buf->size;
5132 66 : memset (buf->buf, 0, buf->size);
5133 66 : break;
5134 : }
5135 1180 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5136 934 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5137 : break;
5138 128 : case UNION_TYPE:
5139 128 : clear_padding_union (buf, type, sz, for_auto_init);
5140 128 : break;
5141 36299 : case REAL_TYPE:
5142 36299 : gcc_assert ((size_t) sz <= clear_padding_unit);
5143 36299 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5144 0 : clear_padding_flush (buf, false);
5145 36299 : if (clear_padding_real_needs_padding_p (type))
5146 : {
5147 : /* Use native_interpret_real + native_encode_expr to figure out
5148 : which bits are padding. */
5149 1587 : memset (buf->buf + buf->size, ~0, sz);
5150 1587 : tree cst = native_interpret_real (type, buf->buf + buf->size, sz);
5151 1587 : gcc_assert (cst && TREE_CODE (cst) == REAL_CST);
5152 1587 : int len = native_encode_expr (cst, buf->buf + buf->size, sz);
5153 1587 : gcc_assert (len > 0 && (size_t) len == (size_t) sz);
5154 26979 : for (size_t i = 0; i < (size_t) sz; i++)
5155 25392 : buf->buf[buf->size + i] ^= ~0;
5156 : }
5157 : else
5158 34712 : memset (buf->buf + buf->size, 0, sz);
5159 36299 : buf->size += sz;
5160 36299 : break;
5161 0 : case COMPLEX_TYPE:
5162 0 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5163 0 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5164 0 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5165 0 : break;
5166 5180 : case VECTOR_TYPE:
5167 5180 : nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
5168 5180 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5169 28828 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5170 18468 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5171 : break;
5172 7 : case NULLPTR_TYPE:
5173 7 : gcc_assert ((size_t) sz <= clear_padding_unit);
5174 7 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5175 0 : clear_padding_flush (buf, false);
5176 7 : memset (buf->buf + buf->size, ~0, sz);
5177 7 : buf->size += sz;
5178 7 : break;
5179 4 : case BITINT_TYPE:
5180 4 : do_bitint:
5181 4 : {
5182 4 : struct bitint_info info;
5183 4 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
5184 4 : gcc_assert (ok);
5185 4 : scalar_int_mode limb_mode
5186 4 : = as_a <scalar_int_mode> (info.abi_limb_mode);
5187 4 : if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
5188 : {
5189 2 : gcc_assert ((size_t) sz <= clear_padding_unit);
5190 2 : if ((unsigned HOST_WIDE_INT) sz + buf->size
5191 : > clear_padding_buf_size)
5192 0 : clear_padding_flush (buf, false);
5193 2 : if (!info.extended
5194 2 : && TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
5195 : {
5196 2 : int tprec = GET_MODE_PRECISION (limb_mode);
5197 2 : int prec = TYPE_PRECISION (type);
5198 2 : tree t = build_nonstandard_integer_type (tprec, 1);
5199 2 : tree cst = wide_int_to_tree (t, wi::mask (prec, true, tprec));
5200 2 : int len = native_encode_expr (cst, buf->buf + buf->size, sz);
5201 2 : gcc_assert (len > 0 && (size_t) len == (size_t) sz);
5202 : }
5203 : else
5204 0 : memset (buf->buf + buf->size, 0, sz);
5205 2 : buf->size += sz;
5206 2 : break;
5207 : }
5208 2 : tree limbtype
5209 2 : = build_nonstandard_integer_type (GET_MODE_PRECISION (limb_mode), 1);
5210 2 : fldsz = int_size_in_bytes (limbtype);
5211 2 : nelts = int_size_in_bytes (type) / fldsz;
5212 13 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5213 : {
5214 11 : if (!info.extended
5215 11 : && i == (info.big_endian ? 0 : nelts - 1)
5216 13 : && (((unsigned) TYPE_PRECISION (type))
5217 2 : % TYPE_PRECISION (limbtype)) != 0)
5218 : {
5219 2 : int tprec = GET_MODE_PRECISION (limb_mode);
5220 2 : int prec = (((unsigned) TYPE_PRECISION (type)) % tprec);
5221 2 : tree cst = wide_int_to_tree (limbtype,
5222 2 : wi::mask (prec, true, tprec));
5223 2 : int len = native_encode_expr (cst, buf->buf + buf->size,
5224 : fldsz);
5225 2 : gcc_assert (len > 0 && (size_t) len == (size_t) fldsz);
5226 2 : buf->size += fldsz;
5227 : }
5228 : else
5229 9 : clear_padding_type (buf, limbtype, fldsz, for_auto_init);
5230 : }
5231 : break;
5232 : }
5233 0 : case ENUMERAL_TYPE:
5234 0 : if (BITINT_TYPE_P (type))
5235 0 : goto do_bitint;
5236 : /* FALLTHRU */
5237 21589 : default:
5238 21589 : gcc_assert ((size_t) sz <= clear_padding_unit);
5239 21589 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5240 0 : clear_padding_flush (buf, false);
5241 21589 : memset (buf->buf + buf->size, 0, sz);
5242 21589 : buf->size += sz;
5243 21589 : break;
5244 : }
5245 73837 : }
5246 :
5247 : /* Clear padding bits of TYPE in MASK. */
5248 :
5249 : void
5250 37757 : clear_type_padding_in_mask (tree type, unsigned char *mask)
5251 : {
5252 37757 : clear_padding_struct buf;
5253 37757 : buf.loc = UNKNOWN_LOCATION;
5254 37757 : buf.clear_in_mask = true;
5255 37757 : buf.base = NULL_TREE;
5256 37757 : buf.alias_type = NULL_TREE;
5257 37757 : buf.gsi = NULL;
5258 37757 : buf.align = 0;
5259 37757 : buf.off = 0;
5260 37757 : buf.padding_bytes = 0;
5261 37757 : buf.sz = int_size_in_bytes (type);
5262 37757 : buf.size = 0;
5263 37757 : buf.union_ptr = mask;
5264 37757 : clear_padding_type (&buf, type, buf.sz, false);
5265 37757 : clear_padding_flush (&buf, true);
5266 37757 : }
5267 :
5268 : /* Fold __builtin_clear_padding builtin. */
5269 :
5270 : static bool
5271 631 : gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
5272 : {
5273 631 : gimple *stmt = gsi_stmt (*gsi);
5274 631 : gcc_assert (gimple_call_num_args (stmt) == 2);
5275 631 : tree ptr = gimple_call_arg (stmt, 0);
5276 631 : tree typearg = gimple_call_arg (stmt, 1);
5277 : /* The 2nd argument of __builtin_clear_padding's value is used to
5278 : distinguish whether this call is made by the user or by the compiler
5279 : for automatic variable initialization. */
5280 631 : bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg);
5281 631 : tree type = TREE_TYPE (TREE_TYPE (typearg));
5282 631 : location_t loc = gimple_location (stmt);
5283 631 : clear_padding_struct buf;
5284 631 : gimple_stmt_iterator gsiprev = *gsi;
5285 : /* This should be folded during the lower pass. */
5286 1262 : gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL);
5287 631 : gcc_assert (COMPLETE_TYPE_P (type));
5288 631 : gsi_prev (&gsiprev);
5289 :
5290 631 : buf.loc = loc;
5291 631 : buf.clear_in_mask = false;
5292 631 : buf.base = ptr;
5293 631 : buf.alias_type = NULL_TREE;
5294 631 : buf.gsi = gsi;
5295 631 : buf.align = get_pointer_alignment (ptr);
5296 631 : unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT;
5297 631 : buf.align = MAX (buf.align, talign);
5298 631 : buf.off = 0;
5299 631 : buf.padding_bytes = 0;
5300 631 : buf.size = 0;
5301 631 : buf.sz = int_size_in_bytes (type);
5302 631 : buf.union_ptr = NULL;
5303 631 : if (buf.sz < 0 && int_size_in_bytes (strip_array_types (type)) < 0)
5304 1 : sorry_at (loc, "%s not supported for variable length aggregates",
5305 : "__builtin_clear_padding");
5306 : /* The implementation currently assumes 8-bit host and target
5307 : chars which is the case for all currently supported targets
5308 : and hosts and is required e.g. for native_{encode,interpret}* APIs. */
5309 630 : else if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
5310 : sorry_at (loc, "%s not supported on this target",
5311 : "__builtin_clear_padding");
5312 630 : else if (!clear_padding_type_may_have_padding_p (type))
5313 : ;
5314 593 : else if (TREE_CODE (type) == ARRAY_TYPE && buf.sz < 0)
5315 : {
5316 48 : tree sz = TYPE_SIZE_UNIT (type);
5317 48 : tree elttype = type;
5318 : /* Only supports C/C++ VLAs and flattens all the VLA levels. */
5319 48 : while (TREE_CODE (elttype) == ARRAY_TYPE
5320 144 : && int_size_in_bytes (elttype) < 0)
5321 96 : elttype = TREE_TYPE (elttype);
5322 48 : HOST_WIDE_INT eltsz = int_size_in_bytes (elttype);
5323 48 : gcc_assert (eltsz >= 0);
5324 48 : if (eltsz)
5325 : {
5326 48 : buf.base = create_tmp_var (build_pointer_type (elttype));
5327 48 : tree end = make_ssa_name (TREE_TYPE (buf.base));
5328 48 : gimple *g = gimple_build_assign (buf.base, ptr);
5329 48 : gimple_set_location (g, loc);
5330 48 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5331 48 : g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf.base, sz);
5332 48 : gimple_set_location (g, loc);
5333 48 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5334 48 : buf.sz = eltsz;
5335 48 : buf.align = TYPE_ALIGN (elttype);
5336 48 : buf.alias_type = build_pointer_type (elttype);
5337 48 : clear_padding_emit_loop (&buf, elttype, end, for_auto_init);
5338 : }
5339 : }
5340 : else
5341 : {
5342 545 : if (!is_gimple_mem_ref_addr (buf.base))
5343 : {
5344 28 : buf.base = make_ssa_name (TREE_TYPE (ptr));
5345 28 : gimple *g = gimple_build_assign (buf.base, ptr);
5346 28 : gimple_set_location (g, loc);
5347 28 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5348 : }
5349 545 : buf.alias_type = build_pointer_type (type);
5350 545 : clear_padding_type (&buf, type, buf.sz, for_auto_init);
5351 545 : clear_padding_flush (&buf, true);
5352 : }
5353 :
5354 631 : gimple_stmt_iterator gsiprev2 = *gsi;
5355 631 : gsi_prev (&gsiprev2);
5356 631 : if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
5357 126 : gsi_replace (gsi, gimple_build_nop (), true);
5358 : else
5359 : {
5360 505 : gsi_remove (gsi, true);
5361 505 : *gsi = gsiprev2;
5362 : }
5363 631 : return true;
5364 : }
5365 :
5366 : /* Fold __builtin_constant_p builtin. */
5367 :
5368 : static bool
5369 169937 : gimple_fold_builtin_constant_p (gimple_stmt_iterator *gsi)
5370 : {
5371 169937 : gcall *call = as_a<gcall*>(gsi_stmt (*gsi));
5372 :
5373 169937 : if (gimple_call_num_args (call) != 1)
5374 : return false;
5375 :
5376 169932 : tree arg = gimple_call_arg (call, 0);
5377 169932 : tree result = fold_builtin_constant_p (arg);
5378 :
5379 : /* Resolve __builtin_constant_p. If it hasn't been
5380 : folded to integer_one_node by now, it's fairly
5381 : certain that the value simply isn't constant. */
5382 338031 : if (!result && fold_before_rtl_expansion_p ())
5383 3 : result = integer_zero_node;
5384 :
5385 169932 : if (!result)
5386 : return false;
5387 :
5388 1836 : gimplify_and_update_call_from_tree (gsi, result);
5389 1836 : return true;
5390 : }
5391 :
5392 : /* If va_list type is a simple pointer and nothing special is needed,
5393 : optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
5394 : __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
5395 : pointer assignment. Returns true if a change happened. */
5396 :
5397 : static bool
5398 115283 : gimple_fold_builtin_stdarg (gimple_stmt_iterator *gsi, gcall *call)
5399 : {
5400 : /* These shouldn't be folded before pass_stdarg. */
5401 115283 : if (!fold_before_rtl_expansion_p ())
5402 : return false;
5403 :
5404 10840 : tree callee, lhs, rhs, cfun_va_list;
5405 10840 : bool va_list_simple_ptr;
5406 10840 : location_t loc = gimple_location (call);
5407 10840 : gimple *nstmt0, *nstmt;
5408 10840 : tree tlhs, oldvdef, newvdef;
5409 :
5410 10840 : callee = gimple_call_fndecl (call);
5411 :
5412 10840 : cfun_va_list = targetm.fn_abi_va_list (callee);
5413 21680 : va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
5414 10840 : && (TREE_TYPE (cfun_va_list) == void_type_node
5415 436 : || TREE_TYPE (cfun_va_list) == char_type_node);
5416 :
5417 10840 : switch (DECL_FUNCTION_CODE (callee))
5418 : {
5419 7020 : case BUILT_IN_VA_START:
5420 7020 : if (!va_list_simple_ptr
5421 172 : || targetm.expand_builtin_va_start != NULL
5422 7176 : || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
5423 : return false;
5424 :
5425 156 : if (gimple_call_num_args (call) != 2)
5426 : return false;
5427 :
5428 156 : lhs = gimple_call_arg (call, 0);
5429 156 : if (!POINTER_TYPE_P (TREE_TYPE (lhs))
5430 156 : || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
5431 156 : != TYPE_MAIN_VARIANT (cfun_va_list))
5432 : return false;
5433 : /* Create `tlhs = __builtin_next_arg(0);`. */
5434 156 : tlhs = make_ssa_name (cfun_va_list);
5435 156 : nstmt0 = gimple_build_call (builtin_decl_explicit (BUILT_IN_NEXT_ARG), 1, integer_zero_node);
5436 156 : lhs = fold_build2 (MEM_REF, cfun_va_list, lhs, build_zero_cst (TREE_TYPE (lhs)));
5437 156 : gimple_call_set_lhs (nstmt0, tlhs);
5438 156 : gimple_set_location (nstmt0, loc);
5439 156 : gimple_move_vops (nstmt0, call);
5440 156 : gsi_replace (gsi, nstmt0, false);
5441 156 : oldvdef = gimple_vdef (nstmt0);
5442 156 : newvdef = make_ssa_name (gimple_vop (cfun), nstmt0);
5443 156 : gimple_set_vdef (nstmt0, newvdef);
5444 :
5445 : /* Create `*lhs = tlhs;`. */
5446 156 : nstmt = gimple_build_assign (lhs, tlhs);
5447 156 : gimple_set_location (nstmt, loc);
5448 156 : gimple_set_vuse (nstmt, newvdef);
5449 156 : gimple_set_vdef (nstmt, oldvdef);
5450 156 : SSA_NAME_DEF_STMT (oldvdef) = nstmt;
5451 156 : gsi_insert_after (gsi, nstmt, GSI_NEW_STMT);
5452 :
5453 156 : if (dump_file && (dump_flags & TDF_DETAILS))
5454 : {
5455 0 : fprintf (dump_file, "Simplified\n ");
5456 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5457 0 : fprintf (dump_file, "into\n ");
5458 0 : print_gimple_stmt (dump_file, nstmt0, 0, dump_flags);
5459 0 : fprintf (dump_file, " ");
5460 0 : print_gimple_stmt (dump_file, nstmt, 0, dump_flags);
5461 : }
5462 : return true;
5463 :
5464 244 : case BUILT_IN_VA_COPY:
5465 244 : if (!va_list_simple_ptr)
5466 : return false;
5467 :
5468 47 : if (gimple_call_num_args (call) != 2)
5469 : return false;
5470 :
5471 47 : lhs = gimple_call_arg (call, 0);
5472 47 : if (!POINTER_TYPE_P (TREE_TYPE (lhs))
5473 47 : || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
5474 47 : != TYPE_MAIN_VARIANT (cfun_va_list))
5475 : return false;
5476 47 : rhs = gimple_call_arg (call, 1);
5477 47 : if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
5478 47 : != TYPE_MAIN_VARIANT (cfun_va_list))
5479 : return false;
5480 :
5481 47 : lhs = fold_build2 (MEM_REF, cfun_va_list, lhs, build_zero_cst (TREE_TYPE (lhs)));
5482 47 : nstmt = gimple_build_assign (lhs, rhs);
5483 47 : gimple_set_location (nstmt, loc);
5484 47 : gimple_move_vops (nstmt, call);
5485 47 : gsi_replace (gsi, nstmt, false);
5486 :
5487 47 : if (dump_file && (dump_flags & TDF_DETAILS))
5488 : {
5489 0 : fprintf (dump_file, "Simplified\n ");
5490 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5491 0 : fprintf (dump_file, "into\n ");
5492 0 : print_gimple_stmt (dump_file, nstmt, 0, dump_flags);
5493 : }
5494 : return true;
5495 :
5496 3576 : case BUILT_IN_VA_END:
5497 : /* No effect, so the statement will be deleted. */
5498 3576 : if (dump_file && (dump_flags & TDF_DETAILS))
5499 : {
5500 0 : fprintf (dump_file, "Removed\n ");
5501 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5502 : }
5503 3576 : unlink_stmt_vdef (call);
5504 3576 : release_defs (call);
5505 3576 : gsi_replace (gsi, gimple_build_nop (), false);
5506 3576 : return true;
5507 :
5508 0 : default:
5509 0 : gcc_unreachable ();
5510 : }
5511 : }
5512 :
5513 : /* Fold __builtin_call_{code_address,static_chain} builtins. This handles
5514 : only the trivial left-over cases not processed in tree-nested.cc. */
5515 :
5516 : static bool
5517 2 : gimple_fold_builtin_call_info (gimple_stmt_iterator *gsi,
5518 : enum built_in_function fcode)
5519 : {
5520 2 : gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
5521 2 : tree arg = gimple_call_arg (stmt, 0);
5522 :
5523 : /* The error will be emitted in builtins.cc. */
5524 2 : if (TREE_CODE (arg) != ADDR_EXPR
5525 2 : || FUNCTION_DECL != TREE_CODE (TREE_OPERAND (arg, 0)))
5526 : return false;
5527 :
5528 : /* The case with static chain is handled in tree-nested.cc. */
5529 2 : gcc_assert (!DECL_STATIC_CHAIN (TREE_OPERAND (arg, 0)));
5530 :
5531 2 : if (fcode == BUILT_IN_CALL_STATIC_CHAIN)
5532 1 : replace_call_with_value (gsi, null_pointer_node);
5533 : else
5534 1 : replace_call_with_value (gsi, arg);
5535 :
5536 : return true;
5537 : }
5538 :
5539 :
5540 : /* Fold the non-target builtin at *GSI and return whether any simplification
5541 : was made. */
5542 :
5543 : static bool
5544 9629038 : gimple_fold_builtin (gimple_stmt_iterator *gsi)
5545 : {
5546 9629038 : gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
5547 9629038 : tree callee = gimple_call_fndecl (stmt);
5548 :
5549 : /* Give up for always_inline inline builtins until they are
5550 : inlined. */
5551 9629038 : if (avoid_folding_inline_builtin (callee))
5552 : return false;
5553 :
5554 9627861 : unsigned n = gimple_call_num_args (stmt);
5555 9627861 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
5556 9627861 : switch (fcode)
5557 : {
5558 115283 : case BUILT_IN_VA_START:
5559 115283 : case BUILT_IN_VA_END:
5560 115283 : case BUILT_IN_VA_COPY:
5561 115283 : return gimple_fold_builtin_stdarg (gsi, stmt);
5562 148 : case BUILT_IN_BCMP:
5563 148 : return gimple_fold_builtin_bcmp (gsi);
5564 367 : case BUILT_IN_BCOPY:
5565 367 : return gimple_fold_builtin_bcopy (gsi);
5566 250 : case BUILT_IN_BZERO:
5567 250 : return gimple_fold_builtin_bzero (gsi);
5568 :
5569 315790 : case BUILT_IN_MEMSET:
5570 315790 : return gimple_fold_builtin_memset (gsi,
5571 : gimple_call_arg (stmt, 1),
5572 315790 : gimple_call_arg (stmt, 2));
5573 10276 : case BUILT_IN_MEMPCPY:
5574 10276 : if (gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5575 : gimple_call_arg (stmt, 1), fcode))
5576 : return true;
5577 9536 : return gimple_fold_builtin_mempcpy (gsi);
5578 1044445 : case BUILT_IN_MEMCPY:
5579 1044445 : case BUILT_IN_MEMMOVE:
5580 1044445 : return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5581 1044445 : gimple_call_arg (stmt, 1), fcode);
5582 4471 : case BUILT_IN_SPRINTF_CHK:
5583 4471 : case BUILT_IN_VSPRINTF_CHK:
5584 4471 : return gimple_fold_builtin_sprintf_chk (gsi, fcode);
5585 1493 : case BUILT_IN_STRCAT_CHK:
5586 1493 : return gimple_fold_builtin_strcat_chk (gsi);
5587 1116 : case BUILT_IN_STRNCAT_CHK:
5588 1116 : return gimple_fold_builtin_strncat_chk (gsi);
5589 149308 : case BUILT_IN_STRLEN:
5590 149308 : return gimple_fold_builtin_strlen (gsi);
5591 26129 : case BUILT_IN_STRCPY:
5592 26129 : return gimple_fold_builtin_strcpy (gsi,
5593 : gimple_call_arg (stmt, 0),
5594 26129 : gimple_call_arg (stmt, 1));
5595 17274 : case BUILT_IN_STRNCPY:
5596 17274 : return gimple_fold_builtin_strncpy (gsi,
5597 : gimple_call_arg (stmt, 0),
5598 : gimple_call_arg (stmt, 1),
5599 17274 : gimple_call_arg (stmt, 2));
5600 7331 : case BUILT_IN_STRCAT:
5601 7331 : return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
5602 7331 : gimple_call_arg (stmt, 1));
5603 6786 : case BUILT_IN_STRNCAT:
5604 6786 : return gimple_fold_builtin_strncat (gsi);
5605 4743 : case BUILT_IN_INDEX:
5606 4743 : case BUILT_IN_STRCHR:
5607 4743 : return gimple_fold_builtin_strchr (gsi, false);
5608 727 : case BUILT_IN_RINDEX:
5609 727 : case BUILT_IN_STRRCHR:
5610 727 : return gimple_fold_builtin_strchr (gsi, true);
5611 4372 : case BUILT_IN_STRSTR:
5612 4372 : return gimple_fold_builtin_strstr (gsi);
5613 1250699 : case BUILT_IN_STRCMP:
5614 1250699 : case BUILT_IN_STRCMP_EQ:
5615 1250699 : case BUILT_IN_STRCASECMP:
5616 1250699 : case BUILT_IN_STRNCMP:
5617 1250699 : case BUILT_IN_STRNCMP_EQ:
5618 1250699 : case BUILT_IN_STRNCASECMP:
5619 1250699 : return gimple_fold_builtin_string_compare (gsi);
5620 38310 : case BUILT_IN_MEMCHR:
5621 38310 : return gimple_fold_builtin_memchr (gsi);
5622 20687 : case BUILT_IN_FPUTS:
5623 20687 : return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5624 20687 : gimple_call_arg (stmt, 1), false);
5625 43 : case BUILT_IN_FPUTS_UNLOCKED:
5626 43 : return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5627 43 : gimple_call_arg (stmt, 1), true);
5628 40685 : case BUILT_IN_FWRITE:
5629 40685 : return gimple_fold_builtin_fwrite (gsi, false);
5630 257 : case BUILT_IN_FWRITE_UNLOCKED:
5631 257 : return gimple_fold_builtin_fwrite (gsi, true);
5632 25701 : case BUILT_IN_MEMCPY_CHK:
5633 25701 : case BUILT_IN_MEMPCPY_CHK:
5634 25701 : case BUILT_IN_MEMMOVE_CHK:
5635 25701 : case BUILT_IN_MEMSET_CHK:
5636 25701 : return gimple_fold_builtin_memory_chk (gsi,
5637 : gimple_call_arg (stmt, 0),
5638 : gimple_call_arg (stmt, 1),
5639 : gimple_call_arg (stmt, 2),
5640 : gimple_call_arg (stmt, 3),
5641 25701 : fcode);
5642 3674 : case BUILT_IN_STPCPY:
5643 3674 : return gimple_fold_builtin_stpcpy (gsi);
5644 2566 : case BUILT_IN_STRCPY_CHK:
5645 2566 : case BUILT_IN_STPCPY_CHK:
5646 2566 : return gimple_fold_builtin_stxcpy_chk (gsi,
5647 : gimple_call_arg (stmt, 0),
5648 : gimple_call_arg (stmt, 1),
5649 : gimple_call_arg (stmt, 2),
5650 2566 : fcode);
5651 2721 : case BUILT_IN_STRNCPY_CHK:
5652 2721 : case BUILT_IN_STPNCPY_CHK:
5653 2721 : return gimple_fold_builtin_stxncpy_chk (gsi,
5654 : gimple_call_arg (stmt, 0),
5655 : gimple_call_arg (stmt, 1),
5656 : gimple_call_arg (stmt, 2),
5657 : gimple_call_arg (stmt, 3),
5658 2721 : fcode);
5659 2359 : case BUILT_IN_SNPRINTF_CHK:
5660 2359 : case BUILT_IN_VSNPRINTF_CHK:
5661 2359 : return gimple_fold_builtin_snprintf_chk (gsi, fcode);
5662 :
5663 847624 : case BUILT_IN_FPRINTF:
5664 847624 : case BUILT_IN_FPRINTF_UNLOCKED:
5665 847624 : case BUILT_IN_VFPRINTF:
5666 847624 : if (n == 2 || n == 3)
5667 95103 : return gimple_fold_builtin_fprintf (gsi,
5668 : gimple_call_arg (stmt, 0),
5669 : gimple_call_arg (stmt, 1),
5670 : n == 3
5671 42586 : ? gimple_call_arg (stmt, 2)
5672 : : NULL_TREE,
5673 52517 : fcode);
5674 : break;
5675 2229 : case BUILT_IN_FPRINTF_CHK:
5676 2229 : case BUILT_IN_VFPRINTF_CHK:
5677 2229 : if (n == 3 || n == 4)
5678 3814 : return gimple_fold_builtin_fprintf (gsi,
5679 : gimple_call_arg (stmt, 0),
5680 : gimple_call_arg (stmt, 2),
5681 : n == 4
5682 1744 : ? gimple_call_arg (stmt, 3)
5683 : : NULL_TREE,
5684 2070 : fcode);
5685 : break;
5686 199032 : case BUILT_IN_PRINTF:
5687 199032 : case BUILT_IN_PRINTF_UNLOCKED:
5688 199032 : case BUILT_IN_VPRINTF:
5689 199032 : if (n == 1 || n == 2)
5690 234792 : return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
5691 : n == 2
5692 112837 : ? gimple_call_arg (stmt, 1)
5693 121955 : : NULL_TREE, fcode);
5694 : break;
5695 2273 : case BUILT_IN_PRINTF_CHK:
5696 2273 : case BUILT_IN_VPRINTF_CHK:
5697 2273 : if (n == 2 || n == 3)
5698 3893 : return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 1),
5699 : n == 3
5700 1771 : ? gimple_call_arg (stmt, 2)
5701 2122 : : NULL_TREE, fcode);
5702 : break;
5703 2866 : case BUILT_IN_ACC_ON_DEVICE:
5704 2866 : return gimple_fold_builtin_acc_on_device (gsi,
5705 2866 : gimple_call_arg (stmt, 0));
5706 245 : case BUILT_IN_OMP_IS_INITIAL_DEVICE:
5707 245 : return gimple_fold_builtin_omp_is_initial_device (gsi);
5708 :
5709 103 : case BUILT_IN_OMP_GET_INITIAL_DEVICE:
5710 103 : return gimple_fold_builtin_omp_get_initial_device (gsi);
5711 :
5712 321 : case BUILT_IN_OMP_GET_NUM_DEVICES:
5713 321 : return gimple_fold_builtin_omp_get_num_devices (gsi);
5714 :
5715 49817 : case BUILT_IN_REALLOC:
5716 49817 : return gimple_fold_builtin_realloc (gsi);
5717 :
5718 631 : case BUILT_IN_CLEAR_PADDING:
5719 631 : return gimple_fold_builtin_clear_padding (gsi);
5720 :
5721 169937 : case BUILT_IN_CONSTANT_P:
5722 169937 : return gimple_fold_builtin_constant_p (gsi);
5723 :
5724 2 : case BUILT_IN_CALL_CODE_ADDRESS:
5725 2 : case BUILT_IN_CALL_STATIC_CHAIN:
5726 2 : return gimple_fold_builtin_call_info (gsi, fcode);
5727 :
5728 6127264 : default:;
5729 : }
5730 :
5731 : /* Try the generic builtin folder. */
5732 6127264 : bool ignore = (gimple_call_lhs (stmt) == NULL);
5733 6127264 : tree result = fold_call_stmt (stmt, ignore);
5734 6127264 : if (result)
5735 : {
5736 5089 : if (ignore)
5737 1249 : STRIP_NOPS (result);
5738 : else
5739 3840 : result = fold_convert (gimple_call_return_type (stmt), result);
5740 5089 : gimplify_and_update_call_from_tree (gsi, result);
5741 5089 : return true;
5742 : }
5743 :
5744 : return false;
5745 : }
5746 :
5747 : /* Transform IFN_GOACC_DIM_SIZE and IFN_GOACC_DIM_POS internal
5748 : function calls to constants, where possible. */
5749 :
5750 : static tree
5751 20589 : fold_internal_goacc_dim (const gimple *call)
5752 : {
5753 20589 : int axis = oacc_get_ifn_dim_arg (call);
5754 20589 : int size = oacc_get_fn_dim_size (current_function_decl, axis);
5755 20589 : tree result = NULL_TREE;
5756 20589 : tree type = TREE_TYPE (gimple_call_lhs (call));
5757 :
5758 20589 : switch (gimple_call_internal_fn (call))
5759 : {
5760 8915 : case IFN_GOACC_DIM_POS:
5761 : /* If the size is 1, we know the answer. */
5762 8915 : if (size == 1)
5763 8915 : result = build_int_cst (type, 0);
5764 : break;
5765 11674 : case IFN_GOACC_DIM_SIZE:
5766 : /* If the size is not dynamic, we know the answer. */
5767 11674 : if (size)
5768 11674 : result = build_int_cst (type, size);
5769 : break;
5770 : default:
5771 : break;
5772 : }
5773 :
5774 20589 : return result;
5775 : }
5776 :
5777 : /* Return true if stmt is __atomic_compare_exchange_N call which is suitable
5778 : for conversion into ATOMIC_COMPARE_EXCHANGE if the second argument is
5779 : &var where var is only addressable because of such calls. */
5780 :
5781 : bool
5782 60857714 : optimize_atomic_compare_exchange_p (gimple *stmt)
5783 : {
5784 60857714 : if (gimple_call_num_args (stmt) != 6
5785 1655755 : || !flag_inline_atomics
5786 1655755 : || !optimize
5787 1655755 : || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
5788 1655674 : || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
5789 1111171 : || !gimple_vdef (stmt)
5790 61849113 : || !gimple_vuse (stmt))
5791 : return false;
5792 :
5793 991399 : tree fndecl = gimple_call_fndecl (stmt);
5794 991399 : switch (DECL_FUNCTION_CODE (fndecl))
5795 : {
5796 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
5797 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
5798 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
5799 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
5800 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
5801 51845 : break;
5802 : default:
5803 : return false;
5804 : }
5805 :
5806 51845 : tree expected = gimple_call_arg (stmt, 1);
5807 51845 : if (TREE_CODE (expected) != ADDR_EXPR
5808 51845 : || !SSA_VAR_P (TREE_OPERAND (expected, 0)))
5809 : return false;
5810 :
5811 49457 : tree etype = TREE_TYPE (TREE_OPERAND (expected, 0));
5812 49457 : if (!is_gimple_reg_type (etype)
5813 49022 : || !auto_var_in_fn_p (TREE_OPERAND (expected, 0), current_function_decl)
5814 46631 : || TREE_THIS_VOLATILE (etype)
5815 46631 : || VECTOR_TYPE_P (etype)
5816 : || TREE_CODE (etype) == COMPLEX_TYPE
5817 : /* Don't optimize floating point expected vars, VIEW_CONVERT_EXPRs
5818 : might not preserve all the bits. See PR71716. */
5819 : || SCALAR_FLOAT_TYPE_P (etype)
5820 67481 : || maybe_ne (TYPE_PRECISION (etype),
5821 36048 : GET_MODE_BITSIZE (TYPE_MODE (etype))))
5822 : return false;
5823 :
5824 11616 : tree weak = gimple_call_arg (stmt, 3);
5825 11616 : if (!integer_zerop (weak) && !integer_onep (weak))
5826 : return false;
5827 :
5828 11616 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5829 11616 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5830 11616 : machine_mode mode = TYPE_MODE (itype);
5831 :
5832 11616 : if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
5833 : == CODE_FOR_nothing
5834 11616 : && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
5835 : return false;
5836 :
5837 23232 : if (maybe_ne (int_size_in_bytes (etype), GET_MODE_SIZE (mode)))
5838 0 : return false;
5839 :
5840 : return true;
5841 : }
5842 :
5843 : /* Fold
5844 : r = __atomic_compare_exchange_N (p, &e, d, w, s, f);
5845 : into
5846 : _Complex uintN_t t = ATOMIC_COMPARE_EXCHANGE (p, e, d, w * 256 + N, s, f);
5847 : i = IMAGPART_EXPR <t>;
5848 : r = (_Bool) i;
5849 : e = REALPART_EXPR <t>; */
5850 :
5851 : void
5852 5733 : fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
5853 : {
5854 5733 : gimple *stmt = gsi_stmt (*gsi);
5855 5733 : tree fndecl = gimple_call_fndecl (stmt);
5856 5733 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5857 5733 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5858 5733 : tree ctype = build_complex_type (itype);
5859 5733 : tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
5860 5733 : bool throws = false;
5861 5733 : edge e = NULL;
5862 5733 : gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5863 : expected);
5864 5733 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5865 5733 : gimple_stmt_iterator gsiret = gsi_for_stmt (g);
5866 5733 : if (!useless_type_conversion_p (itype, TREE_TYPE (expected)))
5867 : {
5868 2651 : g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
5869 : build1 (VIEW_CONVERT_EXPR, itype,
5870 : gimple_assign_lhs (g)));
5871 2651 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5872 : }
5873 5733 : int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
5874 11083 : + int_size_in_bytes (itype);
5875 5733 : g = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE, 6,
5876 : gimple_call_arg (stmt, 0),
5877 : gimple_assign_lhs (g),
5878 : gimple_call_arg (stmt, 2),
5879 5733 : build_int_cst (integer_type_node, flag),
5880 : gimple_call_arg (stmt, 4),
5881 : gimple_call_arg (stmt, 5));
5882 5733 : tree lhs = make_ssa_name (ctype);
5883 5733 : gimple_call_set_lhs (g, lhs);
5884 5733 : gimple_move_vops (g, stmt);
5885 5733 : tree oldlhs = gimple_call_lhs (stmt);
5886 5733 : if (stmt_can_throw_internal (cfun, stmt))
5887 : {
5888 203 : throws = true;
5889 203 : e = find_fallthru_edge (gsi_bb (*gsi)->succs);
5890 : }
5891 5733 : gimple_call_set_nothrow (as_a <gcall *> (g),
5892 5733 : gimple_call_nothrow_p (as_a <gcall *> (stmt)));
5893 5733 : gimple_call_set_lhs (stmt, NULL_TREE);
5894 5733 : gsi_replace (gsi, g, true);
5895 5733 : if (oldlhs)
5896 : {
5897 5686 : g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
5898 : build1 (IMAGPART_EXPR, itype, lhs));
5899 5686 : if (throws)
5900 : {
5901 197 : gsi_insert_on_edge_immediate (e, g);
5902 197 : *gsi = gsi_for_stmt (g);
5903 : }
5904 : else
5905 5489 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5906 5686 : g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
5907 5686 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5908 : }
5909 5733 : g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
5910 : build1 (REALPART_EXPR, itype, lhs));
5911 5733 : if (throws && oldlhs == NULL_TREE)
5912 : {
5913 6 : gsi_insert_on_edge_immediate (e, g);
5914 6 : *gsi = gsi_for_stmt (g);
5915 : }
5916 : else
5917 5727 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5918 5733 : if (!useless_type_conversion_p (TREE_TYPE (expected), itype))
5919 : {
5920 5302 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5921 : VIEW_CONVERT_EXPR,
5922 2651 : build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected),
5923 : gimple_assign_lhs (g)));
5924 2651 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5925 : }
5926 5733 : g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
5927 5733 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5928 5733 : *gsi = gsiret;
5929 5733 : }
5930 :
5931 : /* Return true if ARG0 CODE ARG1 in infinite signed precision operation
5932 : doesn't fit into TYPE. The test for overflow should be regardless of
5933 : -fwrapv, and even for unsigned types. */
5934 :
5935 : bool
5936 450945 : arith_overflowed_p (enum tree_code code, const_tree type,
5937 : const_tree arg0, const_tree arg1)
5938 : {
5939 450945 : widest2_int warg0 = widest2_int_cst (arg0);
5940 450945 : widest2_int warg1 = widest2_int_cst (arg1);
5941 450945 : widest2_int wres;
5942 450945 : switch (code)
5943 : {
5944 96513 : case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
5945 115747 : case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
5946 240136 : case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
5947 0 : default: gcc_unreachable ();
5948 : }
5949 450945 : signop sign = TYPE_SIGN (type);
5950 450945 : if (sign == UNSIGNED && wi::neg_p (wres))
5951 : return true;
5952 379012 : return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
5953 451085 : }
5954 :
5955 : /* Mask state for partial load/store operations (mask and length). */
5956 : enum mask_load_store_state {
5957 : MASK_ALL_INACTIVE, /* All lanes/elements are inactive (can be elided). */
5958 : MASK_ALL_ACTIVE, /* All lanes/elements are active (unconditional). */
5959 : MASK_UNKNOWN
5960 : };
5961 :
5962 : /* Check the mask/length state of IFN_{MASK,LEN,MASK_LEN}_LOAD/STORE call CALL.
5963 : Returns whether all elements are active, all inactive, or mixed.
5964 : VECTYPE is the vector type of the operation. */
5965 :
5966 : static enum mask_load_store_state
5967 7951 : partial_load_store_mask_state (gcall *call, tree vectype)
5968 : {
5969 7951 : internal_fn ifn = gimple_call_internal_fn (call);
5970 7951 : int mask_index = internal_fn_mask_index (ifn);
5971 7951 : int len_index = internal_fn_len_index (ifn);
5972 :
5973 : /* Extract length and mask arguments up front. */
5974 7951 : tree len = len_index != -1 ? gimple_call_arg (call, len_index) : NULL_TREE;
5975 0 : tree bias = len ? gimple_call_arg (call, len_index + 1) : NULL_TREE;
5976 7951 : tree mask = mask_index != -1 ? gimple_call_arg (call, mask_index) : NULL_TREE;
5977 :
5978 15902 : poly_int64 nelts = GET_MODE_NUNITS (TYPE_MODE (vectype));
5979 :
5980 7951 : poly_widest_int wlen = -1;
5981 7951 : bool full_length_p = !len; /* No length means full length. */
5982 :
5983 : /* Compute effective length. */
5984 7951 : if (len && poly_int_tree_p (len))
5985 : {
5986 0 : gcc_assert (TREE_CODE (bias) == INTEGER_CST);
5987 0 : wlen = wi::to_poly_widest (len) + wi::to_widest (bias);
5988 :
5989 0 : if (known_eq (wlen, 0))
5990 : return MASK_ALL_INACTIVE;
5991 :
5992 0 : if (known_eq (wlen, nelts))
5993 : full_length_p = true;
5994 : else
5995 7951 : full_length_p = false;
5996 : }
5997 :
5998 : /* Check mask for early return cases. */
5999 7951 : if (mask)
6000 : {
6001 7951 : if (integer_zerop (mask))
6002 : return MASK_ALL_INACTIVE;
6003 :
6004 7936 : if (full_length_p && integer_all_onesp (mask))
6005 : return MASK_ALL_ACTIVE;
6006 : }
6007 0 : else if (full_length_p)
6008 : /* No mask and full length means all active. */
6009 : return MASK_ALL_ACTIVE;
6010 :
6011 : /* For VLA vectors, we can't do much more. */
6012 7786 : if (!nelts.is_constant ())
6013 : return MASK_UNKNOWN;
6014 :
6015 : /* Same for VLS vectors with non-constant mask. */
6016 7786 : if (mask && TREE_CODE (mask) != VECTOR_CST)
6017 : return MASK_UNKNOWN;
6018 :
6019 : /* Check VLS vector elements. */
6020 504 : gcc_assert (wlen.is_constant ());
6021 :
6022 504 : HOST_WIDE_INT active_len = wlen.to_constant ().to_shwi ();
6023 504 : if (active_len == -1)
6024 504 : active_len = nelts.to_constant ();
6025 :
6026 : /* Check if all elements in the active range match the mask. */
6027 1038 : for (HOST_WIDE_INT i = 0; i < active_len; i++)
6028 : {
6029 1038 : bool elt_active = !mask || !integer_zerop (vector_cst_elt (mask, i));
6030 : if (!elt_active)
6031 : {
6032 : /* Found an inactive element. Check if all are inactive. */
6033 1002 : for (HOST_WIDE_INT j = 0; j < active_len; j++)
6034 1002 : if (!mask || !integer_zerop (vector_cst_elt (mask, j)))
6035 : return MASK_UNKNOWN; /* Mixed state. */
6036 : return MASK_ALL_INACTIVE;
6037 : }
6038 : }
6039 :
6040 : /* All elements in active range are active. */
6041 0 : return full_length_p ? MASK_ALL_ACTIVE : MASK_UNKNOWN;
6042 7951 : }
6043 :
6044 :
6045 : /* If IFN_{MASK,LEN,MASK_LEN}_LOAD/STORE call CALL is unconditional
6046 : (all lanes active), return a MEM_REF for the memory it references.
6047 : Otherwise return NULL_TREE. VECTYPE is the type of the memory vector. */
6048 :
6049 : static tree
6050 3968 : gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype)
6051 : {
6052 : /* Only fold if all lanes are active (unconditional). */
6053 3968 : if (partial_load_store_mask_state (call, vectype) != MASK_ALL_ACTIVE)
6054 : return NULL_TREE;
6055 :
6056 75 : tree ptr = gimple_call_arg (call, 0);
6057 75 : tree alias_align = gimple_call_arg (call, 1);
6058 75 : if (!tree_fits_uhwi_p (alias_align))
6059 : return NULL_TREE;
6060 :
6061 75 : unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
6062 75 : if (TYPE_ALIGN (vectype) != align)
6063 14 : vectype = build_aligned_type (vectype, align);
6064 75 : tree offset = build_zero_cst (TREE_TYPE (alias_align));
6065 75 : return fold_build2 (MEM_REF, vectype, ptr, offset);
6066 : }
6067 :
6068 : /* Try to fold IFN_{MASK,LEN}_LOAD/STORE call CALL. Return true on success. */
6069 :
6070 : static bool
6071 3983 : gimple_fold_partial_load_store (gimple_stmt_iterator *gsi, gcall *call)
6072 : {
6073 3983 : internal_fn ifn = gimple_call_internal_fn (call);
6074 3983 : tree lhs = gimple_call_lhs (call);
6075 3983 : bool is_load = (lhs != NULL_TREE);
6076 3983 : tree vectype;
6077 :
6078 3983 : if (is_load)
6079 1991 : vectype = TREE_TYPE (lhs);
6080 : else
6081 : {
6082 1992 : tree rhs = gimple_call_arg (call, internal_fn_stored_value_index (ifn));
6083 1992 : vectype = TREE_TYPE (rhs);
6084 : }
6085 :
6086 3983 : enum mask_load_store_state state
6087 3983 : = partial_load_store_mask_state (call, vectype);
6088 :
6089 : /* Handle all-inactive case. */
6090 3983 : if (state == MASK_ALL_INACTIVE)
6091 : {
6092 15 : if (is_load)
6093 : {
6094 : /* Replace load with else value. */
6095 15 : int else_index = internal_fn_else_index (ifn);
6096 15 : tree else_value = gimple_call_arg (call, else_index);
6097 15 : if (!is_gimple_reg (lhs))
6098 : {
6099 0 : if (!zerop (else_value))
6100 : return false;
6101 0 : else_value = build_constructor (TREE_TYPE (lhs), NULL);
6102 : }
6103 15 : gassign *new_stmt = gimple_build_assign (lhs, else_value);
6104 15 : gimple_set_location (new_stmt, gimple_location (call));
6105 : /* When the lhs is an array for LANES version, then there is still
6106 : a store, move the vops from the old stmt to the new one. */
6107 15 : if (!is_gimple_reg (lhs))
6108 0 : gimple_move_vops (new_stmt, call);
6109 15 : gsi_replace (gsi, new_stmt, false);
6110 15 : return true;
6111 : }
6112 : else
6113 : {
6114 : /* Remove inactive store altogether. */
6115 0 : unlink_stmt_vdef (call);
6116 0 : release_defs (call);
6117 0 : gsi_replace (gsi, gimple_build_nop (), true);
6118 0 : return true;
6119 : }
6120 : }
6121 :
6122 : /* We cannot simplify a gather/scatter or load/store lanes further. */
6123 3968 : if (internal_gather_scatter_fn_p (ifn)
6124 3968 : || TREE_CODE (vectype) == ARRAY_TYPE)
6125 : return false;
6126 :
6127 : /* Handle all-active case by folding to regular memory operation. */
6128 3968 : if (tree mem_ref = gimple_fold_partial_load_store_mem_ref (call, vectype))
6129 : {
6130 75 : gassign *new_stmt;
6131 75 : if (is_load)
6132 21 : new_stmt = gimple_build_assign (lhs, mem_ref);
6133 : else
6134 : {
6135 54 : tree rhs
6136 54 : = gimple_call_arg (call, internal_fn_stored_value_index (ifn));
6137 54 : new_stmt = gimple_build_assign (mem_ref, rhs);
6138 : }
6139 :
6140 75 : gimple_set_location (new_stmt, gimple_location (call));
6141 75 : gimple_move_vops (new_stmt, call);
6142 75 : gsi_replace (gsi, new_stmt, false);
6143 75 : return true;
6144 : }
6145 : return false;
6146 : }
6147 :
6148 : /* Attempt to fold a call statement referenced by the statement iterator GSI.
6149 : The statement may be replaced by another statement, e.g., if the call
6150 : simplifies to a constant value. Return true if any changes were made.
6151 : It is assumed that the operands have been previously folded. */
6152 :
6153 : static bool
6154 58068062 : gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
6155 : {
6156 58068062 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
6157 58068062 : tree callee;
6158 58068062 : bool changed = false;
6159 :
6160 : /* Check for virtual calls that became direct calls. */
6161 58068062 : callee = gimple_call_fn (stmt);
6162 58068062 : if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
6163 : {
6164 462627 : if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
6165 : {
6166 6 : if (dump_file && virtual_method_call_p (callee)
6167 408 : && !possible_polymorphic_call_target_p
6168 6 : (callee, stmt, cgraph_node::get (gimple_call_addr_fndecl
6169 6 : (OBJ_TYPE_REF_EXPR (callee)))))
6170 : {
6171 0 : fprintf (dump_file,
6172 : "Type inheritance inconsistent devirtualization of ");
6173 0 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
6174 0 : fprintf (dump_file, " to ");
6175 0 : print_generic_expr (dump_file, callee, TDF_SLIM);
6176 0 : fprintf (dump_file, "\n");
6177 : }
6178 :
6179 402 : gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
6180 402 : changed = true;
6181 : }
6182 462225 : else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
6183 : {
6184 457152 : bool final;
6185 457152 : vec <cgraph_node *>targets
6186 457152 : = possible_polymorphic_call_targets (callee, stmt, &final);
6187 459816 : if (final && targets.length () <= 1 && dbg_cnt (devirt))
6188 : {
6189 2028 : tree lhs = gimple_call_lhs (stmt);
6190 2028 : if (dump_enabled_p ())
6191 : {
6192 34 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
6193 : "folding virtual function call to %s\n",
6194 34 : targets.length () == 1
6195 17 : ? targets[0]->name ()
6196 : : "__builtin_unreachable");
6197 : }
6198 2028 : if (targets.length () == 1)
6199 : {
6200 1989 : tree fndecl = targets[0]->decl;
6201 1989 : gimple_call_set_fndecl (stmt, fndecl);
6202 1989 : changed = true;
6203 : /* If changing the call to __cxa_pure_virtual
6204 : or similar noreturn function, adjust gimple_call_fntype
6205 : too. */
6206 1989 : if (gimple_call_noreturn_p (stmt)
6207 19 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
6208 13 : && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
6209 2002 : && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
6210 13 : == void_type_node))
6211 13 : gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
6212 : /* If the call becomes noreturn, remove the lhs. */
6213 1989 : if (lhs
6214 1668 : && gimple_call_noreturn_p (stmt)
6215 2004 : && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
6216 6 : || should_remove_lhs_p (lhs)))
6217 : {
6218 12 : if (TREE_CODE (lhs) == SSA_NAME)
6219 : {
6220 0 : tree var = create_tmp_var (TREE_TYPE (lhs));
6221 0 : tree def = get_or_create_ssa_default_def (cfun, var);
6222 0 : gimple *new_stmt = gimple_build_assign (lhs, def);
6223 0 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
6224 : }
6225 12 : gimple_call_set_lhs (stmt, NULL_TREE);
6226 : }
6227 1989 : maybe_remove_unused_call_args (cfun, stmt);
6228 : }
6229 : else
6230 : {
6231 39 : location_t loc = gimple_location (stmt);
6232 39 : gimple *new_stmt = gimple_build_builtin_unreachable (loc);
6233 39 : gimple_call_set_ctrl_altering (new_stmt, false);
6234 : /* If the call had a SSA name as lhs morph that into
6235 : an uninitialized value. */
6236 39 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
6237 : {
6238 12 : tree var = create_tmp_var (TREE_TYPE (lhs));
6239 12 : SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
6240 12 : SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
6241 12 : set_ssa_default_def (cfun, var, lhs);
6242 : }
6243 39 : gimple_move_vops (new_stmt, stmt);
6244 39 : gsi_replace (gsi, new_stmt, false);
6245 39 : return true;
6246 : }
6247 : }
6248 : }
6249 : }
6250 :
6251 : /* Check for indirect calls that became direct calls, and then
6252 : no longer require a static chain. */
6253 58068023 : if (gimple_call_chain (stmt))
6254 : {
6255 246623 : tree fn = gimple_call_fndecl (stmt);
6256 295697 : if (fn && !DECL_STATIC_CHAIN (fn))
6257 : {
6258 2054 : gimple_call_set_chain (stmt, NULL);
6259 2054 : changed = true;
6260 : }
6261 : }
6262 :
6263 58068023 : if (inplace)
6264 : return changed;
6265 :
6266 : /* Don't constant fold functions which can change the control. */
6267 58064892 : if (gimple_call_ctrl_altering_p (stmt))
6268 : return changed;
6269 :
6270 : /* Check for builtins that CCP can handle using information not
6271 : available in the generic fold routines. */
6272 50116534 : if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
6273 : {
6274 9629038 : if (gimple_fold_builtin (gsi))
6275 211241 : changed = true;
6276 : }
6277 40487496 : else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
6278 : {
6279 1156311 : changed |= targetm.gimple_fold_builtin (gsi);
6280 : }
6281 39331185 : else if (gimple_call_internal_p (stmt))
6282 : {
6283 1959311 : enum tree_code subcode = ERROR_MARK;
6284 1959311 : tree result = NULL_TREE;
6285 1959311 : bool cplx_result = false;
6286 1959311 : bool uaddc_usubc = false;
6287 1959311 : tree overflow = NULL_TREE;
6288 1959311 : switch (gimple_call_internal_fn (stmt))
6289 : {
6290 852 : case IFN_ASSUME:
6291 : /* Remove .ASSUME calls during the last fold since it is no
6292 : longer needed. */
6293 852 : if (fold_before_rtl_expansion_p ())
6294 116 : replace_call_with_value (gsi, NULL_TREE);
6295 : break;
6296 165575 : case IFN_BUILTIN_EXPECT:
6297 165575 : result = fold_builtin_expect (gimple_location (stmt),
6298 : gimple_call_arg (stmt, 0),
6299 : gimple_call_arg (stmt, 1),
6300 : gimple_call_arg (stmt, 2),
6301 : NULL_TREE);
6302 165575 : break;
6303 8881 : case IFN_UBSAN_OBJECT_SIZE:
6304 8881 : {
6305 8881 : tree offset = gimple_call_arg (stmt, 1);
6306 8881 : tree objsize = gimple_call_arg (stmt, 2);
6307 8881 : if (integer_all_onesp (objsize)
6308 8881 : || (TREE_CODE (offset) == INTEGER_CST
6309 4828 : && TREE_CODE (objsize) == INTEGER_CST
6310 1126 : && tree_int_cst_le (offset, objsize)))
6311 : {
6312 1539 : replace_call_with_value (gsi, NULL_TREE);
6313 1539 : return true;
6314 : }
6315 : }
6316 : break;
6317 11656 : case IFN_UBSAN_PTR:
6318 11656 : if (integer_zerop (gimple_call_arg (stmt, 1)))
6319 : {
6320 30 : replace_call_with_value (gsi, NULL_TREE);
6321 30 : return true;
6322 : }
6323 : break;
6324 8493 : case IFN_UBSAN_BOUNDS:
6325 8493 : {
6326 8493 : tree index = gimple_call_arg (stmt, 1);
6327 8493 : tree bound = gimple_call_arg (stmt, 2);
6328 8493 : if (TREE_CODE (index) == INTEGER_CST
6329 5471 : && TREE_CODE (bound) == INTEGER_CST)
6330 : {
6331 4340 : index = fold_convert (TREE_TYPE (bound), index);
6332 4340 : if (TREE_CODE (index) == INTEGER_CST
6333 4340 : && tree_int_cst_lt (index, bound))
6334 : {
6335 286 : replace_call_with_value (gsi, NULL_TREE);
6336 286 : return true;
6337 : }
6338 : }
6339 : }
6340 : break;
6341 20589 : case IFN_GOACC_DIM_SIZE:
6342 20589 : case IFN_GOACC_DIM_POS:
6343 20589 : result = fold_internal_goacc_dim (stmt);
6344 20589 : break;
6345 : case IFN_UBSAN_CHECK_ADD:
6346 : subcode = PLUS_EXPR;
6347 : break;
6348 : case IFN_UBSAN_CHECK_SUB:
6349 : subcode = MINUS_EXPR;
6350 : break;
6351 : case IFN_UBSAN_CHECK_MUL:
6352 : subcode = MULT_EXPR;
6353 : break;
6354 : case IFN_ADD_OVERFLOW:
6355 : subcode = PLUS_EXPR;
6356 : cplx_result = true;
6357 : break;
6358 : case IFN_SUB_OVERFLOW:
6359 : subcode = MINUS_EXPR;
6360 : cplx_result = true;
6361 : break;
6362 : case IFN_MUL_OVERFLOW:
6363 : subcode = MULT_EXPR;
6364 : cplx_result = true;
6365 : break;
6366 : case IFN_UADDC:
6367 : subcode = PLUS_EXPR;
6368 : cplx_result = true;
6369 : uaddc_usubc = true;
6370 : break;
6371 : case IFN_USUBC:
6372 : subcode = MINUS_EXPR;
6373 : cplx_result = true;
6374 : uaddc_usubc = true;
6375 : break;
6376 3983 : case IFN_LEN_LOAD:
6377 3983 : case IFN_MASK_LOAD:
6378 3983 : case IFN_MASK_LEN_LOAD:
6379 3983 : case IFN_MASK_GATHER_LOAD:
6380 3983 : case IFN_MASK_LEN_GATHER_LOAD:
6381 3983 : case IFN_MASK_LOAD_LANES:
6382 3983 : case IFN_MASK_LEN_LOAD_LANES:
6383 3983 : case IFN_LEN_STORE:
6384 3983 : case IFN_MASK_STORE:
6385 3983 : case IFN_MASK_LEN_STORE:
6386 3983 : case IFN_MASK_SCATTER_STORE:
6387 3983 : case IFN_MASK_LEN_SCATTER_STORE:
6388 3983 : case IFN_MASK_STORE_LANES:
6389 3983 : case IFN_MASK_LEN_STORE_LANES:
6390 3983 : changed |= gimple_fold_partial_load_store (gsi, stmt);
6391 3983 : break;
6392 : default:
6393 : break;
6394 : }
6395 190263 : if (subcode != ERROR_MARK)
6396 : {
6397 497168 : tree arg0 = gimple_call_arg (stmt, 0);
6398 497168 : tree arg1 = gimple_call_arg (stmt, 1);
6399 497168 : tree arg2 = NULL_TREE;
6400 497168 : tree type = TREE_TYPE (arg0);
6401 497168 : if (cplx_result)
6402 : {
6403 477804 : tree lhs = gimple_call_lhs (stmt);
6404 477804 : if (lhs == NULL_TREE)
6405 : type = NULL_TREE;
6406 : else
6407 477804 : type = TREE_TYPE (TREE_TYPE (lhs));
6408 477804 : if (uaddc_usubc)
6409 33029 : arg2 = gimple_call_arg (stmt, 2);
6410 : }
6411 497168 : if (type == NULL_TREE)
6412 : ;
6413 497168 : else if (uaddc_usubc)
6414 : {
6415 33029 : if (!integer_zerop (arg2))
6416 : ;
6417 : /* x = y + 0 + 0; x = y - 0 - 0; */
6418 5216 : else if (integer_zerop (arg1))
6419 : result = arg0;
6420 : /* x = 0 + y + 0; */
6421 4580 : else if (subcode != MINUS_EXPR && integer_zerop (arg0))
6422 : result = arg1;
6423 : /* x = y - y - 0; */
6424 4580 : else if (subcode == MINUS_EXPR
6425 4580 : && operand_equal_p (arg0, arg1, 0))
6426 0 : result = integer_zero_node;
6427 : }
6428 : /* x = y + 0; x = y - 0; x = y * 0; */
6429 464139 : else if (integer_zerop (arg1))
6430 10103 : result = subcode == MULT_EXPR ? integer_zero_node : arg0;
6431 : /* x = 0 + y; x = 0 * y; */
6432 454036 : else if (subcode != MINUS_EXPR && integer_zerop (arg0))
6433 0 : result = subcode == MULT_EXPR ? integer_zero_node : arg1;
6434 : /* x = y - y; */
6435 454036 : else if (subcode == MINUS_EXPR && operand_equal_p (arg0, arg1, 0))
6436 13 : result = integer_zero_node;
6437 : /* x = y * 1; x = 1 * y; */
6438 454023 : else if (subcode == MULT_EXPR && integer_onep (arg1))
6439 : result = arg0;
6440 448621 : else if (subcode == MULT_EXPR && integer_onep (arg0))
6441 : result = arg1;
6442 497168 : if (result)
6443 : {
6444 16154 : if (result == integer_zero_node)
6445 2148 : result = build_zero_cst (type);
6446 14006 : else if (cplx_result && TREE_TYPE (result) != type)
6447 : {
6448 9706 : if (TREE_CODE (result) == INTEGER_CST)
6449 : {
6450 0 : if (arith_overflowed_p (PLUS_EXPR, type, result,
6451 : integer_zero_node))
6452 0 : overflow = build_one_cst (type);
6453 : }
6454 9706 : else if ((!TYPE_UNSIGNED (TREE_TYPE (result))
6455 6988 : && TYPE_UNSIGNED (type))
6456 9888 : || (TYPE_PRECISION (type)
6457 2900 : < (TYPE_PRECISION (TREE_TYPE (result))
6458 2900 : + (TYPE_UNSIGNED (TREE_TYPE (result))
6459 3293 : && !TYPE_UNSIGNED (type)))))
6460 : result = NULL_TREE;
6461 62 : if (result)
6462 62 : result = fold_convert (type, result);
6463 : }
6464 : }
6465 : }
6466 :
6467 1466798 : if (result)
6468 : {
6469 29021 : if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
6470 0 : result = drop_tree_overflow (result);
6471 29021 : if (cplx_result)
6472 : {
6473 6499 : if (overflow == NULL_TREE)
6474 6499 : overflow = build_zero_cst (TREE_TYPE (result));
6475 6499 : tree ctype = build_complex_type (TREE_TYPE (result));
6476 6499 : if (TREE_CODE (result) == INTEGER_CST
6477 2148 : && TREE_CODE (overflow) == INTEGER_CST)
6478 2148 : result = build_complex (ctype, result, overflow);
6479 : else
6480 4351 : result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
6481 : ctype, result, overflow);
6482 : }
6483 29021 : gimplify_and_update_call_from_tree (gsi, result);
6484 29021 : changed = true;
6485 : }
6486 : }
6487 :
6488 : return changed;
6489 : }
6490 :
6491 :
6492 : /* Return true whether NAME has a use on STMT. Note this can return
6493 : false even though there's a use on STMT if SSA operands are not
6494 : up-to-date. */
6495 :
6496 : static bool
6497 1702 : has_use_on_stmt (tree name, gimple *stmt)
6498 : {
6499 1702 : ssa_op_iter iter;
6500 1702 : tree op;
6501 3440 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
6502 1784 : if (op == name)
6503 : return true;
6504 : return false;
6505 : }
6506 :
6507 : /* Add the lhs of each statement of SEQ to DCE_WORKLIST. */
6508 :
6509 : void
6510 4899450 : mark_lhs_in_seq_for_dce (bitmap dce_worklist, gimple_seq seq)
6511 : {
6512 4899450 : if (!dce_worklist)
6513 : return;
6514 :
6515 1677619 : for (gimple_stmt_iterator i = gsi_start (seq);
6516 1969782 : !gsi_end_p (i); gsi_next (&i))
6517 : {
6518 292163 : gimple *stmt = gsi_stmt (i);
6519 292163 : tree name = gimple_get_lhs (stmt);
6520 292163 : if (name && TREE_CODE (name) == SSA_NAME)
6521 292163 : bitmap_set_bit (dce_worklist, SSA_NAME_VERSION (name));
6522 : }
6523 : }
6524 :
6525 : /* Worker for fold_stmt_1 dispatch to pattern based folding with
6526 : gimple_simplify.
6527 :
6528 : Replaces *GSI with the simplification result in RCODE and OPS
6529 : and the associated statements in *SEQ. Does the replacement
6530 : according to INPLACE and returns true if the operation succeeded. */
6531 :
6532 : static bool
6533 9413029 : replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
6534 : gimple_match_op *res_op,
6535 : gimple_seq *seq, bool inplace,
6536 : bitmap dce_worklist)
6537 : {
6538 9413029 : gimple *stmt = gsi_stmt (*gsi);
6539 9413029 : tree *ops = res_op->ops;
6540 9413029 : unsigned int num_ops = res_op->num_ops;
6541 :
6542 : /* Play safe and do not allow abnormals to be mentioned in
6543 : newly created statements. See also maybe_push_res_to_seq.
6544 : As an exception allow such uses if there was a use of the
6545 : same SSA name on the old stmt. */
6546 20870135 : for (unsigned int i = 0; i < num_ops; ++i)
6547 11458762 : if (TREE_CODE (ops[i]) == SSA_NAME
6548 6941344 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i])
6549 11460464 : && !has_use_on_stmt (ops[i], stmt))
6550 : return false;
6551 :
6552 9411373 : if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
6553 0 : for (unsigned int i = 0; i < 2; ++i)
6554 0 : if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
6555 0 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i))
6556 0 : && !has_use_on_stmt (TREE_OPERAND (ops[0], i), stmt))
6557 : return false;
6558 :
6559 : /* Don't insert new statements when INPLACE is true, even if we could
6560 : reuse STMT for the final statement. */
6561 9411373 : if (inplace && !gimple_seq_empty_p (*seq))
6562 : return false;
6563 :
6564 9411373 : if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
6565 : {
6566 7059259 : gcc_assert (res_op->code.is_tree_code ());
6567 7059259 : auto code = tree_code (res_op->code);
6568 7059259 : if (TREE_CODE_CLASS (code) == tcc_comparison
6569 : /* GIMPLE_CONDs condition may not throw. */
6570 7059259 : && ((cfun
6571 1176894 : && (!flag_exceptions
6572 802451 : || !cfun->can_throw_non_call_exceptions))
6573 570697 : || !operation_could_trap_p (code,
6574 570697 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6575 : false, NULL_TREE)))
6576 1165605 : gimple_cond_set_condition (cond_stmt, code, ops[0], ops[1]);
6577 5893654 : else if (code == SSA_NAME)
6578 : {
6579 : /* If setting the gimple cond to the same thing,
6580 : return false as nothing changed. */
6581 4075878 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6582 4051387 : && operand_equal_p (gimple_cond_lhs (cond_stmt), ops[0])
6583 8124513 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6584 : return false;
6585 27243 : gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
6586 27243 : build_zero_cst (TREE_TYPE (ops[0])));
6587 : }
6588 1817776 : else if (code == INTEGER_CST)
6589 : {
6590 : /* Make into the canonical form `1 != 0` and `0 != 0`.
6591 : If already in the canonical form return false
6592 : saying nothing has been done. */
6593 1266836 : if (integer_zerop (ops[0]))
6594 : {
6595 882036 : if (gimple_cond_false_canonical_p (cond_stmt))
6596 : return false;
6597 519281 : gimple_cond_make_false (cond_stmt);
6598 : }
6599 : else
6600 : {
6601 384800 : if (gimple_cond_true_canonical_p (cond_stmt))
6602 : return false;
6603 208362 : gimple_cond_make_true (cond_stmt);
6604 : }
6605 : }
6606 550940 : else if (!inplace)
6607 : {
6608 : /* For throwing comparisons, see if the GIMPLE_COND is the same as
6609 : the comparison would be.
6610 : This can happen due to the match pattern for
6611 : `(ne (cmp @0 @1) integer_zerop)` which creates a new expression
6612 : for the comparison. */
6613 550940 : if (TREE_CODE_CLASS (code) == tcc_comparison
6614 11289 : && (!cfun
6615 11289 : || (flag_exceptions
6616 11289 : && cfun->can_throw_non_call_exceptions))
6617 562229 : && operation_could_trap_p (code,
6618 11289 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6619 : false, NULL_TREE))
6620 : {
6621 11289 : tree lhs = gimple_cond_lhs (cond_stmt);
6622 11289 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6623 11289 : && TREE_CODE (lhs) == SSA_NAME
6624 11289 : && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6625 22578 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6626 : {
6627 11289 : gimple *s = SSA_NAME_DEF_STMT (lhs);
6628 11289 : if (is_gimple_assign (s)
6629 11289 : && gimple_assign_rhs_code (s) == code
6630 11289 : && operand_equal_p (gimple_assign_rhs1 (s), ops[0])
6631 22578 : && operand_equal_p (gimple_assign_rhs2 (s), ops[1]))
6632 : return false;
6633 : }
6634 : }
6635 539651 : tree res = maybe_push_res_to_seq (res_op, seq);
6636 539651 : if (!res)
6637 : return false;
6638 539651 : gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
6639 539651 : build_zero_cst (TREE_TYPE (res)));
6640 : }
6641 : else
6642 : return false;
6643 2460142 : if (dump_file && (dump_flags & TDF_DETAILS))
6644 : {
6645 865 : fprintf (dump_file, "gimple_simplified to ");
6646 865 : if (!gimple_seq_empty_p (*seq))
6647 0 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6648 865 : print_gimple_stmt (dump_file, gsi_stmt (*gsi),
6649 : 0, TDF_SLIM);
6650 : }
6651 : // Mark the lhs of the new statements maybe for dce
6652 2460142 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6653 2460142 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6654 2460142 : return true;
6655 : }
6656 2352114 : else if (is_gimple_assign (stmt)
6657 2352114 : && res_op->code.is_tree_code ())
6658 : {
6659 2271121 : auto code = tree_code (res_op->code);
6660 2271121 : if (!inplace
6661 2271121 : || gimple_num_ops (stmt) > get_gimple_rhs_num_ops (code))
6662 : {
6663 2271121 : maybe_build_generic_op (res_op);
6664 5352087 : gimple_assign_set_rhs_with_ops (gsi, code,
6665 : res_op->op_or_null (0),
6666 : res_op->op_or_null (1),
6667 : res_op->op_or_null (2));
6668 2271121 : if (dump_file && (dump_flags & TDF_DETAILS))
6669 : {
6670 16828 : fprintf (dump_file, "gimple_simplified to ");
6671 16828 : if (!gimple_seq_empty_p (*seq))
6672 331 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6673 16828 : print_gimple_stmt (dump_file, gsi_stmt (*gsi),
6674 : 0, TDF_SLIM);
6675 : }
6676 : // Mark the lhs of the new statements maybe for dce
6677 2271121 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6678 2271121 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6679 2271121 : return true;
6680 : }
6681 : }
6682 80993 : else if (res_op->code.is_fn_code ()
6683 80993 : && gimple_call_combined_fn (stmt) == combined_fn (res_op->code))
6684 : {
6685 8092 : gcc_assert (num_ops == gimple_call_num_args (stmt));
6686 23944 : for (unsigned int i = 0; i < num_ops; ++i)
6687 15852 : gimple_call_set_arg (stmt, i, ops[i]);
6688 8092 : if (dump_file && (dump_flags & TDF_DETAILS))
6689 : {
6690 0 : fprintf (dump_file, "gimple_simplified to ");
6691 0 : if (!gimple_seq_empty_p (*seq))
6692 0 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6693 0 : print_gimple_stmt (dump_file, gsi_stmt (*gsi), 0, TDF_SLIM);
6694 : }
6695 : // Mark the lhs of the new statements maybe for dce
6696 8092 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6697 8092 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6698 8092 : return true;
6699 : }
6700 72901 : else if (!inplace)
6701 : {
6702 143774 : if (gimple_has_lhs (stmt))
6703 : {
6704 72901 : tree lhs = gimple_get_lhs (stmt);
6705 72901 : if (!maybe_push_res_to_seq (res_op, seq, lhs))
6706 : return false;
6707 71918 : if (dump_file && (dump_flags & TDF_DETAILS))
6708 : {
6709 10 : fprintf (dump_file, "gimple_simplified to ");
6710 10 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6711 : }
6712 : // Mark the lhs of the new statements maybe for dce
6713 71918 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6714 71918 : gsi_replace_with_seq_vops (gsi, *seq);
6715 71918 : return true;
6716 : }
6717 : else
6718 0 : gcc_unreachable ();
6719 : }
6720 :
6721 : return false;
6722 : }
6723 :
6724 : /* Canonicalize MEM_REFs invariant address operand after propagation. */
6725 :
6726 : static bool
6727 199611585 : maybe_canonicalize_mem_ref_addr (tree *t, bool is_debug = false)
6728 : {
6729 199611585 : bool res = false;
6730 199611585 : tree *orig_t = t;
6731 :
6732 199611585 : if (TREE_CODE (*t) == ADDR_EXPR)
6733 68308824 : t = &TREE_OPERAND (*t, 0);
6734 :
6735 : /* The C and C++ frontends use an ARRAY_REF for indexing with their
6736 : generic vector extension. The actual vector referenced is
6737 : view-converted to an array type for this purpose. If the index
6738 : is constant the canonical representation in the middle-end is a
6739 : BIT_FIELD_REF so re-write the former to the latter here. */
6740 199611585 : if (TREE_CODE (*t) == ARRAY_REF
6741 11090158 : && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
6742 174897 : && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
6743 199665407 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
6744 : {
6745 24285 : tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
6746 24285 : if (VECTOR_TYPE_P (vtype))
6747 : {
6748 24285 : tree low = array_ref_low_bound (*t);
6749 24285 : if (TREE_CODE (low) == INTEGER_CST)
6750 : {
6751 24285 : if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
6752 : {
6753 48510 : widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
6754 48510 : wi::to_widest (low));
6755 24255 : idx = wi::mul (idx, wi::to_widest
6756 48510 : (TYPE_SIZE (TREE_TYPE (*t))));
6757 24255 : widest_int ext
6758 24255 : = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
6759 24255 : if (maybe_le (ext, wi::to_poly_widest (TYPE_SIZE (vtype))))
6760 : {
6761 47358 : *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
6762 23679 : TREE_TYPE (*t),
6763 23679 : TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
6764 23679 : TYPE_SIZE (TREE_TYPE (*t)),
6765 23679 : wide_int_to_tree (bitsizetype, idx));
6766 23679 : res = true;
6767 : }
6768 24255 : }
6769 : }
6770 : }
6771 : }
6772 :
6773 376191918 : while (handled_component_p (*t))
6774 176580333 : t = &TREE_OPERAND (*t, 0);
6775 :
6776 : /* Canonicalize MEM [&foo.bar, 0] which appears after propagating
6777 : of invariant addresses into a SSA name MEM_REF address. */
6778 199611585 : if (TREE_CODE (*t) == MEM_REF
6779 199611585 : || TREE_CODE (*t) == TARGET_MEM_REF)
6780 : {
6781 105116402 : tree addr = TREE_OPERAND (*t, 0);
6782 105116402 : if (TREE_CODE (addr) == ADDR_EXPR
6783 105116402 : && (TREE_CODE (TREE_OPERAND (addr, 0)) == MEM_REF
6784 32040658 : || handled_component_p (TREE_OPERAND (addr, 0))))
6785 : {
6786 567410 : tree base;
6787 567410 : poly_int64 coffset;
6788 567410 : base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
6789 : &coffset);
6790 567410 : if (!base)
6791 : {
6792 18 : if (is_debug)
6793 18 : return false;
6794 0 : gcc_unreachable ();
6795 : }
6796 :
6797 567392 : TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
6798 567392 : TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
6799 567392 : TREE_OPERAND (*t, 1),
6800 567392 : size_int (coffset));
6801 567392 : res = true;
6802 : }
6803 105116384 : gcc_checking_assert (TREE_CODE (TREE_OPERAND (*t, 0)) == DEBUG_EXPR_DECL
6804 : || is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)));
6805 : }
6806 :
6807 : /* Canonicalize back MEM_REFs to plain reference trees if the object
6808 : accessed is a decl that has the same access semantics as the MEM_REF. */
6809 199611567 : if (TREE_CODE (*t) == MEM_REF
6810 103124176 : && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
6811 31726930 : && integer_zerop (TREE_OPERAND (*t, 1))
6812 216859497 : && MR_DEPENDENCE_CLIQUE (*t) == 0)
6813 : {
6814 12217738 : tree decl = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6815 12217738 : tree alias_type = TREE_TYPE (TREE_OPERAND (*t, 1));
6816 12217738 : if (/* Same volatile qualification. */
6817 12217738 : TREE_THIS_VOLATILE (*t) == TREE_THIS_VOLATILE (decl)
6818 : /* Same TBAA behavior with -fstrict-aliasing. */
6819 12214718 : && !TYPE_REF_CAN_ALIAS_ALL (alias_type)
6820 11863214 : && (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
6821 11863214 : == TYPE_MAIN_VARIANT (TREE_TYPE (alias_type)))
6822 : /* Same alignment. */
6823 4893909 : && TYPE_ALIGN (TREE_TYPE (decl)) == TYPE_ALIGN (TREE_TYPE (*t))
6824 : /* We have to look out here to not drop a required conversion
6825 : from the rhs to the lhs if *t appears on the lhs or vice-versa
6826 : if it appears on the rhs. Thus require strict type
6827 : compatibility. */
6828 16822373 : && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (decl)))
6829 : {
6830 2557733 : *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6831 2557733 : res = true;
6832 : }
6833 : }
6834 :
6835 187393829 : else if (TREE_CODE (*orig_t) == ADDR_EXPR
6836 65461790 : && TREE_CODE (*t) == MEM_REF
6837 209963813 : && TREE_CODE (TREE_OPERAND (*t, 0)) == INTEGER_CST)
6838 : {
6839 867 : tree base;
6840 867 : poly_int64 coffset;
6841 867 : base = get_addr_base_and_unit_offset (TREE_OPERAND (*orig_t, 0),
6842 : &coffset);
6843 867 : if (base)
6844 : {
6845 763 : gcc_assert (TREE_CODE (base) == MEM_REF);
6846 763 : poly_int64 moffset;
6847 763 : if (mem_ref_offset (base).to_shwi (&moffset))
6848 : {
6849 763 : coffset += moffset;
6850 763 : if (wi::to_poly_wide (TREE_OPERAND (base, 0)).to_shwi (&moffset))
6851 : {
6852 763 : coffset += moffset;
6853 763 : *orig_t = build_int_cst (TREE_TYPE (*orig_t), coffset);
6854 763 : return true;
6855 : }
6856 : }
6857 : }
6858 : }
6859 :
6860 : /* Canonicalize TARGET_MEM_REF in particular with respect to
6861 : the indexes becoming constant. */
6862 187392962 : else if (TREE_CODE (*t) == TARGET_MEM_REF)
6863 : {
6864 1992208 : tree tem = maybe_fold_tmr (*t);
6865 1992208 : if (tem)
6866 : {
6867 4311 : *t = tem;
6868 4311 : if (TREE_CODE (*orig_t) == ADDR_EXPR)
6869 0 : recompute_tree_invariant_for_addr_expr (*orig_t);
6870 : res = true;
6871 : }
6872 : }
6873 :
6874 : return res;
6875 : }
6876 :
6877 : /* Worker for both fold_stmt and fold_stmt_inplace. The INPLACE argument
6878 : distinguishes both cases. */
6879 :
6880 : static bool
6881 812534400 : fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree),
6882 : bitmap dce_worklist = nullptr)
6883 : {
6884 812534400 : bool changed = false;
6885 812534400 : gimple *stmt = gsi_stmt (*gsi);
6886 812534400 : unsigned i;
6887 :
6888 : /* First do required canonicalization of [TARGET_]MEM_REF addresses
6889 : after propagation.
6890 : ??? This shouldn't be done in generic folding but in the
6891 : propagation helpers which also know whether an address was
6892 : propagated.
6893 : Also canonicalize operand order. */
6894 812534400 : switch (gimple_code (stmt))
6895 : {
6896 263062369 : case GIMPLE_ASSIGN:
6897 263062369 : if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
6898 : {
6899 173628298 : tree *rhs = gimple_assign_rhs1_ptr (stmt);
6900 173628298 : if ((REFERENCE_CLASS_P (*rhs)
6901 109731912 : || TREE_CODE (*rhs) == ADDR_EXPR)
6902 189015518 : && maybe_canonicalize_mem_ref_addr (rhs))
6903 : changed = true;
6904 173628298 : tree *lhs = gimple_assign_lhs_ptr (stmt);
6905 173628298 : if (REFERENCE_CLASS_P (*lhs)
6906 173628298 : && maybe_canonicalize_mem_ref_addr (lhs))
6907 : changed = true;
6908 : /* Canonicalize &MEM[ssa_n, CST] to ssa_n p+ CST.
6909 : This cannot be done in maybe_canonicalize_mem_ref_addr
6910 : as the gimple now has two operands rather than one.
6911 : The same reason why this can't be done in
6912 : maybe_canonicalize_mem_ref_addr is the same reason why
6913 : this can't be done inplace. */
6914 173628298 : if (!inplace && TREE_CODE (*rhs) == ADDR_EXPR)
6915 : {
6916 15180000 : tree inner = TREE_OPERAND (*rhs, 0);
6917 15180000 : if (TREE_CODE (inner) == MEM_REF
6918 1067021 : && TREE_CODE (TREE_OPERAND (inner, 0)) == SSA_NAME
6919 15244894 : && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6920 : {
6921 64894 : tree ptr = TREE_OPERAND (inner, 0);
6922 64894 : tree addon = TREE_OPERAND (inner, 1);
6923 64894 : addon = fold_convert (sizetype, addon);
6924 64894 : gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR,
6925 : ptr, addon);
6926 64894 : changed = true;
6927 64894 : stmt = gsi_stmt (*gsi);
6928 : }
6929 : }
6930 : }
6931 : else
6932 : {
6933 : /* Canonicalize operand order. */
6934 89434071 : enum tree_code code = gimple_assign_rhs_code (stmt);
6935 89434071 : if (TREE_CODE_CLASS (code) == tcc_comparison
6936 83048971 : || commutative_tree_code (code)
6937 134561126 : || commutative_ternary_tree_code (code))
6938 : {
6939 44308000 : tree rhs1 = gimple_assign_rhs1 (stmt);
6940 44308000 : tree rhs2 = gimple_assign_rhs2 (stmt);
6941 44308000 : if (tree_swap_operands_p (rhs1, rhs2))
6942 : {
6943 2635249 : gimple_assign_set_rhs1 (stmt, rhs2);
6944 2635249 : gimple_assign_set_rhs2 (stmt, rhs1);
6945 2635249 : if (TREE_CODE_CLASS (code) == tcc_comparison)
6946 323820 : gimple_assign_set_rhs_code (stmt,
6947 : swap_tree_comparison (code));
6948 : changed = true;
6949 : }
6950 : }
6951 : }
6952 : break;
6953 58127008 : case GIMPLE_CALL:
6954 58127008 : {
6955 58127008 : gcall *call = as_a<gcall *> (stmt);
6956 232464414 : for (i = 0; i < gimple_call_num_args (call); ++i)
6957 : {
6958 116210398 : tree *arg = gimple_call_arg_ptr (call, i);
6959 116210398 : if (REFERENCE_CLASS_P (*arg)
6960 116210398 : && maybe_canonicalize_mem_ref_addr (arg))
6961 : changed = true;
6962 : }
6963 58127008 : tree *lhs = gimple_call_lhs_ptr (call);
6964 58127008 : if (*lhs
6965 23501826 : && REFERENCE_CLASS_P (*lhs)
6966 58249121 : && maybe_canonicalize_mem_ref_addr (lhs))
6967 : changed = true;
6968 58127008 : if (*lhs)
6969 : {
6970 23501826 : combined_fn cfn = gimple_call_combined_fn (call);
6971 23501826 : internal_fn ifn = associated_internal_fn (cfn, TREE_TYPE (*lhs));
6972 23501826 : int opno = first_commutative_argument (ifn);
6973 23501826 : if (opno >= 0)
6974 : {
6975 358216 : tree arg1 = gimple_call_arg (call, opno);
6976 358216 : tree arg2 = gimple_call_arg (call, opno + 1);
6977 358216 : if (tree_swap_operands_p (arg1, arg2))
6978 : {
6979 22651 : gimple_call_set_arg (call, opno, arg2);
6980 22651 : gimple_call_set_arg (call, opno + 1, arg1);
6981 22651 : changed = true;
6982 : }
6983 : }
6984 : }
6985 : break;
6986 : }
6987 548974 : case GIMPLE_ASM:
6988 548974 : {
6989 548974 : gasm *asm_stmt = as_a <gasm *> (stmt);
6990 1778225 : for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
6991 : {
6992 680277 : tree link = gimple_asm_output_op (asm_stmt, i);
6993 680277 : tree op = TREE_VALUE (link);
6994 680277 : if (REFERENCE_CLASS_P (op)
6995 680277 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
6996 : changed = true;
6997 : }
6998 980085 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
6999 : {
7000 431111 : tree link = gimple_asm_input_op (asm_stmt, i);
7001 431111 : tree op = TREE_VALUE (link);
7002 431111 : if ((REFERENCE_CLASS_P (op)
7003 402868 : || TREE_CODE (op) == ADDR_EXPR)
7004 466629 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
7005 : changed = true;
7006 : }
7007 : }
7008 : break;
7009 423639348 : case GIMPLE_DEBUG:
7010 423639348 : if (gimple_debug_bind_p (stmt))
7011 : {
7012 328053033 : tree *val = gimple_debug_bind_get_value_ptr (stmt);
7013 328053033 : if (*val
7014 187478955 : && (REFERENCE_CLASS_P (*val)
7015 184751477 : || TREE_CODE (*val) == ADDR_EXPR)
7016 383666597 : && maybe_canonicalize_mem_ref_addr (val, true))
7017 : changed = true;
7018 : }
7019 : break;
7020 46160133 : case GIMPLE_COND:
7021 46160133 : {
7022 : /* Canonicalize operand order. */
7023 46160133 : tree lhs = gimple_cond_lhs (stmt);
7024 46160133 : tree rhs = gimple_cond_rhs (stmt);
7025 46160133 : if (tree_swap_operands_p (lhs, rhs))
7026 : {
7027 1445448 : gcond *gc = as_a <gcond *> (stmt);
7028 1445448 : gimple_cond_set_lhs (gc, rhs);
7029 1445448 : gimple_cond_set_rhs (gc, lhs);
7030 1445448 : gimple_cond_set_code (gc,
7031 : swap_tree_comparison (gimple_cond_code (gc)));
7032 1445448 : changed = true;
7033 : }
7034 : }
7035 810974162 : default:;
7036 : }
7037 :
7038 : /* Dispatch to pattern-based folding. */
7039 810974162 : if (!inplace
7040 3280479 : || is_gimple_assign (stmt)
7041 811907087 : || gimple_code (stmt) == GIMPLE_COND)
7042 : {
7043 811601475 : gimple_seq seq = NULL;
7044 811601475 : gimple_match_op res_op;
7045 1620855396 : if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
7046 : valueize, valueize)
7047 811601475 : && replace_stmt_with_simplification (gsi, &res_op, &seq, inplace,
7048 : dce_worklist))
7049 : changed = true;
7050 : else
7051 806790202 : gimple_seq_discard (seq);
7052 : }
7053 :
7054 812534400 : stmt = gsi_stmt (*gsi);
7055 :
7056 : /* Fold the main computation performed by the statement. */
7057 812534400 : switch (gimple_code (stmt))
7058 : {
7059 263121315 : case GIMPLE_ASSIGN:
7060 263121315 : {
7061 : /* Try to canonicalize for boolean-typed X the comparisons
7062 : X == 0, X == 1, X != 0, and X != 1. */
7063 263121315 : if (gimple_assign_rhs_code (stmt) == EQ_EXPR
7064 263121315 : || gimple_assign_rhs_code (stmt) == NE_EXPR)
7065 : {
7066 3544456 : tree lhs = gimple_assign_lhs (stmt);
7067 3544456 : tree op1 = gimple_assign_rhs1 (stmt);
7068 3544456 : tree op2 = gimple_assign_rhs2 (stmt);
7069 3544456 : tree type = TREE_TYPE (op1);
7070 :
7071 : /* Check whether the comparison operands are of the same boolean
7072 : type as the result type is.
7073 : Check that second operand is an integer-constant with value
7074 : one or zero. */
7075 3544456 : if (TREE_CODE (op2) == INTEGER_CST
7076 2434699 : && (integer_zerop (op2) || integer_onep (op2))
7077 5350109 : && useless_type_conversion_p (TREE_TYPE (lhs), type))
7078 : {
7079 4969 : enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
7080 4969 : bool is_logical_not = false;
7081 :
7082 : /* X == 0 and X != 1 is a logical-not.of X
7083 : X == 1 and X != 0 is X */
7084 4166 : if ((cmp_code == EQ_EXPR && integer_zerop (op2))
7085 4969 : || (cmp_code == NE_EXPR && integer_onep (op2)))
7086 4912 : is_logical_not = true;
7087 :
7088 4969 : if (is_logical_not == false)
7089 57 : gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1);
7090 : /* Only for one-bit precision typed X the transformation
7091 : !X -> ~X is valid. */
7092 4912 : else if (TYPE_PRECISION (type) == 1)
7093 4912 : gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1);
7094 : /* Otherwise we use !X -> X ^ 1. */
7095 : else
7096 0 : gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1,
7097 : build_int_cst (type, 1));
7098 : changed = true;
7099 : break;
7100 : }
7101 : }
7102 :
7103 263116346 : unsigned old_num_ops = gimple_num_ops (stmt);
7104 263116346 : tree lhs = gimple_assign_lhs (stmt);
7105 263116346 : tree new_rhs = fold_gimple_assign (gsi);
7106 263116346 : if (new_rhs
7107 263236946 : && !useless_type_conversion_p (TREE_TYPE (lhs),
7108 120600 : TREE_TYPE (new_rhs)))
7109 0 : new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
7110 263116346 : if (new_rhs
7111 263116346 : && (!inplace
7112 1024 : || get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
7113 : {
7114 120600 : gimple_assign_set_rhs_from_tree (gsi, new_rhs);
7115 120600 : changed = true;
7116 : }
7117 : break;
7118 : }
7119 :
7120 58068062 : case GIMPLE_CALL:
7121 58068062 : changed |= gimple_fold_call (gsi, inplace);
7122 58068062 : break;
7123 :
7124 423639348 : case GIMPLE_DEBUG:
7125 423639348 : if (gimple_debug_bind_p (stmt))
7126 : {
7127 328053033 : tree val = gimple_debug_bind_get_value (stmt);
7128 328053033 : if (val && REFERENCE_CLASS_P (val))
7129 : {
7130 2725512 : tree tem = maybe_fold_reference (val);
7131 2725512 : if (tem)
7132 : {
7133 4409 : gimple_debug_bind_set_value (stmt, tem);
7134 4409 : changed = true;
7135 : }
7136 : }
7137 : }
7138 : break;
7139 :
7140 11048208 : case GIMPLE_RETURN:
7141 11048208 : {
7142 11048208 : greturn *ret_stmt = as_a<greturn *> (stmt);
7143 11048208 : tree ret = gimple_return_retval(ret_stmt);
7144 :
7145 11048208 : if (ret && TREE_CODE (ret) == SSA_NAME && valueize)
7146 : {
7147 4639462 : tree val = valueize (ret);
7148 4639462 : if (val && val != ret
7149 4639462 : && may_propagate_copy (ret, val))
7150 : {
7151 0 : gimple_return_set_retval (ret_stmt, val);
7152 0 : changed = true;
7153 : }
7154 : }
7155 : }
7156 : break;
7157 :
7158 812534400 : default:;
7159 : }
7160 :
7161 812534400 : return changed;
7162 : }
7163 :
7164 : /* Valueziation callback that ends up not following SSA edges. */
7165 :
7166 : tree
7167 6414564928 : no_follow_ssa_edges (tree)
7168 : {
7169 6414564928 : return NULL_TREE;
7170 : }
7171 :
7172 : /* Valueization callback that ends up following single-use SSA edges only. */
7173 :
7174 : tree
7175 978460635 : follow_single_use_edges (tree val)
7176 : {
7177 978460635 : if (TREE_CODE (val) == SSA_NAME
7178 978460635 : && !has_single_use (val))
7179 500899857 : return NULL_TREE;
7180 : return val;
7181 : }
7182 :
7183 : /* Valueization callback that follows all SSA edges. */
7184 :
7185 : tree
7186 224574302 : follow_all_ssa_edges (tree val)
7187 : {
7188 224574302 : return val;
7189 : }
7190 :
7191 : /* Fold the statement pointed to by GSI. In some cases, this function may
7192 : replace the whole statement with a new one. Returns true iff folding
7193 : makes any changes.
7194 : The statement pointed to by GSI should be in valid gimple form but may
7195 : be in unfolded state as resulting from for example constant propagation
7196 : which can produce *&x = 0. */
7197 :
7198 : bool
7199 162169778 : fold_stmt (gimple_stmt_iterator *gsi, bitmap dce_bitmap)
7200 : {
7201 162169778 : return fold_stmt_1 (gsi, false, no_follow_ssa_edges, dce_bitmap);
7202 : }
7203 :
7204 : bool
7205 647084143 : fold_stmt (gimple_stmt_iterator *gsi, tree (*valueize) (tree), bitmap dce_bitmap)
7206 : {
7207 647084143 : return fold_stmt_1 (gsi, false, valueize, dce_bitmap);
7208 : }
7209 :
7210 : /* Perform the minimal folding on statement *GSI. Only operations like
7211 : *&x created by constant propagation are handled. The statement cannot
7212 : be replaced with a new one. Return true if the statement was
7213 : changed, false otherwise.
7214 : The statement *GSI should be in valid gimple form but may
7215 : be in unfolded state as resulting from for example constant propagation
7216 : which can produce *&x = 0. */
7217 :
7218 : bool
7219 3280479 : fold_stmt_inplace (gimple_stmt_iterator *gsi, tree (*valueize) (tree))
7220 : {
7221 3280479 : gimple *stmt = gsi_stmt (*gsi);
7222 3280479 : bool changed = fold_stmt_1 (gsi, true, valueize);
7223 3280479 : gcc_assert (gsi_stmt (*gsi) == stmt);
7224 3280479 : return changed;
7225 : }
7226 :
7227 : /* Canonicalize and possibly invert the boolean EXPR; return NULL_TREE
7228 : if EXPR is null or we don't know how.
7229 : If non-null, the result always has boolean type. */
7230 :
7231 : static tree
7232 428009 : canonicalize_bool (tree expr, bool invert)
7233 : {
7234 428009 : if (!expr)
7235 : return NULL_TREE;
7236 54 : else if (invert)
7237 : {
7238 35 : if (integer_nonzerop (expr))
7239 0 : return boolean_false_node;
7240 35 : else if (integer_zerop (expr))
7241 0 : return boolean_true_node;
7242 35 : else if (TREE_CODE (expr) == SSA_NAME)
7243 0 : return fold_build2 (EQ_EXPR, boolean_type_node, expr,
7244 : build_int_cst (TREE_TYPE (expr), 0));
7245 35 : else if (COMPARISON_CLASS_P (expr))
7246 35 : return fold_build2 (invert_tree_comparison (TREE_CODE (expr), false),
7247 : boolean_type_node,
7248 : TREE_OPERAND (expr, 0),
7249 : TREE_OPERAND (expr, 1));
7250 : else
7251 : return NULL_TREE;
7252 : }
7253 : else
7254 : {
7255 19 : if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
7256 : return expr;
7257 0 : if (integer_nonzerop (expr))
7258 0 : return boolean_true_node;
7259 0 : else if (integer_zerop (expr))
7260 0 : return boolean_false_node;
7261 0 : else if (TREE_CODE (expr) == SSA_NAME)
7262 0 : return fold_build2 (NE_EXPR, boolean_type_node, expr,
7263 : build_int_cst (TREE_TYPE (expr), 0));
7264 0 : else if (COMPARISON_CLASS_P (expr))
7265 0 : return fold_build2 (TREE_CODE (expr),
7266 : boolean_type_node,
7267 : TREE_OPERAND (expr, 0),
7268 : TREE_OPERAND (expr, 1));
7269 : else
7270 : return NULL_TREE;
7271 : }
7272 : }
7273 :
7274 : /* Check to see if a boolean expression EXPR is logically equivalent to the
7275 : comparison (OP1 CODE OP2). Check for various identities involving
7276 : SSA_NAMEs. */
7277 :
7278 : static bool
7279 1528 : same_bool_comparison_p (const_tree expr, enum tree_code code,
7280 : const_tree op1, const_tree op2)
7281 : {
7282 1528 : gimple *s;
7283 :
7284 : /* The obvious case. */
7285 1528 : if (TREE_CODE (expr) == code
7286 33 : && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
7287 1561 : && operand_equal_p (TREE_OPERAND (expr, 1), op2, 0))
7288 : return true;
7289 :
7290 : /* Check for comparing (name, name != 0) and the case where expr
7291 : is an SSA_NAME with a definition matching the comparison. */
7292 1511 : if (TREE_CODE (expr) == SSA_NAME
7293 1511 : && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
7294 : {
7295 0 : if (operand_equal_p (expr, op1, 0))
7296 0 : return ((code == NE_EXPR && integer_zerop (op2))
7297 0 : || (code == EQ_EXPR && integer_nonzerop (op2)));
7298 0 : s = SSA_NAME_DEF_STMT (expr);
7299 0 : if (is_gimple_assign (s)
7300 0 : && gimple_assign_rhs_code (s) == code
7301 0 : && operand_equal_p (gimple_assign_rhs1 (s), op1, 0)
7302 0 : && operand_equal_p (gimple_assign_rhs2 (s), op2, 0))
7303 : return true;
7304 : }
7305 :
7306 : /* If op1 is of the form (name != 0) or (name == 0), and the definition
7307 : of name is a comparison, recurse. */
7308 1511 : if (TREE_CODE (op1) == SSA_NAME
7309 1511 : && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
7310 : {
7311 460 : s = SSA_NAME_DEF_STMT (op1);
7312 460 : if (is_gimple_assign (s)
7313 460 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
7314 : {
7315 0 : enum tree_code c = gimple_assign_rhs_code (s);
7316 0 : if ((c == NE_EXPR && integer_zerop (op2))
7317 0 : || (c == EQ_EXPR && integer_nonzerop (op2)))
7318 0 : return same_bool_comparison_p (expr, c,
7319 0 : gimple_assign_rhs1 (s),
7320 0 : gimple_assign_rhs2 (s));
7321 0 : if ((c == EQ_EXPR && integer_zerop (op2))
7322 0 : || (c == NE_EXPR && integer_nonzerop (op2)))
7323 0 : return same_bool_comparison_p (expr,
7324 : invert_tree_comparison (c, false),
7325 0 : gimple_assign_rhs1 (s),
7326 0 : gimple_assign_rhs2 (s));
7327 : }
7328 : }
7329 : return false;
7330 : }
7331 :
7332 : /* Check to see if two boolean expressions OP1 and OP2 are logically
7333 : equivalent. */
7334 :
7335 : static bool
7336 15 : same_bool_result_p (const_tree op1, const_tree op2)
7337 : {
7338 : /* Simple cases first. */
7339 15 : if (operand_equal_p (op1, op2, 0))
7340 : return true;
7341 :
7342 : /* Check the cases where at least one of the operands is a comparison.
7343 : These are a bit smarter than operand_equal_p in that they apply some
7344 : identifies on SSA_NAMEs. */
7345 8 : if (COMPARISON_CLASS_P (op2)
7346 16 : && same_bool_comparison_p (op1, TREE_CODE (op2),
7347 8 : TREE_OPERAND (op2, 0),
7348 8 : TREE_OPERAND (op2, 1)))
7349 : return true;
7350 8 : if (COMPARISON_CLASS_P (op1)
7351 16 : && same_bool_comparison_p (op2, TREE_CODE (op1),
7352 8 : TREE_OPERAND (op1, 0),
7353 8 : TREE_OPERAND (op1, 1)))
7354 : return true;
7355 :
7356 : /* Default case. */
7357 : return false;
7358 : }
7359 :
7360 : /* Forward declarations for some mutually recursive functions. */
7361 :
7362 : static tree
7363 : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
7364 : enum tree_code code2, tree op2a, tree op2b, basic_block);
7365 : static tree
7366 : and_var_with_comparison (tree type, tree var, bool invert,
7367 : enum tree_code code2, tree op2a, tree op2b,
7368 : basic_block);
7369 : static tree
7370 : and_var_with_comparison_1 (tree type, gimple *stmt,
7371 : enum tree_code code2, tree op2a, tree op2b,
7372 : basic_block);
7373 : static tree
7374 : or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
7375 : enum tree_code code2, tree op2a, tree op2b,
7376 : basic_block);
7377 : static tree
7378 : or_var_with_comparison (tree, tree var, bool invert,
7379 : enum tree_code code2, tree op2a, tree op2b,
7380 : basic_block);
7381 : static tree
7382 : or_var_with_comparison_1 (tree, gimple *stmt,
7383 : enum tree_code code2, tree op2a, tree op2b,
7384 : basic_block);
7385 :
7386 : /* Helper function for and_comparisons_1: try to simplify the AND of the
7387 : ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
7388 : If INVERT is true, invert the value of the VAR before doing the AND.
7389 : Return NULL_EXPR if we can't simplify this to a single expression. */
7390 :
7391 : static tree
7392 365237 : and_var_with_comparison (tree type, tree var, bool invert,
7393 : enum tree_code code2, tree op2a, tree op2b,
7394 : basic_block outer_cond_bb)
7395 : {
7396 365237 : tree t;
7397 365237 : gimple *stmt = SSA_NAME_DEF_STMT (var);
7398 :
7399 : /* We can only deal with variables whose definitions are assignments. */
7400 365237 : if (!is_gimple_assign (stmt))
7401 : return NULL_TREE;
7402 :
7403 : /* If we have an inverted comparison, apply DeMorgan's law and rewrite
7404 : !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
7405 : Then we only have to consider the simpler non-inverted cases. */
7406 364683 : if (invert)
7407 125184 : t = or_var_with_comparison_1 (type, stmt,
7408 : invert_tree_comparison (code2, false),
7409 : op2a, op2b, outer_cond_bb);
7410 : else
7411 239499 : t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
7412 : outer_cond_bb);
7413 364683 : return canonicalize_bool (t, invert);
7414 : }
7415 :
7416 : /* Try to simplify the AND of the ssa variable defined by the assignment
7417 : STMT with the comparison specified by (OP2A CODE2 OP2B).
7418 : Return NULL_EXPR if we can't simplify this to a single expression. */
7419 :
7420 : static tree
7421 263822 : and_var_with_comparison_1 (tree type, gimple *stmt,
7422 : enum tree_code code2, tree op2a, tree op2b,
7423 : basic_block outer_cond_bb)
7424 : {
7425 263822 : tree var = gimple_assign_lhs (stmt);
7426 263822 : tree true_test_var = NULL_TREE;
7427 263822 : tree false_test_var = NULL_TREE;
7428 263822 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
7429 :
7430 : /* Check for identities like (var AND (var == 0)) => false. */
7431 263822 : if (TREE_CODE (op2a) == SSA_NAME
7432 263822 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
7433 : {
7434 14060 : if ((code2 == NE_EXPR && integer_zerop (op2b))
7435 37639 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
7436 : {
7437 14344 : true_test_var = op2a;
7438 14344 : if (var == true_test_var)
7439 : return var;
7440 : }
7441 6035 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
7442 24122 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
7443 : {
7444 4041 : false_test_var = op2a;
7445 4041 : if (var == false_test_var)
7446 0 : return boolean_false_node;
7447 : }
7448 : }
7449 :
7450 : /* If the definition is a comparison, recurse on it. */
7451 263822 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
7452 : {
7453 1970 : tree t = and_comparisons_1 (type, innercode,
7454 : gimple_assign_rhs1 (stmt),
7455 : gimple_assign_rhs2 (stmt),
7456 : code2,
7457 : op2a,
7458 : op2b, outer_cond_bb);
7459 1970 : if (t)
7460 : return t;
7461 : }
7462 :
7463 : /* If the definition is an AND or OR expression, we may be able to
7464 : simplify by reassociating. */
7465 263816 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
7466 263816 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
7467 : {
7468 26736 : tree inner1 = gimple_assign_rhs1 (stmt);
7469 26736 : tree inner2 = gimple_assign_rhs2 (stmt);
7470 26736 : gimple *s;
7471 26736 : tree t;
7472 26736 : tree partial = NULL_TREE;
7473 26736 : bool is_and = (innercode == BIT_AND_EXPR);
7474 :
7475 : /* Check for boolean identities that don't require recursive examination
7476 : of inner1/inner2:
7477 : inner1 AND (inner1 AND inner2) => inner1 AND inner2 => var
7478 : inner1 AND (inner1 OR inner2) => inner1
7479 : !inner1 AND (inner1 AND inner2) => false
7480 : !inner1 AND (inner1 OR inner2) => !inner1 AND inner2
7481 : Likewise for similar cases involving inner2. */
7482 26736 : if (inner1 == true_test_var)
7483 0 : return (is_and ? var : inner1);
7484 26736 : else if (inner2 == true_test_var)
7485 0 : return (is_and ? var : inner2);
7486 26736 : else if (inner1 == false_test_var)
7487 0 : return (is_and
7488 0 : ? boolean_false_node
7489 0 : : and_var_with_comparison (type, inner2, false, code2, op2a,
7490 0 : op2b, outer_cond_bb));
7491 26736 : else if (inner2 == false_test_var)
7492 0 : return (is_and
7493 0 : ? boolean_false_node
7494 0 : : and_var_with_comparison (type, inner1, false, code2, op2a,
7495 0 : op2b, outer_cond_bb));
7496 :
7497 : /* Next, redistribute/reassociate the AND across the inner tests.
7498 : Compute the first partial result, (inner1 AND (op2a code op2b)) */
7499 26736 : if (TREE_CODE (inner1) == SSA_NAME
7500 26736 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
7501 25762 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7502 50770 : && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
7503 : gimple_assign_rhs1 (s),
7504 : gimple_assign_rhs2 (s),
7505 : code2, op2a, op2b,
7506 : outer_cond_bb)))
7507 : {
7508 : /* Handle the AND case, where we are reassociating:
7509 : (inner1 AND inner2) AND (op2a code2 op2b)
7510 : => (t AND inner2)
7511 : If the partial result t is a constant, we win. Otherwise
7512 : continue on to try reassociating with the other inner test. */
7513 33 : if (is_and)
7514 : {
7515 3 : if (integer_onep (t))
7516 : return inner2;
7517 3 : else if (integer_zerop (t))
7518 0 : return boolean_false_node;
7519 : }
7520 :
7521 : /* Handle the OR case, where we are redistributing:
7522 : (inner1 OR inner2) AND (op2a code2 op2b)
7523 : => (t OR (inner2 AND (op2a code2 op2b))) */
7524 30 : else if (integer_onep (t))
7525 0 : return boolean_true_node;
7526 :
7527 : /* Save partial result for later. */
7528 : partial = t;
7529 : }
7530 :
7531 : /* Compute the second partial result, (inner2 AND (op2a code op2b)) */
7532 26736 : if (TREE_CODE (inner2) == SSA_NAME
7533 26736 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
7534 26276 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7535 51084 : && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
7536 : gimple_assign_rhs1 (s),
7537 : gimple_assign_rhs2 (s),
7538 : code2, op2a, op2b,
7539 : outer_cond_bb)))
7540 : {
7541 : /* Handle the AND case, where we are reassociating:
7542 : (inner1 AND inner2) AND (op2a code2 op2b)
7543 : => (inner1 AND t) */
7544 874 : if (is_and)
7545 : {
7546 22 : if (integer_onep (t))
7547 : return inner1;
7548 22 : else if (integer_zerop (t))
7549 1 : return boolean_false_node;
7550 : /* If both are the same, we can apply the identity
7551 : (x AND x) == x. */
7552 21 : else if (partial && same_bool_result_p (t, partial))
7553 0 : return t;
7554 : }
7555 :
7556 : /* Handle the OR case. where we are redistributing:
7557 : (inner1 OR inner2) AND (op2a code2 op2b)
7558 : => (t OR (inner1 AND (op2a code2 op2b)))
7559 : => (t OR partial) */
7560 : else
7561 : {
7562 852 : if (integer_onep (t))
7563 0 : return boolean_true_node;
7564 852 : else if (partial)
7565 : {
7566 : /* We already got a simplification for the other
7567 : operand to the redistributed OR expression. The
7568 : interesting case is when at least one is false.
7569 : Or, if both are the same, we can apply the identity
7570 : (x OR x) == x. */
7571 11 : if (integer_zerop (partial))
7572 : return t;
7573 6 : else if (integer_zerop (t))
7574 : return partial;
7575 4 : else if (same_bool_result_p (t, partial))
7576 0 : return t;
7577 : }
7578 : }
7579 : }
7580 : }
7581 : return NULL_TREE;
7582 : }
7583 :
7584 : /* Try to simplify the AND of two comparisons defined by
7585 : (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
7586 : If this can be done without constructing an intermediate value,
7587 : return the resulting tree; otherwise NULL_TREE is returned.
7588 : This function is deliberately asymmetric as it recurses on SSA_DEFs
7589 : in the first comparison but not the second. */
7590 :
7591 : static tree
7592 1271649 : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
7593 : enum tree_code code2, tree op2a, tree op2b,
7594 : basic_block outer_cond_bb)
7595 : {
7596 1271649 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
7597 :
7598 : /* First check for ((x CODE1 y) AND (x CODE2 y)). */
7599 1271649 : if (operand_equal_p (op1a, op2a, 0)
7600 1271649 : && operand_equal_p (op1b, op2b, 0))
7601 : {
7602 : /* Result will be either NULL_TREE, or a combined comparison. */
7603 4589 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7604 : TRUTH_ANDIF_EXPR, code1, code2,
7605 : truth_type, op1a, op1b);
7606 4589 : if (t)
7607 : return t;
7608 : }
7609 :
7610 : /* Likewise the swapped case of the above. */
7611 1269960 : if (operand_equal_p (op1a, op2b, 0)
7612 1269960 : && operand_equal_p (op1b, op2a, 0))
7613 : {
7614 : /* Result will be either NULL_TREE, or a combined comparison. */
7615 65 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7616 : TRUTH_ANDIF_EXPR, code1,
7617 : swap_tree_comparison (code2),
7618 : truth_type, op1a, op1b);
7619 65 : if (t)
7620 : return t;
7621 : }
7622 :
7623 : /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
7624 : NAME's definition is a truth value. See if there are any simplifications
7625 : that can be done against the NAME's definition. */
7626 1269959 : if (TREE_CODE (op1a) == SSA_NAME
7627 1269908 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
7628 2240115 : && (integer_zerop (op1b) || integer_onep (op1b)))
7629 : {
7630 178429 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
7631 468739 : || (code1 == NE_EXPR && integer_onep (op1b)));
7632 428328 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
7633 428328 : switch (gimple_code (stmt))
7634 : {
7635 362398 : case GIMPLE_ASSIGN:
7636 : /* Try to simplify by copy-propagating the definition. */
7637 362398 : return and_var_with_comparison (type, op1a, invert, code2, op2a,
7638 362398 : op2b, outer_cond_bb);
7639 :
7640 31249 : case GIMPLE_PHI:
7641 : /* If every argument to the PHI produces the same result when
7642 : ANDed with the second comparison, we win.
7643 : Do not do this unless the type is bool since we need a bool
7644 : result here anyway. */
7645 31249 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
7646 : {
7647 : tree result = NULL_TREE;
7648 : unsigned i;
7649 11712 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
7650 : {
7651 11712 : tree arg = gimple_phi_arg_def (stmt, i);
7652 :
7653 : /* If this PHI has itself as an argument, ignore it.
7654 : If all the other args produce the same result,
7655 : we're still OK. */
7656 11712 : if (arg == gimple_phi_result (stmt))
7657 0 : continue;
7658 11712 : else if (TREE_CODE (arg) == INTEGER_CST)
7659 : {
7660 7969 : if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
7661 : {
7662 4751 : if (!result)
7663 1869 : result = boolean_false_node;
7664 2882 : else if (!integer_zerop (result))
7665 : return NULL_TREE;
7666 : }
7667 3218 : else if (!result)
7668 1928 : result = fold_build2 (code2, boolean_type_node,
7669 : op2a, op2b);
7670 1290 : else if (!same_bool_comparison_p (result,
7671 : code2, op2a, op2b))
7672 : return NULL_TREE;
7673 : }
7674 3743 : else if (TREE_CODE (arg) == SSA_NAME
7675 3743 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
7676 : {
7677 3740 : tree temp;
7678 3740 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
7679 : /* In simple cases we can look through PHI nodes,
7680 : but we have to be careful with loops.
7681 : See PR49073. */
7682 3740 : if (! dom_info_available_p (CDI_DOMINATORS)
7683 3740 : || gimple_bb (def_stmt) == gimple_bb (stmt)
7684 7480 : || dominated_by_p (CDI_DOMINATORS,
7685 3740 : gimple_bb (def_stmt),
7686 3740 : gimple_bb (stmt)))
7687 : return NULL_TREE;
7688 2839 : temp = and_var_with_comparison (type, arg, invert, code2,
7689 : op2a, op2b,
7690 : outer_cond_bb);
7691 2839 : if (!temp)
7692 : return NULL_TREE;
7693 0 : else if (!result)
7694 : result = temp;
7695 0 : else if (!same_bool_result_p (result, temp))
7696 : return NULL_TREE;
7697 : }
7698 : else
7699 : return NULL_TREE;
7700 : }
7701 : return result;
7702 : }
7703 :
7704 : default:
7705 : break;
7706 : }
7707 : }
7708 : return NULL_TREE;
7709 : }
7710 :
7711 : static basic_block fosa_bb;
7712 : static vec<std::pair<tree, flow_sensitive_info_storage> > *fosa_unwind;
7713 : static tree
7714 60669677 : follow_outer_ssa_edges (tree val)
7715 : {
7716 60669677 : if (TREE_CODE (val) == SSA_NAME
7717 60669677 : && !SSA_NAME_IS_DEFAULT_DEF (val))
7718 : {
7719 59491576 : basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (val));
7720 59491576 : if (!def_bb
7721 20119053 : || def_bb == fosa_bb
7722 70513562 : || (dom_info_available_p (CDI_DOMINATORS)
7723 11021986 : && (def_bb == fosa_bb
7724 11021986 : || dominated_by_p (CDI_DOMINATORS, fosa_bb, def_bb))))
7725 : return val;
7726 6874030 : flow_sensitive_info_storage storage;
7727 6874030 : storage.save_and_clear (val);
7728 : /* If the definition does not dominate fosa_bb temporarily reset
7729 : flow-sensitive info. */
7730 6874030 : fosa_unwind->safe_push (std::make_pair (val, storage));
7731 : /* We cannot temporarily rewrite stmts with undefined overflow
7732 : behavior, so avoid expanding them. But still save off the
7733 : flow-sensitive info as we might be using the ssa name as the leaf. */
7734 13701383 : if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val))
7735 747103 : || POINTER_TYPE_P (TREE_TYPE (val)))
7736 13306759 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val)))
7737 3931128 : return NULL_TREE;
7738 : return val;
7739 : }
7740 : return val;
7741 : }
7742 :
7743 : /* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
7744 : : try to simplify the AND/OR of the ssa variable VAR with the comparison
7745 : specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't
7746 : simplify this to a single expression. As we are going to lower the cost
7747 : of building SSA names / gimple stmts significantly, we need to allocate
7748 : them ont the stack. This will cause the code to be a bit ugly. */
7749 :
7750 : static tree
7751 1235432 : maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
7752 : enum tree_code code1,
7753 : tree op1a, tree op1b,
7754 : enum tree_code code2, tree op2a,
7755 : tree op2b,
7756 : basic_block outer_cond_bb)
7757 : {
7758 : /* Allocate gimple stmt1 on the stack. */
7759 1235432 : gassign *stmt1
7760 1235432 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7761 1235432 : gimple_init (stmt1, GIMPLE_ASSIGN, 3);
7762 1235432 : gimple_assign_set_rhs_code (stmt1, code1);
7763 1235432 : gimple_assign_set_rhs1 (stmt1, op1a);
7764 1235432 : gimple_assign_set_rhs2 (stmt1, op1b);
7765 1235432 : gimple_set_bb (stmt1, NULL);
7766 :
7767 : /* Allocate gimple stmt2 on the stack. */
7768 1235432 : gassign *stmt2
7769 1235432 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7770 1235432 : gimple_init (stmt2, GIMPLE_ASSIGN, 3);
7771 1235432 : gimple_assign_set_rhs_code (stmt2, code2);
7772 1235432 : gimple_assign_set_rhs1 (stmt2, op2a);
7773 1235432 : gimple_assign_set_rhs2 (stmt2, op2b);
7774 1235432 : gimple_set_bb (stmt2, NULL);
7775 :
7776 : /* Allocate SSA names(lhs1) on the stack. */
7777 1235432 : alignas (tree_node) unsigned char lhs1buf[sizeof (tree_ssa_name)];
7778 1235432 : tree lhs1 = (tree) &lhs1buf[0];
7779 1235432 : memset (lhs1, 0, sizeof (tree_ssa_name));
7780 1235432 : TREE_SET_CODE (lhs1, SSA_NAME);
7781 1235432 : TREE_TYPE (lhs1) = type;
7782 1235432 : init_ssa_name_imm_use (lhs1);
7783 :
7784 : /* Allocate SSA names(lhs2) on the stack. */
7785 1235432 : alignas (tree_node) unsigned char lhs2buf[sizeof (tree_ssa_name)];
7786 1235432 : tree lhs2 = (tree) &lhs2buf[0];
7787 1235432 : memset (lhs2, 0, sizeof (tree_ssa_name));
7788 1235432 : TREE_SET_CODE (lhs2, SSA_NAME);
7789 1235432 : TREE_TYPE (lhs2) = type;
7790 1235432 : init_ssa_name_imm_use (lhs2);
7791 :
7792 1235432 : gimple_assign_set_lhs (stmt1, lhs1);
7793 1235432 : gimple_assign_set_lhs (stmt2, lhs2);
7794 :
7795 1235432 : gimple_match_op op (gimple_match_cond::UNCOND, code,
7796 : type, gimple_assign_lhs (stmt1),
7797 1235432 : gimple_assign_lhs (stmt2));
7798 1235432 : fosa_bb = outer_cond_bb;
7799 1235432 : auto_vec<std::pair<tree, flow_sensitive_info_storage>, 8> unwind_stack;
7800 1235432 : fosa_unwind = &unwind_stack;
7801 1836802 : if (op.resimplify (NULL, (!outer_cond_bb
7802 : ? follow_all_ssa_edges : follow_outer_ssa_edges)))
7803 : {
7804 3240 : fosa_unwind = NULL;
7805 13985 : for (auto p : unwind_stack)
7806 4265 : p.second.restore (p.first);
7807 3240 : if (gimple_simplified_result_is_gimple_val (&op))
7808 : {
7809 2606 : tree res = op.ops[0];
7810 2606 : if (res == lhs1)
7811 2103 : return build2 (code1, type, op1a, op1b);
7812 503 : else if (res == lhs2)
7813 432 : return build2 (code2, type, op2a, op2b);
7814 : else
7815 : return res;
7816 : }
7817 634 : else if (op.code.is_tree_code ()
7818 634 : && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
7819 : {
7820 634 : tree op0 = op.ops[0];
7821 634 : tree op1 = op.ops[1];
7822 634 : if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
7823 : return NULL_TREE; /* not simple */
7824 :
7825 634 : return build2 ((enum tree_code)op.code, op.type, op0, op1);
7826 : }
7827 : }
7828 1232192 : fosa_unwind = NULL;
7829 10566341 : for (auto p : unwind_stack)
7830 6869765 : p.second.restore (p.first);
7831 :
7832 1232192 : return NULL_TREE;
7833 1235432 : }
7834 :
7835 : /* Return TRUE and set op[0] if T, following all SSA edges, is a type
7836 : conversion. Reject loads if LOAD is NULL, otherwise set *LOAD if a
7837 : converting load is found. */
7838 :
7839 : static bool
7840 3291077 : gimple_convert_def_p (tree t, tree op[1], gimple **load = NULL)
7841 : {
7842 3291077 : bool ret = false;
7843 :
7844 3291077 : if (TREE_CODE (t) == SSA_NAME
7845 3291077 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7846 1819700 : if (gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7847 : {
7848 1725349 : bool load_p = gimple_assign_load_p (def);
7849 1725349 : if (load_p && !load)
7850 : return false;
7851 1733772 : switch (gimple_assign_rhs_code (def))
7852 : {
7853 13887 : CASE_CONVERT:
7854 13887 : op[0] = gimple_assign_rhs1 (def);
7855 13887 : ret = true;
7856 13887 : break;
7857 :
7858 3950 : case VIEW_CONVERT_EXPR:
7859 3950 : op[0] = TREE_OPERAND (gimple_assign_rhs1 (def), 0);
7860 3950 : ret = true;
7861 3950 : break;
7862 :
7863 : default:
7864 : break;
7865 : }
7866 :
7867 17837 : if (ret && load_p)
7868 0 : *load = def;
7869 : }
7870 :
7871 : return ret;
7872 : }
7873 :
7874 : /* Return TRUE and set op[*] if T, following all SSA edges, resolves to a
7875 : binary expression with code CODE. */
7876 :
7877 : static bool
7878 3325431 : gimple_binop_def_p (enum tree_code code, tree t, tree op[2])
7879 : {
7880 3325431 : if (TREE_CODE (t) == SSA_NAME
7881 3325431 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7882 1851803 : if (gimple *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7883 1755008 : if (gimple_assign_rhs_code (def) == code)
7884 : {
7885 57261 : op[0] = gimple_assign_rhs1 (def);
7886 57261 : op[1] = gimple_assign_rhs2 (def);
7887 57261 : return true;
7888 : }
7889 : return false;
7890 : }
7891 : /* Subroutine for fold_truth_andor_1: decode a field reference.
7892 :
7893 : If *PEXP is a comparison reference, we return the innermost reference.
7894 :
7895 : *PBITSIZE is set to the number of bits in the reference, *PBITPOS is
7896 : set to the starting bit number.
7897 :
7898 : *PVOLATILEP is set to 1 if the any expression encountered is volatile;
7899 : otherwise it is not changed.
7900 :
7901 : *PUNSIGNEDP is set to the signedness of the field.
7902 :
7903 : *PREVERSEP is set to the storage order of the field.
7904 :
7905 : *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If
7906 : *PAND_MASK is initially set to a mask with nonzero precision, that mask is
7907 : combined with the found mask, or adjusted in precision to match.
7908 :
7909 : *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask
7910 : encompassed bits that corresponded to extensions of the sign bit.
7911 :
7912 : *PXORP is to be FALSE if EXP might be a XOR used in a compare, in which
7913 : case, if PXOR_CMP_OP is a zero constant, it will be overridden with *PEXP,
7914 : *PXORP will be set to TRUE, *PXOR_AND_MASK will be copied from *PAND_MASK,
7915 : and the left-hand operand of the XOR will be decoded. If *PXORP is TRUE,
7916 : PXOR_CMP_OP and PXOR_AND_MASK are supposed to be NULL, and then the
7917 : right-hand operand of the XOR will be decoded.
7918 :
7919 : *LOAD is set to the load stmt of the innermost reference, if any,
7920 : *and NULL otherwise.
7921 :
7922 : LOC[0..3] are filled in as conversion, masking, shifting and loading
7923 : operations are located.
7924 :
7925 : Return 0 if this is not a component reference or is one that we can't
7926 : do anything with. */
7927 :
7928 : static tree
7929 1174277 : decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize,
7930 : HOST_WIDE_INT *pbitpos,
7931 : bool *punsignedp, bool *preversep, bool *pvolatilep,
7932 : wide_int *pand_mask, bool *psignbit,
7933 : bool *pxorp, tree *pxor_cmp_op, wide_int *pxor_and_mask,
7934 : gimple **pload, location_t loc[4])
7935 : {
7936 1174277 : tree exp = *pexp;
7937 1174277 : tree outer_type = 0;
7938 1174277 : wide_int and_mask;
7939 1174277 : tree inner, offset;
7940 1174277 : int shiftrt = 0;
7941 1174277 : tree res_ops[2];
7942 1174277 : machine_mode mode;
7943 1174277 : bool convert_before_shift = false;
7944 1174277 : bool signbit = false;
7945 1174277 : bool xorp = false;
7946 1174277 : tree xor_cmp_op;
7947 1174277 : wide_int xor_and_mask;
7948 1174277 : gimple *load = NULL;
7949 :
7950 : /* All the optimizations using this function assume integer fields.
7951 : There are problems with FP fields since the type_for_size call
7952 : below can fail for, e.g., XFmode. */
7953 1174277 : if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
7954 : return NULL_TREE;
7955 :
7956 : /* Drop casts, saving only the outermost type, effectively used in
7957 : the compare. We can deal with at most one conversion, and it may
7958 : appear at various points in the chain of recognized preparation
7959 : statements. Earlier optimizers will often have already dropped
7960 : unneeded extensions, but they may survive, as in PR118046. ???
7961 : Can we do better and allow multiple conversions, perhaps taking
7962 : note of the narrowest intermediate type, sign extensions and
7963 : whatnot? */
7964 1108495 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
7965 : {
7966 16483 : outer_type = TREE_TYPE (exp);
7967 16483 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
7968 16483 : exp = res_ops[0];
7969 : }
7970 :
7971 : /* Recognize and save a masking operation. Combine it with an
7972 : incoming mask. */
7973 1108495 : if (gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops)
7974 1108495 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
7975 : {
7976 33534 : loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp));
7977 33534 : exp = res_ops[0];
7978 33534 : and_mask = wi::to_wide (res_ops[1]);
7979 33534 : unsigned prec_in = pand_mask->get_precision ();
7980 33534 : if (prec_in)
7981 : {
7982 0 : unsigned prec_op = and_mask.get_precision ();
7983 0 : if (prec_in >= prec_op)
7984 : {
7985 0 : if (prec_in > prec_op)
7986 0 : and_mask = wide_int::from (and_mask, prec_in, UNSIGNED);
7987 0 : and_mask &= *pand_mask;
7988 : }
7989 : else
7990 0 : and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED);
7991 : }
7992 : }
7993 : else
7994 1074961 : and_mask = *pand_mask;
7995 :
7996 : /* Turn (a ^ b) [!]= 0 into a [!]= b. */
7997 1108495 : if (pxorp && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops))
7998 : {
7999 : /* No location recorded for this one, it's entirely subsumed by the
8000 : compare. */
8001 10978 : if (*pxorp)
8002 : {
8003 5461 : exp = res_ops[1];
8004 5461 : gcc_checking_assert (!pxor_cmp_op && !pxor_and_mask);
8005 : }
8006 5517 : else if (!pxor_cmp_op)
8007 : /* Not much we can do when xor appears in the right-hand compare
8008 : operand. */
8009 : return NULL_TREE;
8010 5463 : else if (integer_zerop (*pxor_cmp_op))
8011 : {
8012 5461 : xorp = true;
8013 5461 : exp = res_ops[0];
8014 5461 : xor_cmp_op = *pexp;
8015 5461 : xor_and_mask = *pand_mask;
8016 : }
8017 : }
8018 :
8019 : /* Another chance to drop conversions. */
8020 1108441 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
8021 : {
8022 1334 : outer_type = TREE_TYPE (exp);
8023 1334 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
8024 1334 : exp = res_ops[0];
8025 : }
8026 :
8027 : /* Take note of shifts. */
8028 1108441 : if (gimple_binop_def_p (RSHIFT_EXPR, exp, res_ops)
8029 1108441 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
8030 : {
8031 629 : loc[2] = gimple_location (SSA_NAME_DEF_STMT (exp));
8032 629 : exp = res_ops[0];
8033 629 : if (!tree_fits_shwi_p (res_ops[1]))
8034 : return NULL_TREE;
8035 629 : shiftrt = tree_to_shwi (res_ops[1]);
8036 629 : if (shiftrt <= 0)
8037 : return NULL_TREE;
8038 : }
8039 :
8040 : /* Yet another chance to drop conversions. This one is allowed to
8041 : match a converting load, subsuming the load identification block
8042 : below. */
8043 1108441 : if (!outer_type && gimple_convert_def_p (exp, res_ops, &load))
8044 : {
8045 20 : outer_type = TREE_TYPE (exp);
8046 20 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
8047 20 : if (load)
8048 0 : loc[3] = gimple_location (load);
8049 20 : exp = res_ops[0];
8050 : /* This looks backwards, but we're going back the def chain, so if we
8051 : find the conversion here, after finding a shift, that's because the
8052 : convert appears before the shift, and we should thus adjust the bit
8053 : pos and size because of the shift after adjusting it due to type
8054 : conversion. */
8055 20 : convert_before_shift = true;
8056 : }
8057 :
8058 : /* Identify the load, if there is one. */
8059 1108441 : if (!load && TREE_CODE (exp) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (exp))
8060 : {
8061 616460 : gimple *def = SSA_NAME_DEF_STMT (exp);
8062 616460 : if (gimple_assign_load_p (def))
8063 : {
8064 390850 : loc[3] = gimple_location (def);
8065 390850 : load = def;
8066 390850 : exp = gimple_assign_rhs1 (def);
8067 : }
8068 : }
8069 :
8070 : /* Identify the relevant bits. */
8071 1108441 : poly_int64 poly_bitsize, poly_bitpos;
8072 1108441 : int unsignedp, reversep = *preversep, volatilep = *pvolatilep;
8073 1108441 : inner = get_inner_reference (exp, &poly_bitsize, &poly_bitpos, &offset,
8074 : &mode, &unsignedp, &reversep, &volatilep);
8075 :
8076 1108441 : HOST_WIDE_INT bs, bp;
8077 1108441 : if (!poly_bitsize.is_constant (&bs)
8078 1108441 : || !poly_bitpos.is_constant (&bp)
8079 1108441 : || bs <= shiftrt
8080 1108441 : || offset != 0
8081 1107203 : || TREE_CODE (inner) == PLACEHOLDER_EXPR
8082 : /* Reject out-of-bound accesses (PR79731, PR118514). */
8083 1156370 : || !access_in_bounds_of_type_p (TREE_TYPE (inner), bs, bp)
8084 1107169 : || (INTEGRAL_TYPE_P (TREE_TYPE (inner))
8085 758831 : && !type_has_mode_precision_p (TREE_TYPE (inner))))
8086 : return NULL_TREE;
8087 :
8088 : /* Adjust shifts... */
8089 1059240 : if (convert_before_shift
8090 1059240 : && outer_type && bs > TYPE_PRECISION (outer_type))
8091 : {
8092 2 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8093 2 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8094 0 : bp += excess;
8095 : bs -= excess;
8096 : }
8097 :
8098 1059240 : if (shiftrt)
8099 : {
8100 : /* Punt if we're shifting by more than the loaded bitfield (after
8101 : adjustment), or if there's a shift after a change of signedness, punt.
8102 : When comparing this field with a constant, we'll check that the
8103 : constant is a proper sign- or zero-extension (depending on signedness)
8104 : of a value that would fit in the selected portion of the bitfield. A
8105 : shift after a change of signedness would make the extension
8106 : non-uniform, and we can't deal with that (yet ???). See
8107 : gcc.dg/field-merge-22.c for a test that would go wrong. */
8108 629 : if (bs <= shiftrt
8109 629 : || (convert_before_shift
8110 20 : && outer_type && unsignedp != TYPE_UNSIGNED (outer_type)))
8111 : return NULL_TREE;
8112 610 : if (!reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8113 610 : bp += shiftrt;
8114 610 : bs -= shiftrt;
8115 : }
8116 :
8117 : /* ... and bit position. */
8118 1059221 : if (!convert_before_shift
8119 1059221 : && outer_type && bs > TYPE_PRECISION (outer_type))
8120 : {
8121 7731 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8122 7731 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8123 0 : bp += excess;
8124 : bs -= excess;
8125 : }
8126 :
8127 : /* If the number of bits in the reference is the same as the bitsize of
8128 : the outer type, then the outer type gives the signedness. Otherwise
8129 : (in case of a small bitfield) the signedness is unchanged. */
8130 1059221 : if (outer_type && bs == TYPE_PRECISION (outer_type))
8131 12997 : unsignedp = TYPE_UNSIGNED (outer_type);
8132 :
8133 : /* Make the mask the expected width. */
8134 1059221 : if (and_mask.get_precision () != 0)
8135 : {
8136 : /* If the AND_MASK encompasses bits that would be extensions of
8137 : the sign bit, set SIGNBIT. */
8138 38825 : if (!unsignedp
8139 2983 : && and_mask.get_precision () > bs
8140 41862 : && (and_mask & wi::mask (bs, true, and_mask.get_precision ())) != 0)
8141 : signbit = true;
8142 38825 : and_mask = wide_int::from (and_mask, bs, UNSIGNED);
8143 : }
8144 :
8145 1059221 : *pexp = exp;
8146 1059221 : *pload = load;
8147 1059221 : *pbitsize = bs;
8148 1059221 : *pbitpos = bp;
8149 1059221 : *punsignedp = unsignedp;
8150 1059221 : *preversep = reversep;
8151 1059221 : *pvolatilep = volatilep;
8152 1059221 : *psignbit = signbit;
8153 1059221 : *pand_mask = and_mask;
8154 1059221 : if (xorp)
8155 : {
8156 5461 : *pxorp = xorp;
8157 5461 : *pxor_cmp_op = xor_cmp_op;
8158 5461 : *pxor_and_mask = xor_and_mask;
8159 : }
8160 :
8161 : return inner;
8162 1174277 : }
8163 :
8164 : /* Return the one bitpos within bit extents L or R that is at an
8165 : ALIGN-bit alignment boundary, or -1 if there is more than one such
8166 : boundary, if there isn't any, or if there is any such boundary
8167 : between the extents. L and R are given by bitpos and bitsize. If
8168 : it doesn't return -1, there are two consecutive ALIGN-bit words
8169 : that contain both extents, and at least one of the extents
8170 : straddles across the returned alignment boundary. */
8171 :
8172 : static inline HOST_WIDE_INT
8173 48589 : compute_split_boundary_from_align (HOST_WIDE_INT align,
8174 : HOST_WIDE_INT l_bitpos,
8175 : HOST_WIDE_INT l_bitsize,
8176 : HOST_WIDE_INT r_bitpos,
8177 : HOST_WIDE_INT r_bitsize)
8178 : {
8179 48589 : HOST_WIDE_INT amask = ~(align - 1);
8180 :
8181 48589 : HOST_WIDE_INT first_bit = MIN (l_bitpos, r_bitpos);
8182 48589 : HOST_WIDE_INT end_bit = MAX (l_bitpos + l_bitsize, r_bitpos + r_bitsize);
8183 :
8184 48589 : HOST_WIDE_INT boundary = (end_bit - 1) & amask;
8185 :
8186 : /* Make sure we're crossing no more than one alignment boundary.
8187 :
8188 : ??? We don't have logic to recombine loads of two adjacent
8189 : fields that each crosses a different alignment boundary, so
8190 : as to load the middle word only once, if other words can't be
8191 : otherwise recombined. */
8192 48589 : if (boundary - first_bit > align)
8193 : return -1;
8194 :
8195 18785 : HOST_WIDE_INT l_start_word = l_bitpos & amask;
8196 18785 : HOST_WIDE_INT l_end_word = (l_bitpos + l_bitsize - 1) & amask;
8197 :
8198 18785 : HOST_WIDE_INT r_start_word = r_bitpos & amask;
8199 18785 : HOST_WIDE_INT r_end_word = (r_bitpos + r_bitsize - 1) & amask;
8200 :
8201 : /* If neither field straddles across an alignment boundary, it's no
8202 : use to even try to merge them. */
8203 18785 : if (l_start_word == l_end_word && r_start_word == r_end_word)
8204 18478 : return -1;
8205 :
8206 : return boundary;
8207 : }
8208 :
8209 : /* Make a bit_field_ref. If POINT is NULL, return the BIT_FIELD_REF.
8210 : Otherwise, build and insert a load stmt before POINT, and return
8211 : the SSA_NAME. ??? Rewrite LOAD in terms of the bitfield? */
8212 :
8213 : static tree
8214 4640 : make_bit_field_load (location_t loc, tree inner, tree orig_inner, tree type,
8215 : HOST_WIDE_INT bitsize, poly_int64 bitpos,
8216 : bool unsignedp, bool reversep, gimple *point)
8217 : {
8218 4640 : if (point && loc == UNKNOWN_LOCATION)
8219 18 : loc = gimple_location (point);
8220 :
8221 4640 : tree ref = make_bit_field_ref (loc, unshare_expr (inner),
8222 : unshare_expr (orig_inner),
8223 : type, bitsize, bitpos,
8224 : unsignedp, reversep);
8225 4640 : if (!point)
8226 : return ref;
8227 :
8228 : /* If we're remaking the same load, reuse the SSA NAME it is already loaded
8229 : into. */
8230 4485 : if (gimple_assign_load_p (point)
8231 4485 : && operand_equal_p (ref, gimple_assign_rhs1 (point)))
8232 : {
8233 1662 : gcc_checking_assert (TREE_CODE (gimple_assign_lhs (point)) == SSA_NAME);
8234 : return gimple_assign_lhs (point);
8235 : }
8236 :
8237 2823 : gimple_seq stmts = NULL;
8238 2823 : tree ret = force_gimple_operand (ref, &stmts, true, NULL_TREE);
8239 :
8240 : /* We know the vuse is supposed to end up being the same as that at the
8241 : original load at the insertion point, but if we don't set it, it will be a
8242 : generic placeholder that only the global SSA update at the end of the pass
8243 : would make equal, too late for us to use in further combinations. So go
8244 : ahead and copy the vuse. */
8245 :
8246 2823 : tree reaching_vuse = gimple_vuse (point);
8247 2823 : for (gimple_stmt_iterator i = gsi_start (stmts);
8248 6161 : !gsi_end_p (i); gsi_next (&i))
8249 : {
8250 3338 : gimple *new_stmt = gsi_stmt (i);
8251 6676 : if (gimple_has_mem_ops (new_stmt))
8252 3338 : gimple_set_vuse (new_stmt, reaching_vuse);
8253 : }
8254 :
8255 2823 : gimple_stmt_iterator gsi = gsi_for_stmt (point);
8256 2823 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
8257 2823 : return ret;
8258 : }
8259 :
8260 : /* Initialize ln_arg[0] and ln_arg[1] to a pair of newly-created (at
8261 : LOC) loads from INNER (from ORIG_INNER), of modes MODE and MODE2,
8262 : respectively, starting at BIT_POS, using reversed endianness if
8263 : REVERSEP. Also initialize BITPOS (the starting position of each
8264 : part into INNER), BITSIZ (the bit count starting at BITPOS),
8265 : TOSHIFT[1] (the amount by which the part and its mask are to be
8266 : shifted right to bring its least-significant bit to bit zero) and
8267 : SHIFTED (the amount by which the part, by separate loading, has
8268 : already been shifted right, but that the mask needs shifting to
8269 : match). */
8270 :
8271 : static inline void
8272 307 : build_split_load (tree /* out */ ln_arg[2],
8273 : HOST_WIDE_INT /* out */ bitpos[2],
8274 : HOST_WIDE_INT /* out */ bitsiz[2],
8275 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8276 : HOST_WIDE_INT /* out */ shifted[2],
8277 : location_t loc, tree inner, tree orig_inner,
8278 : scalar_int_mode mode, scalar_int_mode mode2,
8279 : HOST_WIDE_INT bit_pos, bool reversep,
8280 : gimple *point[2])
8281 : {
8282 307 : scalar_int_mode modes[2] = { mode, mode2 };
8283 307 : bitsiz[0] = GET_MODE_BITSIZE (mode);
8284 307 : bitsiz[1] = GET_MODE_BITSIZE (mode2);
8285 :
8286 921 : for (int i = 0; i < 2; i++)
8287 : {
8288 614 : tree type = lang_hooks.types.type_for_mode (modes[i], 1);
8289 614 : if (!type)
8290 : {
8291 0 : type = build_nonstandard_integer_type (bitsiz[0], 1);
8292 0 : gcc_assert (type);
8293 : }
8294 614 : bitpos[i] = bit_pos;
8295 1228 : ln_arg[i] = make_bit_field_load (loc, inner, orig_inner,
8296 614 : type, bitsiz[i],
8297 614 : bit_pos, 1, reversep, point[i]);
8298 614 : bit_pos += bitsiz[i];
8299 : }
8300 :
8301 307 : toshift[1] = toshift[0];
8302 307 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8303 : {
8304 3 : shifted[0] = bitsiz[1];
8305 3 : shifted[1] = 0;
8306 3 : toshift[0] = 0;
8307 : }
8308 : else
8309 : {
8310 304 : shifted[1] = bitsiz[0];
8311 304 : shifted[0] = 0;
8312 304 : toshift[1] = 0;
8313 : }
8314 307 : }
8315 :
8316 : /* Make arrangements to split at bit BOUNDARY a single loaded word
8317 : (with REVERSEP bit order) LN_ARG[0], to be shifted right by
8318 : TOSHIFT[0] to bring the field of interest to the least-significant
8319 : bit. The expectation is that the same loaded word will be
8320 : propagated from part 0 to part 1, with just different shifting and
8321 : masking to extract both parts. MASK is not expected to do more
8322 : than masking out the bits that belong to the other part. See
8323 : build_split_load for more information on the other fields. */
8324 :
8325 : static inline void
8326 51 : reuse_split_load (tree /* in[0] out[1] */ ln_arg[2],
8327 : HOST_WIDE_INT /* in[0] out[1] */ bitpos[2],
8328 : HOST_WIDE_INT /* in[0] out[1] */ bitsiz[2],
8329 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8330 : HOST_WIDE_INT /* out */ shifted[2],
8331 : wide_int /* out */ mask[2],
8332 : HOST_WIDE_INT boundary, bool reversep)
8333 : {
8334 51 : unsigned prec = TYPE_PRECISION (TREE_TYPE (ln_arg[0]));
8335 :
8336 51 : ln_arg[1] = ln_arg[0];
8337 51 : bitpos[1] = bitpos[0];
8338 51 : bitsiz[1] = bitsiz[0];
8339 51 : shifted[1] = shifted[0] = 0;
8340 :
8341 51 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8342 : {
8343 3 : toshift[1] = toshift[0];
8344 3 : toshift[0] = bitpos[0] + bitsiz[0] - boundary;
8345 3 : mask[0] = wi::mask (toshift[0], true, prec);
8346 3 : mask[1] = wi::mask (toshift[0], false, prec);
8347 : }
8348 : else
8349 : {
8350 48 : toshift[1] = boundary - bitpos[1];
8351 48 : mask[1] = wi::mask (toshift[1], true, prec);
8352 48 : mask[0] = wi::mask (toshift[1], false, prec);
8353 : }
8354 51 : }
8355 :
8356 : /* Find ways of folding logical expressions of LHS and RHS:
8357 :
8358 : Try to merge two comparisons to nearby fields.
8359 :
8360 : For example, if we have p->a == 2 && p->b == 4 and we can load both A and B
8361 : at once, we can do this with a comparison against the object ANDed with the
8362 : a mask.
8363 :
8364 : If we have p->a == q->a && p->b == q->b, we may be able to use bit masking
8365 : operations to do this with one comparison, loading both fields from P at
8366 : once, and likewise from Q.
8367 :
8368 : Herein, loading at once means loading from within the same alignment
8369 : boundary for the enclosing object. If (packed) fields cross such alignment
8370 : boundaries, we may still recombine the compares, so that loads do not cross
8371 : the boundaries.
8372 :
8373 : CODE is the logical operation being done. It can be TRUTH_ANDIF_EXPR,
8374 : TRUTH_AND_EXPR, TRUTH_ORIF_EXPR, or TRUTH_OR_EXPR.
8375 :
8376 : TRUTH_TYPE is the type of the logical operand.
8377 :
8378 : LHS is denoted as LL_ARG LCODE LR_ARG.
8379 :
8380 : RHS is denoted as RL_ARG RCODE RR_ARG.
8381 :
8382 : LHS is assumed to dominate RHS.
8383 :
8384 : Combined loads are inserted next to preexisting loads, once we determine
8385 : that the combination is viable, and the combined condition references new
8386 : SSA_NAMEs that hold the loaded values. Since the original loads are
8387 : verified to have the same gimple_vuse, the insertion point doesn't matter
8388 : for correctness. ??? The loads may be a lot earlier than the compares, and
8389 : it's conceivable that one or two loads for RHS appear before those for LHS.
8390 : It could be advantageous to try to place the loads optimally, taking
8391 : advantage of knowing whether RHS is accessed before LHS, or that both are
8392 : accessed before both compares, but we don't do that (yet?).
8393 :
8394 : SEPARATEP should be NULL if the combined condition must be returned as a
8395 : single expression, even if it is a compound condition. This must only be
8396 : done if LHS and RHS are adjacent, without intervening conditions, and the
8397 : combined condition is to replace RHS, while LHS is dropped altogether.
8398 :
8399 : Otherwise, SEPARATEP must be a non-NULL pointer to a NULL_TREE, that may be
8400 : replaced by a part of the compound condition that could replace RHS, while
8401 : the returned expression replaces LHS. This works whether or not LHS and RHS
8402 : are adjacent, as long as there aren't VDEFs or other side effects between
8403 : them.
8404 :
8405 : If the "words" accessed by RHS are already accessed by LHS, this won't
8406 : matter, but if RHS accesses "words" that LHS doesn't, then *SEPARATEP will
8407 : be set to the compares that should take RHS's place. By "words" we mean
8408 : contiguous bits that do not cross a an TYPE_ALIGN boundary of the accessed
8409 : object's type.
8410 :
8411 : We return the simplified tree or 0 if no optimization is possible. */
8412 :
8413 : tree
8414 439460 : fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type,
8415 : location_t lloc, enum tree_code lcode,
8416 : tree ll_arg, tree lr_arg,
8417 : location_t rloc, enum tree_code rcode,
8418 : tree rl_arg, tree rr_arg,
8419 : tree *separatep)
8420 : {
8421 : /* If this is the "or" of two comparisons, we can do something if
8422 : the comparisons are NE_EXPR. If this is the "and", we can do something
8423 : if the comparisons are EQ_EXPR. I.e.,
8424 : (a->b == 2 && a->c == 4) can become (a->new == NEW).
8425 :
8426 : WANTED_CODE is this operation code. For single bit fields, we can
8427 : convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
8428 : comparison for one-bit fields. */
8429 :
8430 439460 : enum tree_code orig_code = code;
8431 439460 : enum tree_code wanted_code;
8432 439460 : tree ll_inner, lr_inner, rl_inner, rr_inner;
8433 439460 : gimple *ll_load, *lr_load, *rl_load, *rr_load;
8434 439460 : HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
8435 439460 : HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
8436 439460 : HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
8437 439460 : HOST_WIDE_INT lnbitsize, lnbitpos, lnprec;
8438 439460 : HOST_WIDE_INT rnbitsize, rnbitpos, rnprec;
8439 439460 : bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
8440 439460 : bool ll_reversep, lr_reversep, rl_reversep, rr_reversep;
8441 439460 : bool ll_signbit, lr_signbit, rl_signbit, rr_signbit;
8442 439460 : scalar_int_mode lnmode, lnmode2, rnmode;
8443 439460 : wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
8444 439460 : wide_int l_const, r_const;
8445 439460 : tree lntype, rntype, result;
8446 439460 : HOST_WIDE_INT first_bit, end_bit;
8447 439460 : bool volatilep;
8448 439460 : bool l_split_load;
8449 :
8450 : /* These are indexed by: conv, mask, shft, load. */
8451 439460 : location_t ll_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8452 439460 : location_t lr_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8453 439460 : location_t rl_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8454 439460 : location_t rr_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8455 :
8456 439460 : gcc_checking_assert (!separatep || !*separatep);
8457 :
8458 : /* Start by getting the comparison codes. Fail if anything is volatile.
8459 : If one operand is a BIT_AND_EXPR with the constant one, treat it as if
8460 : it were surrounded with a NE_EXPR. */
8461 :
8462 439460 : if (TREE_CODE_CLASS (lcode) != tcc_comparison
8463 439460 : || TREE_CODE_CLASS (rcode) != tcc_comparison)
8464 : return 0;
8465 :
8466 : /* We don't normally find TRUTH_*IF_EXPR in gimple, but these codes may be
8467 : given by our caller to denote conditions from different blocks. */
8468 439460 : switch (code)
8469 : {
8470 : case TRUTH_AND_EXPR:
8471 : case TRUTH_ANDIF_EXPR:
8472 : code = TRUTH_AND_EXPR;
8473 : break;
8474 :
8475 0 : case TRUTH_OR_EXPR:
8476 0 : case TRUTH_ORIF_EXPR:
8477 0 : code = TRUTH_OR_EXPR;
8478 0 : break;
8479 :
8480 : default:
8481 : return 0;
8482 : }
8483 :
8484 : /* Prepare to turn compares of signed quantities with zero into sign-bit
8485 : tests. We need not worry about *_reversep here for these compare
8486 : rewrites: loads will have already been reversed before compares. Save the
8487 : precision, because [lr]l_arg may change and we won't be able to tell how
8488 : wide it was originally. */
8489 439460 : unsigned lsignbit = 0, rsignbit = 0;
8490 439460 : if ((lcode == LT_EXPR || lcode == GE_EXPR)
8491 16038 : && integer_zerop (lr_arg)
8492 3705 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8493 443165 : && !TYPE_UNSIGNED (TREE_TYPE (ll_arg)))
8494 : {
8495 3705 : lsignbit = TYPE_PRECISION (TREE_TYPE (ll_arg));
8496 3705 : lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8497 : }
8498 : /* Turn compares of unsigned quantities with powers of two into
8499 : equality tests of masks. */
8500 435755 : else if ((lcode == LT_EXPR || lcode == GE_EXPR)
8501 12333 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8502 11571 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8503 8428 : && TREE_CODE (lr_arg) == INTEGER_CST
8504 435755 : && wi::popcount (wi::to_wide (lr_arg)) == 1)
8505 : {
8506 0 : ll_and_mask = ~(wi::to_wide (lr_arg) - 1);
8507 0 : lcode = (lcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8508 0 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8509 : }
8510 : /* Turn compares of unsigned quantities with powers of two minus one
8511 : into equality tests of masks. */
8512 871510 : else if ((lcode == LE_EXPR || lcode == GT_EXPR)
8513 34577 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8514 34352 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8515 27751 : && TREE_CODE (lr_arg) == INTEGER_CST
8516 495012 : && wi::popcount (wi::to_wide (lr_arg) + 1) == 1)
8517 : {
8518 4097 : ll_and_mask = ~wi::to_wide (lr_arg);
8519 4097 : lcode = (lcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8520 4097 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8521 : }
8522 : /* Likewise for the second compare. */
8523 439460 : if ((rcode == LT_EXPR || rcode == GE_EXPR)
8524 22447 : && integer_zerop (rr_arg)
8525 2457 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8526 441917 : && !TYPE_UNSIGNED (TREE_TYPE (rl_arg)))
8527 : {
8528 2457 : rsignbit = TYPE_PRECISION (TREE_TYPE (rl_arg));
8529 2457 : rcode = (rcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8530 : }
8531 437003 : else if ((rcode == LT_EXPR || rcode == GE_EXPR)
8532 19990 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8533 18859 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8534 4049 : && TREE_CODE (rr_arg) == INTEGER_CST
8535 437003 : && wi::popcount (wi::to_wide (rr_arg)) == 1)
8536 : {
8537 0 : rl_and_mask = ~(wi::to_wide (rr_arg) - 1);
8538 0 : rcode = (rcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8539 0 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8540 : }
8541 874006 : else if ((rcode == LE_EXPR || rcode == GT_EXPR)
8542 44831 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8543 44549 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8544 32713 : && TREE_CODE (rr_arg) == INTEGER_CST
8545 504729 : && wi::popcount (wi::to_wide (rr_arg) + 1) == 1)
8546 : {
8547 3465 : rl_and_mask = ~wi::to_wide (rr_arg);
8548 3465 : rcode = (rcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8549 3465 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8550 : }
8551 :
8552 : /* See if the comparisons can be merged. Then get all the parameters for
8553 : each side. */
8554 :
8555 439460 : if ((lcode != EQ_EXPR && lcode != NE_EXPR)
8556 395559 : || (rcode != EQ_EXPR && rcode != NE_EXPR))
8557 : return 0;
8558 :
8559 367825 : ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
8560 367825 : volatilep = 0;
8561 367825 : bool l_xor = false, r_xor = false;
8562 367825 : ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos,
8563 : &ll_unsignedp, &ll_reversep, &volatilep,
8564 : &ll_and_mask, &ll_signbit,
8565 : &l_xor, &lr_arg, &lr_and_mask,
8566 : &ll_load, ll_loc);
8567 367825 : if (!ll_inner)
8568 : return 0;
8569 277809 : lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos,
8570 : &lr_unsignedp, &lr_reversep, &volatilep,
8571 : &lr_and_mask, &lr_signbit, &l_xor, 0, 0,
8572 : &lr_load, lr_loc);
8573 277809 : if (!lr_inner)
8574 : return 0;
8575 273477 : rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos,
8576 : &rl_unsignedp, &rl_reversep, &volatilep,
8577 : &rl_and_mask, &rl_signbit,
8578 : &r_xor, &rr_arg, &rr_and_mask,
8579 : &rl_load, rl_loc);
8580 273477 : if (!rl_inner)
8581 : return 0;
8582 255166 : rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos,
8583 : &rr_unsignedp, &rr_reversep, &volatilep,
8584 : &rr_and_mask, &rr_signbit, &r_xor, 0, 0,
8585 : &rr_load, rr_loc);
8586 255166 : if (!rr_inner)
8587 : return 0;
8588 :
8589 : /* It must be true that the inner operation on the lhs of each
8590 : comparison must be the same if we are to be able to do anything.
8591 : Then see if we have constants. If not, the same must be true for
8592 : the rhs's. If one is a load and the other isn't, we have to be
8593 : conservative and avoid the optimization, otherwise we could get
8594 : SRAed fields wrong. */
8595 252769 : if (volatilep)
8596 : return 0;
8597 :
8598 252767 : if (ll_reversep != rl_reversep
8599 252767 : || ! operand_equal_p (ll_inner, rl_inner, 0))
8600 : {
8601 : /* Try swapping the operands. */
8602 195223 : if (ll_reversep != rr_reversep || rsignbit
8603 389742 : || !operand_equal_p (ll_inner, rr_inner, 0))
8604 : return 0;
8605 :
8606 1931 : rcode = swap_tree_comparison (rcode);
8607 1931 : std::swap (rl_arg, rr_arg);
8608 1931 : std::swap (rl_inner, rr_inner);
8609 1931 : std::swap (rl_bitsize, rr_bitsize);
8610 1931 : std::swap (rl_bitpos, rr_bitpos);
8611 1931 : std::swap (rl_unsignedp, rr_unsignedp);
8612 1931 : std::swap (rl_reversep, rr_reversep);
8613 1931 : std::swap (rl_and_mask, rr_and_mask);
8614 1931 : std::swap (rl_signbit, rr_signbit);
8615 1931 : std::swap (rl_load, rr_load);
8616 1931 : std::swap (rl_loc, rr_loc);
8617 : }
8618 :
8619 116513 : if ((ll_load && rl_load)
8620 230791 : ? gimple_vuse (ll_load) != gimple_vuse (rl_load)
8621 2235 : : (!ll_load != !rl_load))
8622 : return 0;
8623 :
8624 : /* ??? Can we do anything with these? */
8625 58612 : if (lr_signbit || rr_signbit)
8626 : return 0;
8627 :
8628 : /* If the mask encompassed extensions of the sign bit before
8629 : clipping, try to include the sign bit in the test. If we're not
8630 : comparing with zero, don't even try to deal with it (for now?).
8631 : If we've already committed to a sign test, the extended (before
8632 : clipping) mask could already be messing with it. */
8633 58612 : if (ll_signbit)
8634 : {
8635 4 : if (!integer_zerop (lr_arg) || lsignbit)
8636 0 : return 0;
8637 4 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8638 4 : if (!ll_and_mask.get_precision ())
8639 0 : ll_and_mask = sign;
8640 : else
8641 4 : ll_and_mask |= sign;
8642 4 : }
8643 :
8644 58612 : if (rl_signbit)
8645 : {
8646 4 : if (!integer_zerop (rr_arg) || rsignbit)
8647 1 : return 0;
8648 3 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8649 3 : if (!rl_and_mask.get_precision ())
8650 0 : rl_and_mask = sign;
8651 : else
8652 3 : rl_and_mask |= sign;
8653 3 : }
8654 :
8655 58611 : if (TREE_CODE (lr_arg) == INTEGER_CST
8656 46409 : && TREE_CODE (rr_arg) == INTEGER_CST)
8657 : {
8658 45822 : l_const = wi::to_wide (lr_arg);
8659 : /* We don't expect masks on constants, but if there are any, apply
8660 : them now. */
8661 45822 : if (lr_and_mask.get_precision ())
8662 0 : l_const &= wide_int::from (lr_and_mask,
8663 0 : l_const.get_precision (), UNSIGNED);
8664 45822 : r_const = wi::to_wide (rr_arg);
8665 45822 : if (rr_and_mask.get_precision ())
8666 0 : r_const &= wide_int::from (rr_and_mask,
8667 0 : r_const.get_precision (), UNSIGNED);
8668 45822 : lr_reversep = ll_reversep;
8669 : }
8670 12789 : else if (lr_reversep != rr_reversep
8671 12781 : || ! operand_equal_p (lr_inner, rr_inner, 0)
8672 22290 : || ((lr_load && rr_load)
8673 28329 : ? gimple_vuse (lr_load) != gimple_vuse (rr_load)
8674 58 : : (!lr_load != !rr_load)))
8675 : return 0;
8676 :
8677 : /* If we found sign tests, finish turning them into bit tests. */
8678 :
8679 55084 : if (lsignbit)
8680 : {
8681 66 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8682 : /* If ll_arg is zero-extended and we're testing the sign bit, we know
8683 : what the result should be. Shifting the sign bit out of sign will get
8684 : us to mask the entire field out, yielding zero, i.e., the sign bit of
8685 : the zero-extended value. We know the masked value is being compared
8686 : with zero, so the compare will get us the result we're looking
8687 : for: TRUE if EQ_EXPR, FALSE if NE_EXPR. */
8688 66 : if (lsignbit > ll_bitsize && ll_unsignedp)
8689 1 : sign <<= 1;
8690 66 : if (!ll_and_mask.get_precision ())
8691 65 : ll_and_mask = sign;
8692 : else
8693 1 : ll_and_mask &= sign;
8694 66 : if (l_xor)
8695 : {
8696 1 : if (ll_bitsize != lr_bitsize)
8697 1 : return 0;
8698 0 : if (!lr_and_mask.get_precision ())
8699 0 : lr_and_mask = sign;
8700 : else
8701 0 : lr_and_mask &= sign;
8702 0 : if (l_const.get_precision ())
8703 0 : l_const &= wide_int::from (lr_and_mask,
8704 0 : l_const.get_precision (), UNSIGNED);
8705 : }
8706 66 : }
8707 :
8708 55083 : if (rsignbit)
8709 : {
8710 183 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8711 183 : if (rsignbit > rl_bitsize && rl_unsignedp)
8712 0 : sign <<= 1;
8713 183 : if (!rl_and_mask.get_precision ())
8714 183 : rl_and_mask = sign;
8715 : else
8716 0 : rl_and_mask &= sign;
8717 183 : if (r_xor)
8718 : {
8719 16 : if (rl_bitsize != rr_bitsize)
8720 0 : return 0;
8721 16 : if (!rr_and_mask.get_precision ())
8722 16 : rr_and_mask = sign;
8723 : else
8724 0 : rr_and_mask &= sign;
8725 16 : if (r_const.get_precision ())
8726 24 : r_const &= wide_int::from (rr_and_mask,
8727 12 : r_const.get_precision (), UNSIGNED);
8728 : }
8729 183 : }
8730 :
8731 : /* If either comparison code is not correct for our logical operation,
8732 : fail. However, we can convert a one-bit comparison against zero into
8733 : the opposite comparison against that bit being set in the field. */
8734 :
8735 55083 : wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
8736 55083 : if (lcode != wanted_code)
8737 : {
8738 5070 : if (l_const.get_precision ()
8739 4896 : && l_const == 0
8740 1655 : && ll_and_mask.get_precision ()
8741 5463 : && wi::popcount (ll_and_mask) == 1)
8742 : {
8743 : /* Make the left operand unsigned, since we are only interested
8744 : in the value of one bit. Otherwise we are doing the wrong
8745 : thing below. */
8746 235 : ll_unsignedp = 1;
8747 235 : l_const = ll_and_mask;
8748 : }
8749 : else
8750 4835 : return 0;
8751 : }
8752 :
8753 : /* This is analogous to the code for l_const above. */
8754 50248 : if (rcode != wanted_code)
8755 : {
8756 992 : if (r_const.get_precision ()
8757 992 : && r_const == 0
8758 953 : && rl_and_mask.get_precision ()
8759 1869 : && wi::popcount (rl_and_mask) == 1)
8760 : {
8761 534 : rl_unsignedp = 1;
8762 534 : r_const = rl_and_mask;
8763 : }
8764 : else
8765 458 : return 0;
8766 : }
8767 :
8768 : /* This will be bumped to 2 if any of the field pairs crosses an
8769 : alignment boundary, so the merged compare has to be done in two
8770 : parts. */
8771 49790 : int parts = 1;
8772 : /* Set to true if the second combined compare should come first,
8773 : e.g., because the second original compare accesses a word that
8774 : the first one doesn't, and the combined compares access those in
8775 : cmp[0]. */
8776 49790 : bool first1 = false;
8777 : /* Set to true if the first original compare is not the one being
8778 : split. */
8779 49790 : bool maybe_separate = false;
8780 :
8781 : /* The following 2-dimensional arrays use the first index to
8782 : identify left(0)- vs right(1)-hand compare operands, and the
8783 : second one to identify merged compare parts. */
8784 : /* The memory loads or constants to be compared. */
8785 49790 : tree ld_arg[2][2];
8786 : /* The first bit of the corresponding inner object that the
8787 : corresponding LD_ARG covers. */
8788 49790 : HOST_WIDE_INT bitpos[2][2];
8789 : /* The bit count starting at BITPOS that the corresponding LD_ARG
8790 : covers. */
8791 49790 : HOST_WIDE_INT bitsiz[2][2];
8792 : /* The number of bits by which LD_ARG has already been shifted
8793 : right, WRT mask. */
8794 49790 : HOST_WIDE_INT shifted[2][2];
8795 : /* The number of bits by which both LD_ARG and MASK need shifting to
8796 : bring its least-significant bit to bit zero. */
8797 49790 : HOST_WIDE_INT toshift[2][2];
8798 : /* An additional mask to be applied to LD_ARG, to remove any bits
8799 : that may have been loaded for use in another compare, but that
8800 : don't belong in the corresponding compare. */
8801 597480 : wide_int xmask[2][2] = {};
8802 :
8803 : /* The combined compare or compares. */
8804 49790 : tree cmp[2];
8805 :
8806 : /* Consider we're comparing two non-contiguous fields of packed
8807 : structs, both aligned at 32-bit boundaries:
8808 :
8809 : ll_arg: an 8-bit field at offset 0
8810 : lr_arg: a 16-bit field at offset 2
8811 :
8812 : rl_arg: an 8-bit field at offset 1
8813 : rr_arg: a 16-bit field at offset 3
8814 :
8815 : We'll have r_split_load, because rr_arg straddles across an
8816 : alignment boundary.
8817 :
8818 : We'll want to have:
8819 :
8820 : bitpos = { { 0, 0 }, { 0, 32 } }
8821 : bitsiz = { { 32, 32 }, { 32, 8 } }
8822 :
8823 : And, for little-endian:
8824 :
8825 : shifted = { { 0, 0 }, { 0, 32 } }
8826 : toshift = { { 0, 24 }, { 0, 0 } }
8827 :
8828 : Or, for big-endian:
8829 :
8830 : shifted = { { 0, 0 }, { 8, 0 } }
8831 : toshift = { { 8, 0 }, { 0, 0 } }
8832 : */
8833 :
8834 : /* See if we can find a mode that contains both fields being compared on
8835 : the left. If we can't, fail. Otherwise, update all constants and masks
8836 : to be relative to a field of that size. */
8837 49790 : first_bit = MIN (ll_bitpos, rl_bitpos);
8838 49790 : end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
8839 49790 : HOST_WIDE_INT ll_align = TYPE_ALIGN (TREE_TYPE (ll_inner));
8840 49790 : poly_uint64 ll_end_region = 0;
8841 49790 : if (TYPE_SIZE (TREE_TYPE (ll_inner))
8842 49790 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (ll_inner))))
8843 49790 : ll_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (ll_inner)));
8844 49790 : if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region,
8845 49790 : ll_align, BITS_PER_WORD, volatilep, &lnmode))
8846 : l_split_load = false;
8847 : /* ??? If ll and rl share the same load, reuse that?
8848 : See PR 118206 -> gcc.dg/field-merge-18.c */
8849 : else
8850 : {
8851 : /* Consider the possibility of recombining loads if any of the
8852 : fields straddles across an alignment boundary, so that either
8853 : part can be loaded along with the other field. Since we
8854 : limit access modes to BITS_PER_WORD, don't exceed that,
8855 : otherwise on a 32-bit host and a 64-bit-aligned data
8856 : structure, we'll fail the above for a field that straddles
8857 : across two words, and would fail here for not even trying to
8858 : split it at between 32-bit words. */
8859 46592 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
8860 49442 : (MIN (ll_align, BITS_PER_WORD),
8861 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8862 :
8863 46592 : if (boundary < 0
8864 219 : || !get_best_mode (boundary - first_bit, first_bit, 0, ll_end_region,
8865 : ll_align, BITS_PER_WORD, volatilep, &lnmode)
8866 46769 : || !get_best_mode (end_bit - boundary, boundary, 0, ll_end_region,
8867 177 : ll_align, BITS_PER_WORD, volatilep, &lnmode2))
8868 : {
8869 49223 : if (ll_align <= BITS_PER_WORD)
8870 : return 0;
8871 :
8872 : /* As a last resort, try double-word access modes. This
8873 : enables us to deal with misaligned double-word fields
8874 : that straddle across 3 separate words. */
8875 1859 : boundary = compute_split_boundary_from_align
8876 1951 : (MIN (ll_align, 2 * BITS_PER_WORD),
8877 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8878 1859 : if (boundary < 0
8879 0 : || !get_best_mode (boundary - first_bit, first_bit,
8880 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8881 : volatilep, &lnmode)
8882 1859 : || !get_best_mode (end_bit - boundary, boundary,
8883 0 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8884 : volatilep, &lnmode2))
8885 : return 0;
8886 : }
8887 :
8888 : /* If we can't have a single load, but can with two, figure out whether
8889 : the two compares can be separated, i.e., whether the entirety of the
8890 : first original compare is encompassed by the entirety of the first
8891 : combined compare. If the first original compare is past the alignment
8892 : boundary, arrange to compare that range first, by setting first1
8893 : (meaning make cmp[1] first, instead of cmp[0]). */
8894 177 : l_split_load = true;
8895 177 : parts = 2;
8896 177 : if (ll_bitpos >= boundary)
8897 : maybe_separate = first1 = true;
8898 132 : else if (ll_bitpos + ll_bitsize <= boundary)
8899 32 : maybe_separate = true;
8900 : }
8901 :
8902 3375 : lnbitsize = GET_MODE_BITSIZE (lnmode);
8903 3375 : lnbitpos = first_bit & ~ (lnbitsize - 1);
8904 : /* Avoid situations that the code below can't handle. */
8905 3375 : if (lnbitpos < 0)
8906 : return 0;
8907 :
8908 : /* Choose the type for the combined compare. Even if we're splitting loads,
8909 : make it wide enough to hold both. */
8910 3375 : if (l_split_load)
8911 354 : lnbitsize += GET_MODE_BITSIZE (lnmode2);
8912 3375 : lntype = build_nonstandard_integer_type (lnbitsize, 1);
8913 3375 : if (!lntype)
8914 : return NULL_TREE;
8915 3375 : lnprec = TYPE_PRECISION (lntype);
8916 3375 : xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
8917 :
8918 : /* Adjust bit ranges for reverse endianness. */
8919 3375 : if (ll_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8920 : {
8921 6 : xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
8922 6 : xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
8923 : }
8924 :
8925 : /* Adjust masks to match the positions in the combined lntype. */
8926 6750 : wide_int ll_mask, rl_mask, r_mask;
8927 3375 : if (ll_and_mask.get_precision ())
8928 4300 : ll_mask = wi::lshift (wide_int::from (ll_and_mask, lnprec, UNSIGNED),
8929 2150 : xll_bitpos);
8930 : else
8931 1225 : ll_mask = wi::shifted_mask (xll_bitpos, ll_bitsize, false, lnprec);
8932 3375 : if (rl_and_mask.get_precision ())
8933 3968 : rl_mask = wi::lshift (wide_int::from (rl_and_mask, lnprec, UNSIGNED),
8934 1984 : xrl_bitpos);
8935 : else
8936 1391 : rl_mask = wi::shifted_mask (xrl_bitpos, rl_bitsize, false, lnprec);
8937 :
8938 : /* When we set l_const, we also set r_const. */
8939 3375 : gcc_checking_assert (!l_const.get_precision () == !r_const.get_precision ());
8940 :
8941 : /* Adjust right-hand constants in both original comparisons to match width
8942 : and bit position. */
8943 3375 : if (l_const.get_precision ())
8944 : {
8945 : /* Before clipping upper bits of the right-hand operand of the compare,
8946 : check that they're sign or zero extensions, depending on how the
8947 : left-hand operand would be extended. If it is unsigned, or if there's
8948 : a mask that zeroes out extension bits, whether because we've checked
8949 : for upper bits in the mask and did not set ll_signbit, or because the
8950 : sign bit itself is masked out, check that the right-hand operand is
8951 : zero-extended. */
8952 1983 : bool l_non_ext_bits = false;
8953 1983 : if (ll_bitsize < lr_bitsize)
8954 : {
8955 44 : wide_int zext = wi::zext (l_const, ll_bitsize);
8956 88 : if ((ll_unsignedp
8957 32 : || (ll_and_mask.get_precision ()
8958 4 : && (!ll_signbit
8959 52 : || ((ll_and_mask & wi::mask (ll_bitsize - 1, true, ll_bitsize))
8960 8 : == 0)))
8961 164 : ? zext : wi::sext (l_const, ll_bitsize)) == l_const)
8962 44 : l_const = zext;
8963 : else
8964 : l_non_ext_bits = true;
8965 44 : }
8966 : /* We're doing bitwise equality tests, so don't bother with sign
8967 : extensions. */
8968 1983 : l_const = wide_int::from (l_const, lnprec, UNSIGNED);
8969 1983 : if (ll_and_mask.get_precision ())
8970 1163 : l_const &= wide_int::from (ll_and_mask, lnprec, UNSIGNED);
8971 1983 : l_const <<= xll_bitpos;
8972 5949 : if (l_non_ext_bits || (l_const & ~ll_mask) != 0)
8973 : {
8974 0 : warning_at (lloc, OPT_Wtautological_compare,
8975 : "comparison is always %d", wanted_code == NE_EXPR);
8976 :
8977 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
8978 : }
8979 :
8980 : /* Before clipping upper bits of the right-hand operand of the compare,
8981 : check that they're sign or zero extensions, depending on how the
8982 : left-hand operand would be extended. */
8983 1983 : bool r_non_ext_bits = false;
8984 1983 : if (rl_bitsize < rr_bitsize)
8985 : {
8986 15 : wide_int zext = wi::zext (r_const, rl_bitsize);
8987 30 : if ((rl_unsignedp
8988 11 : || (rl_and_mask.get_precision ()
8989 4 : && (!rl_signbit
8990 21 : || ((rl_and_mask & wi::mask (rl_bitsize - 1, true, rl_bitsize))
8991 6 : == 0)))
8992 56 : ? zext : wi::sext (r_const, rl_bitsize)) == r_const)
8993 15 : r_const = zext;
8994 : else
8995 : r_non_ext_bits = true;
8996 15 : }
8997 1983 : r_const = wide_int::from (r_const, lnprec, UNSIGNED);
8998 1983 : if (rl_and_mask.get_precision ())
8999 1038 : r_const &= wide_int::from (rl_and_mask, lnprec, UNSIGNED);
9000 1983 : r_const <<= xrl_bitpos;
9001 5949 : if (r_non_ext_bits || (r_const & ~rl_mask) != 0)
9002 : {
9003 0 : warning_at (rloc, OPT_Wtautological_compare,
9004 : "comparison is always %d", wanted_code == NE_EXPR);
9005 :
9006 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
9007 : }
9008 :
9009 : /* If there is something in common between the masks, those bits of the
9010 : constants must be the same. If not, the combined condition cannot be
9011 : met, and the result is known. Test for this to avoid generating
9012 : incorrect code below. */
9013 1983 : wide_int mask = ll_mask & rl_mask;
9014 1983 : if (mask != 0
9015 2031 : && (l_const & mask) != (r_const & mask))
9016 : {
9017 0 : if (wanted_code == NE_EXPR)
9018 0 : return constant_boolean_node (true, truth_type);
9019 : else
9020 0 : return constant_boolean_node (false, truth_type);
9021 : }
9022 :
9023 : /* The constants are combined so as to line up with the loaded field, so
9024 : tentatively use the same parameters for the second combined
9025 : compare. */
9026 1983 : ld_arg[1][0] = wide_int_to_tree (lntype, l_const | r_const);
9027 1983 : toshift[1][0] = MIN (xll_bitpos, xrl_bitpos);
9028 1983 : shifted[1][0] = 0;
9029 1983 : bitpos[1][0] = lnbitpos;
9030 1983 : bitsiz[1][0] = lnbitsize;
9031 :
9032 1983 : if (parts > 1)
9033 49 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9034 : shifted[1], xmask[1],
9035 49 : lnbitpos + GET_MODE_BITSIZE (lnmode),
9036 : lr_reversep);
9037 :
9038 : /* No masking needed, we know the full constants. */
9039 1983 : r_mask = wi::mask (0, true, lnprec);
9040 :
9041 : /* If the compiler thinks this is used uninitialized below, it's
9042 : because it can't realize that parts can only be 2 when
9043 : comparing with constants if l_split_load is also true. This
9044 : just silences the warning. */
9045 1983 : rnbitpos = 0;
9046 1983 : }
9047 :
9048 : /* Likewise, if the right sides are not constant, align them for the combined
9049 : compare. Also, disallow this optimization if a size, signedness or
9050 : storage order mismatch occurs between the left and right sides. */
9051 : else
9052 : {
9053 1392 : if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
9054 1306 : || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
9055 1306 : || ll_reversep != lr_reversep
9056 : /* Make sure the two fields on the right
9057 : correspond to the left without being swapped. */
9058 1306 : || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
9059 217 : return 0;
9060 :
9061 1183 : bool r_split_load;
9062 1183 : scalar_int_mode rnmode2;
9063 :
9064 : /* Figure out how to load the bits for the right-hand size of the
9065 : combined compare. As in the left-hand size, we may have to split it,
9066 : and then we use two separate compares. */
9067 1183 : first_bit = MIN (lr_bitpos, rr_bitpos);
9068 1183 : end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
9069 1183 : HOST_WIDE_INT lr_align = TYPE_ALIGN (TREE_TYPE (lr_inner));
9070 1183 : poly_uint64 lr_end_region = 0;
9071 1183 : if (TYPE_SIZE (TREE_TYPE (lr_inner))
9072 1183 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (lr_inner))))
9073 1183 : lr_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (lr_inner)));
9074 1183 : if (!get_best_mode (end_bit - first_bit, first_bit, 0, lr_end_region,
9075 1183 : lr_align, BITS_PER_WORD, volatilep, &rnmode))
9076 : {
9077 : /* Consider the possibility of recombining loads if any of the
9078 : fields straddles across an alignment boundary, so that either
9079 : part can be loaded along with the other field. */
9080 138 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
9081 138 : (lr_align, lr_bitpos, lr_bitsize, rr_bitpos, rr_bitsize);
9082 :
9083 138 : if (boundary < 0
9084 : /* If we're to split both, make sure the split point is
9085 : the same. */
9086 130 : || (l_split_load
9087 128 : && (boundary - lr_bitpos
9088 128 : != (lnbitpos + GET_MODE_BITSIZE (lnmode)) - ll_bitpos))
9089 130 : || !get_best_mode (boundary - first_bit, first_bit,
9090 : 0, lr_end_region,
9091 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode)
9092 268 : || !get_best_mode (end_bit - boundary, boundary, 0, lr_end_region,
9093 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode2))
9094 : return 0;
9095 :
9096 130 : r_split_load = true;
9097 130 : parts = 2;
9098 130 : if (lr_bitpos >= boundary)
9099 : maybe_separate = first1 = true;
9100 88 : else if (lr_bitpos + lr_bitsize <= boundary)
9101 29 : maybe_separate = true;
9102 : }
9103 : else
9104 : r_split_load = false;
9105 :
9106 : /* Find a type that can hold the entire right-hand operand. */
9107 1175 : rnbitsize = GET_MODE_BITSIZE (rnmode);
9108 1175 : rnbitpos = first_bit & ~ (rnbitsize - 1);
9109 1175 : if (r_split_load)
9110 260 : rnbitsize += GET_MODE_BITSIZE (rnmode2);
9111 1175 : rntype = build_nonstandard_integer_type (rnbitsize, 1);
9112 1175 : if (!rntype)
9113 : return 0;
9114 1175 : rnprec = TYPE_PRECISION (rntype);
9115 1175 : xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
9116 :
9117 : /* Adjust for reversed endianness. */
9118 1175 : if (lr_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
9119 : {
9120 0 : xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
9121 0 : xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
9122 : }
9123 :
9124 : /* Adjust the masks to match the combined type, and combine them. */
9125 1175 : wide_int lr_mask, rr_mask;
9126 1175 : if (lr_and_mask.get_precision ())
9127 1972 : lr_mask = wi::lshift (wide_int::from (lr_and_mask, rnprec, UNSIGNED),
9128 986 : xlr_bitpos);
9129 : else
9130 189 : lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec);
9131 1175 : if (rr_and_mask.get_precision ())
9132 1890 : rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED),
9133 945 : xrr_bitpos);
9134 : else
9135 230 : rr_mask = wi::shifted_mask (xrr_bitpos, rr_bitsize, false, rnprec);
9136 1175 : r_mask = lr_mask | rr_mask;
9137 :
9138 : /* Load the right-hand operand of the combined compare. */
9139 1175 : toshift[1][0] = MIN (xlr_bitpos, xrr_bitpos);
9140 1175 : shifted[1][0] = 0;
9141 :
9142 1175 : if (!r_split_load)
9143 : {
9144 1045 : bitpos[1][0] = rnbitpos;
9145 1045 : bitsiz[1][0] = rnbitsize;
9146 2090 : ld_arg[1][0] = make_bit_field_load (ll_loc[3], lr_inner, lr_arg,
9147 1045 : rntype, rnbitsize, rnbitpos,
9148 : lr_unsignedp || rr_unsignedp,
9149 : lr_reversep, lr_load);
9150 : }
9151 :
9152 : /* ... and the second part of the right-hand operand if needed. */
9153 1175 : if (parts > 1)
9154 : {
9155 130 : if (r_split_load)
9156 : {
9157 130 : gimple *point[2];
9158 130 : point[0] = lr_load;
9159 130 : point[1] = rr_load;
9160 130 : build_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9161 : shifted[1], rl_loc[3], lr_inner, lr_arg,
9162 : rnmode, rnmode2, rnbitpos, lr_reversep, point);
9163 : }
9164 : else
9165 0 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9166 : shifted[1], xmask[1],
9167 0 : lnbitpos + GET_MODE_BITSIZE (lnmode)
9168 0 : - ll_bitpos + lr_bitpos, lr_reversep);
9169 : }
9170 1175 : }
9171 :
9172 : /* Now issue the loads for the left-hand combined operand/s. */
9173 6316 : wide_int l_mask = ll_mask | rl_mask;
9174 3158 : toshift[0][0] = MIN (xll_bitpos, xrl_bitpos);
9175 3158 : shifted[0][0] = 0;
9176 :
9177 3158 : if (!l_split_load)
9178 : {
9179 2981 : bitpos[0][0] = lnbitpos;
9180 2981 : bitsiz[0][0] = lnbitsize;
9181 5962 : ld_arg[0][0] = make_bit_field_load (ll_loc[3], ll_inner, ll_arg,
9182 2981 : lntype, lnbitsize, lnbitpos,
9183 : ll_unsignedp || rl_unsignedp,
9184 : ll_reversep, ll_load);
9185 : }
9186 :
9187 3158 : if (parts > 1)
9188 : {
9189 179 : if (l_split_load)
9190 : {
9191 177 : gimple *point[2];
9192 177 : point[0] = ll_load;
9193 177 : point[1] = rl_load;
9194 177 : build_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9195 : shifted[0], rl_loc[3], ll_inner, ll_arg,
9196 : lnmode, lnmode2, lnbitpos, ll_reversep, point);
9197 : }
9198 : else
9199 2 : reuse_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9200 : shifted[0], xmask[0],
9201 2 : rnbitpos + GET_MODE_BITSIZE (rnmode)
9202 2 : - lr_bitpos + ll_bitpos, ll_reversep);
9203 : }
9204 :
9205 : /* Compute the compares. */
9206 6495 : for (int i = 0; i < parts; i++)
9207 : {
9208 3337 : tree op[2] = { ld_arg[0][i], ld_arg[1][i] };
9209 10011 : wide_int mask[2] = { l_mask, r_mask };
9210 3337 : location_t *locs[2] = { i ? rl_loc : ll_loc, i ? rr_loc : lr_loc };
9211 :
9212 : /* Figure out the masks, and unshare the original operands. */
9213 10011 : for (int j = 0; j < 2; j++)
9214 : {
9215 6674 : unsigned prec = TYPE_PRECISION (TREE_TYPE (op[j]));
9216 6674 : op[j] = unshare_expr (op[j]);
9217 :
9218 : /* Mask out the bits belonging to the other part. */
9219 6674 : if (xmask[j][i].get_precision ())
9220 102 : mask[j] &= xmask[j][i];
9221 :
9222 6674 : if (shifted[j][i])
9223 : {
9224 307 : wide_int shift = wide_int::from (shifted[j][i], prec, UNSIGNED);
9225 307 : mask[j] = wi::lrshift (mask[j], shift);
9226 307 : }
9227 6674 : mask[j] = wide_int::from (mask[j], prec, UNSIGNED);
9228 : }
9229 :
9230 : /* Line up the operands for a compare. */
9231 3337 : HOST_WIDE_INT shift = (toshift[0][i] - toshift[1][i]);
9232 :
9233 3337 : if (shift)
9234 : {
9235 54 : int j;
9236 54 : if (shift > 0)
9237 : j = 0;
9238 : else
9239 : {
9240 52 : j = 1;
9241 52 : shift = -shift;
9242 : }
9243 :
9244 54 : tree shiftsz = bitsize_int (shift);
9245 54 : op[j] = fold_build2_loc (locs[j][1], RSHIFT_EXPR, TREE_TYPE (op[j]),
9246 : op[j], shiftsz);
9247 54 : mask[j] = wi::lrshift (mask[j], shift);
9248 : }
9249 :
9250 : /* Convert to the smaller type before masking out unwanted
9251 : bits. */
9252 3337 : tree type = TREE_TYPE (op[0]);
9253 3337 : if (type != TREE_TYPE (op[1]))
9254 : {
9255 188 : int j = (TYPE_PRECISION (type)
9256 188 : < TYPE_PRECISION (TREE_TYPE (op[1])));
9257 188 : if (!j)
9258 89 : type = TREE_TYPE (op[1]);
9259 188 : op[j] = fold_convert_loc (locs[j][0], type, op[j]);
9260 188 : mask[j] = wide_int::from (mask[j], TYPE_PRECISION (type), UNSIGNED);
9261 : }
9262 :
9263 : /* Apply masks. */
9264 10011 : for (int j = 0; j < 2; j++)
9265 6674 : if (mask[j] != wi::mask (0, true, mask[j].get_precision ()))
9266 2688 : op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type,
9267 5376 : op[j], wide_int_to_tree (type, mask[j]));
9268 :
9269 6495 : cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type,
9270 : op[0], op[1]);
9271 10011 : }
9272 :
9273 : /* Reorder the compares if needed. */
9274 3158 : if (first1)
9275 45 : std::swap (cmp[0], cmp[1]);
9276 :
9277 : /* Prepare to return the resulting compares. Combine two parts if
9278 : needed. */
9279 3158 : if (parts == 1)
9280 2979 : result = cmp[0];
9281 179 : else if (!separatep || !maybe_separate)
9282 : {
9283 : /* Only fold if any of the cmp is known, otherwise we may lose the
9284 : sequence point, and that may prevent further optimizations. */
9285 173 : if (TREE_CODE (cmp[0]) == INTEGER_CST
9286 137 : || TREE_CODE (cmp[1]) == INTEGER_CST)
9287 37 : result = fold_build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9288 : else
9289 136 : result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9290 : }
9291 : else
9292 : {
9293 6 : result = cmp[0];
9294 6 : *separatep = cmp[1];
9295 : }
9296 :
9297 3158 : return result;
9298 439460 : }
9299 :
9300 : /* Try to simplify the AND of two comparisons, specified by
9301 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9302 : If this can be simplified to a single expression (without requiring
9303 : introducing more SSA variables to hold intermediate values),
9304 : return the resulting tree. Otherwise return NULL_TREE.
9305 : If the result expression is non-null, it has boolean type. */
9306 :
9307 : tree
9308 635693 : maybe_fold_and_comparisons (tree type,
9309 : enum tree_code code1, tree op1a, tree op1b,
9310 : enum tree_code code2, tree op2a, tree op2b,
9311 : basic_block outer_cond_bb)
9312 : {
9313 635693 : if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9314 : outer_cond_bb))
9315 : return t;
9316 :
9317 633986 : if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b,
9318 : outer_cond_bb))
9319 : return t;
9320 :
9321 633960 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1,
9322 : op1a, op1b, code2, op2a,
9323 : op2b, outer_cond_bb))
9324 : return t;
9325 :
9326 : return NULL_TREE;
9327 : }
9328 :
9329 : /* Helper function for or_comparisons_1: try to simplify the OR of the
9330 : ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
9331 : If INVERT is true, invert the value of VAR before doing the OR.
9332 : Return NULL_EXPR if we can't simplify this to a single expression. */
9333 :
9334 : static tree
9335 63506 : or_var_with_comparison (tree type, tree var, bool invert,
9336 : enum tree_code code2, tree op2a, tree op2b,
9337 : basic_block outer_cond_bb)
9338 : {
9339 63506 : tree t;
9340 63506 : gimple *stmt = SSA_NAME_DEF_STMT (var);
9341 :
9342 : /* We can only deal with variables whose definitions are assignments. */
9343 63506 : if (!is_gimple_assign (stmt))
9344 : return NULL_TREE;
9345 :
9346 : /* If we have an inverted comparison, apply DeMorgan's law and rewrite
9347 : !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
9348 : Then we only have to consider the simpler non-inverted cases. */
9349 63326 : if (invert)
9350 24323 : t = and_var_with_comparison_1 (type, stmt,
9351 : invert_tree_comparison (code2, false),
9352 : op2a, op2b, outer_cond_bb);
9353 : else
9354 39003 : t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
9355 : outer_cond_bb);
9356 63326 : return canonicalize_bool (t, invert);
9357 : }
9358 :
9359 : /* Try to simplify the OR of the ssa variable defined by the assignment
9360 : STMT with the comparison specified by (OP2A CODE2 OP2B).
9361 : Return NULL_EXPR if we can't simplify this to a single expression. */
9362 :
9363 : static tree
9364 164187 : or_var_with_comparison_1 (tree type, gimple *stmt,
9365 : enum tree_code code2, tree op2a, tree op2b,
9366 : basic_block outer_cond_bb)
9367 : {
9368 164187 : tree var = gimple_assign_lhs (stmt);
9369 164187 : tree true_test_var = NULL_TREE;
9370 164187 : tree false_test_var = NULL_TREE;
9371 164187 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
9372 :
9373 : /* Check for identities like (var OR (var != 0)) => true . */
9374 164187 : if (TREE_CODE (op2a) == SSA_NAME
9375 164187 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
9376 : {
9377 34902 : if ((code2 == NE_EXPR && integer_zerop (op2b))
9378 93097 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
9379 : {
9380 28444 : true_test_var = op2a;
9381 28444 : if (var == true_test_var)
9382 : return var;
9383 : }
9384 6377 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
9385 52655 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
9386 : {
9387 13123 : false_test_var = op2a;
9388 13123 : if (var == false_test_var)
9389 0 : return boolean_true_node;
9390 : }
9391 : }
9392 :
9393 : /* If the definition is a comparison, recurse on it. */
9394 164187 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
9395 : {
9396 971 : tree t = or_comparisons_1 (type, innercode,
9397 : gimple_assign_rhs1 (stmt),
9398 : gimple_assign_rhs2 (stmt),
9399 : code2, op2a, op2b, outer_cond_bb);
9400 971 : if (t)
9401 : return t;
9402 : }
9403 :
9404 : /* If the definition is an AND or OR expression, we may be able to
9405 : simplify by reassociating. */
9406 164170 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
9407 164170 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
9408 : {
9409 73659 : tree inner1 = gimple_assign_rhs1 (stmt);
9410 73659 : tree inner2 = gimple_assign_rhs2 (stmt);
9411 73659 : gimple *s;
9412 73659 : tree t;
9413 73659 : tree partial = NULL_TREE;
9414 73659 : bool is_or = (innercode == BIT_IOR_EXPR);
9415 :
9416 : /* Check for boolean identities that don't require recursive examination
9417 : of inner1/inner2:
9418 : inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
9419 : inner1 OR (inner1 AND inner2) => inner1
9420 : !inner1 OR (inner1 OR inner2) => true
9421 : !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
9422 : */
9423 73659 : if (inner1 == true_test_var)
9424 0 : return (is_or ? var : inner1);
9425 73659 : else if (inner2 == true_test_var)
9426 0 : return (is_or ? var : inner2);
9427 73659 : else if (inner1 == false_test_var)
9428 0 : return (is_or
9429 0 : ? boolean_true_node
9430 0 : : or_var_with_comparison (type, inner2, false, code2, op2a,
9431 0 : op2b, outer_cond_bb));
9432 73659 : else if (inner2 == false_test_var)
9433 0 : return (is_or
9434 0 : ? boolean_true_node
9435 0 : : or_var_with_comparison (type, inner1, false, code2, op2a,
9436 0 : op2b, outer_cond_bb));
9437 :
9438 : /* Next, redistribute/reassociate the OR across the inner tests.
9439 : Compute the first partial result, (inner1 OR (op2a code op2b)) */
9440 73659 : if (TREE_CODE (inner1) == SSA_NAME
9441 73659 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
9442 72436 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9443 127860 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9444 : gimple_assign_rhs1 (s),
9445 : gimple_assign_rhs2 (s),
9446 : code2, op2a, op2b,
9447 : outer_cond_bb)))
9448 : {
9449 : /* Handle the OR case, where we are reassociating:
9450 : (inner1 OR inner2) OR (op2a code2 op2b)
9451 : => (t OR inner2)
9452 : If the partial result t is a constant, we win. Otherwise
9453 : continue on to try reassociating with the other inner test. */
9454 5971 : if (is_or)
9455 : {
9456 94 : if (integer_onep (t))
9457 0 : return boolean_true_node;
9458 94 : else if (integer_zerop (t))
9459 : return inner2;
9460 : }
9461 :
9462 : /* Handle the AND case, where we are redistributing:
9463 : (inner1 AND inner2) OR (op2a code2 op2b)
9464 : => (t AND (inner2 OR (op2a code op2b))) */
9465 5877 : else if (integer_zerop (t))
9466 0 : return boolean_false_node;
9467 :
9468 : /* Save partial result for later. */
9469 : partial = t;
9470 : }
9471 :
9472 : /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
9473 73659 : if (TREE_CODE (inner2) == SSA_NAME
9474 73659 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
9475 72724 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9476 142881 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9477 : gimple_assign_rhs1 (s),
9478 : gimple_assign_rhs2 (s),
9479 : code2, op2a, op2b,
9480 : outer_cond_bb)))
9481 : {
9482 : /* Handle the OR case, where we are reassociating:
9483 : (inner1 OR inner2) OR (op2a code2 op2b)
9484 : => (inner1 OR t)
9485 : => (t OR partial) */
9486 5602 : if (is_or)
9487 : {
9488 75 : if (integer_zerop (t))
9489 : return inner1;
9490 75 : else if (integer_onep (t))
9491 1 : return boolean_true_node;
9492 : /* If both are the same, we can apply the identity
9493 : (x OR x) == x. */
9494 74 : else if (partial && same_bool_result_p (t, partial))
9495 7 : return t;
9496 : }
9497 :
9498 : /* Handle the AND case, where we are redistributing:
9499 : (inner1 AND inner2) OR (op2a code2 op2b)
9500 : => (t AND (inner1 OR (op2a code2 op2b)))
9501 : => (t AND partial) */
9502 : else
9503 : {
9504 5527 : if (integer_zerop (t))
9505 0 : return boolean_false_node;
9506 5527 : else if (partial)
9507 : {
9508 : /* We already got a simplification for the other
9509 : operand to the redistributed AND expression. The
9510 : interesting case is when at least one is true.
9511 : Or, if both are the same, we can apply the identity
9512 : (x AND x) == x. */
9513 19 : if (integer_onep (partial))
9514 : return t;
9515 18 : else if (integer_onep (t))
9516 : return partial;
9517 4 : else if (same_bool_result_p (t, partial))
9518 0 : return t;
9519 : }
9520 : }
9521 : }
9522 : }
9523 : return NULL_TREE;
9524 : }
9525 :
9526 : /* Try to simplify the OR of two comparisons defined by
9527 : (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
9528 : If this can be done without constructing an intermediate value,
9529 : return the resulting tree; otherwise NULL_TREE is returned.
9530 : This function is deliberately asymmetric as it recurses on SSA_DEFs
9531 : in the first comparison but not the second. */
9532 :
9533 : static tree
9534 1217064 : or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
9535 : enum tree_code code2, tree op2a, tree op2b,
9536 : basic_block outer_cond_bb)
9537 : {
9538 1217064 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
9539 :
9540 : /* First check for ((x CODE1 y) OR (x CODE2 y)). */
9541 1217064 : if (operand_equal_p (op1a, op2a, 0)
9542 1217064 : && operand_equal_p (op1b, op2b, 0))
9543 : {
9544 : /* Result will be either NULL_TREE, or a combined comparison. */
9545 13188 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9546 : TRUTH_ORIF_EXPR, code1, code2,
9547 : truth_type, op1a, op1b);
9548 13188 : if (t)
9549 : return t;
9550 : }
9551 :
9552 : /* Likewise the swapped case of the above. */
9553 1203908 : if (operand_equal_p (op1a, op2b, 0)
9554 1203908 : && operand_equal_p (op1b, op2a, 0))
9555 : {
9556 : /* Result will be either NULL_TREE, or a combined comparison. */
9557 0 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9558 : TRUTH_ORIF_EXPR, code1,
9559 : swap_tree_comparison (code2),
9560 : truth_type, op1a, op1b);
9561 0 : if (t)
9562 : return t;
9563 : }
9564 :
9565 : /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
9566 : NAME's definition is a truth value. See if there are any simplifications
9567 : that can be done against the NAME's definition. */
9568 1203908 : if (TREE_CODE (op1a) == SSA_NAME
9569 1203489 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
9570 1615567 : && (integer_zerop (op1b) || integer_onep (op1b)))
9571 : {
9572 46419 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
9573 107625 : || (code1 == NE_EXPR && integer_onep (op1b)));
9574 103152 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
9575 103152 : switch (gimple_code (stmt))
9576 : {
9577 63311 : case GIMPLE_ASSIGN:
9578 : /* Try to simplify by copy-propagating the definition. */
9579 63311 : return or_var_with_comparison (type, op1a, invert, code2, op2a,
9580 63311 : op2b, outer_cond_bb);
9581 :
9582 15100 : case GIMPLE_PHI:
9583 : /* If every argument to the PHI produces the same result when
9584 : ORed with the second comparison, we win.
9585 : Do not do this unless the type is bool since we need a bool
9586 : result here anyway. */
9587 15100 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
9588 : {
9589 : tree result = NULL_TREE;
9590 : unsigned i;
9591 991 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
9592 : {
9593 991 : tree arg = gimple_phi_arg_def (stmt, i);
9594 :
9595 : /* If this PHI has itself as an argument, ignore it.
9596 : If all the other args produce the same result,
9597 : we're still OK. */
9598 991 : if (arg == gimple_phi_result (stmt))
9599 0 : continue;
9600 991 : else if (TREE_CODE (arg) == INTEGER_CST)
9601 : {
9602 773 : if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
9603 : {
9604 355 : if (!result)
9605 215 : result = boolean_true_node;
9606 140 : else if (!integer_onep (result))
9607 : return NULL_TREE;
9608 : }
9609 418 : else if (!result)
9610 196 : result = fold_build2 (code2, boolean_type_node,
9611 : op2a, op2b);
9612 222 : else if (!same_bool_comparison_p (result,
9613 : code2, op2a, op2b))
9614 : return NULL_TREE;
9615 : }
9616 218 : else if (TREE_CODE (arg) == SSA_NAME
9617 218 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
9618 : {
9619 218 : tree temp;
9620 218 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
9621 : /* In simple cases we can look through PHI nodes,
9622 : but we have to be careful with loops.
9623 : See PR49073. */
9624 218 : if (! dom_info_available_p (CDI_DOMINATORS)
9625 218 : || gimple_bb (def_stmt) == gimple_bb (stmt)
9626 436 : || dominated_by_p (CDI_DOMINATORS,
9627 218 : gimple_bb (def_stmt),
9628 218 : gimple_bb (stmt)))
9629 : return NULL_TREE;
9630 195 : temp = or_var_with_comparison (type, arg, invert, code2,
9631 : op2a, op2b, outer_cond_bb);
9632 195 : if (!temp)
9633 : return NULL_TREE;
9634 0 : else if (!result)
9635 : result = temp;
9636 0 : else if (!same_bool_result_p (result, temp))
9637 : return NULL_TREE;
9638 : }
9639 : else
9640 : return NULL_TREE;
9641 : }
9642 : return result;
9643 : }
9644 :
9645 : default:
9646 : break;
9647 : }
9648 : }
9649 : return NULL_TREE;
9650 : }
9651 :
9652 : /* Try to simplify the OR of two comparisons, specified by
9653 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9654 : If this can be simplified to a single expression (without requiring
9655 : introducing more SSA variables to hold intermediate values),
9656 : return the resulting tree. Otherwise return NULL_TREE.
9657 : If the result expression is non-null, it has boolean type. */
9658 :
9659 : tree
9660 614616 : maybe_fold_or_comparisons (tree type,
9661 : enum tree_code code1, tree op1a, tree op1b,
9662 : enum tree_code code2, tree op2a, tree op2b,
9663 : basic_block outer_cond_bb)
9664 : {
9665 614616 : if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9666 : outer_cond_bb))
9667 : return t;
9668 :
9669 601477 : if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b,
9670 : outer_cond_bb))
9671 : return t;
9672 :
9673 601472 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1,
9674 : op1a, op1b, code2, op2a,
9675 : op2b, outer_cond_bb))
9676 : return t;
9677 :
9678 : return NULL_TREE;
9679 : }
9680 :
9681 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
9682 :
9683 : Either NULL_TREE, a simplified but non-constant or a constant
9684 : is returned.
9685 :
9686 : ??? This should go into a gimple-fold-inline.h file to be eventually
9687 : privatized with the single valueize function used in the various TUs
9688 : to avoid the indirect function call overhead. */
9689 :
9690 : tree
9691 433209770 : gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
9692 : tree (*gvalueize) (tree))
9693 : {
9694 433209770 : gimple_match_op res_op;
9695 : /* ??? The SSA propagators do not correctly deal with following SSA use-def
9696 : edges if there are intermediate VARYING defs. For this reason
9697 : do not follow SSA edges here even though SCCVN can technically
9698 : just deal fine with that. */
9699 433209770 : if (gimple_simplify (stmt, &res_op, NULL, gvalueize, valueize))
9700 : {
9701 56995005 : tree res = NULL_TREE;
9702 56995005 : if (gimple_simplified_result_is_gimple_val (&res_op))
9703 34849573 : res = res_op.ops[0];
9704 22145432 : else if (mprts_hook)
9705 7718784 : res = mprts_hook (&res_op);
9706 42568357 : if (res)
9707 : {
9708 36744251 : if (dump_file && dump_flags & TDF_DETAILS)
9709 : {
9710 9454 : fprintf (dump_file, "Match-and-simplified ");
9711 9454 : print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
9712 9454 : fprintf (dump_file, " to ");
9713 9454 : print_generic_expr (dump_file, res);
9714 9454 : fprintf (dump_file, "\n");
9715 : }
9716 : return res;
9717 : }
9718 : }
9719 :
9720 396465519 : location_t loc = gimple_location (stmt);
9721 396465519 : switch (gimple_code (stmt))
9722 : {
9723 342994885 : case GIMPLE_ASSIGN:
9724 342994885 : {
9725 342994885 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
9726 :
9727 342994885 : switch (get_gimple_rhs_class (subcode))
9728 : {
9729 117143781 : case GIMPLE_SINGLE_RHS:
9730 117143781 : {
9731 117143781 : tree rhs = gimple_assign_rhs1 (stmt);
9732 117143781 : enum tree_code_class kind = TREE_CODE_CLASS (subcode);
9733 :
9734 117143781 : if (TREE_CODE (rhs) == SSA_NAME)
9735 : {
9736 : /* If the RHS is an SSA_NAME, return its known constant value,
9737 : if any. */
9738 11083089 : return (*valueize) (rhs);
9739 : }
9740 : /* Handle propagating invariant addresses into address
9741 : operations. */
9742 106060692 : else if (TREE_CODE (rhs) == ADDR_EXPR
9743 106060692 : && !is_gimple_min_invariant (rhs))
9744 : {
9745 6387346 : poly_int64 offset = 0;
9746 6387346 : tree base;
9747 6387346 : base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (rhs, 0),
9748 : &offset,
9749 : valueize);
9750 6387346 : if (base
9751 6387346 : && (CONSTANT_CLASS_P (base)
9752 5724414 : || decl_address_invariant_p (base)))
9753 199619 : return build_invariant_address (TREE_TYPE (rhs),
9754 199619 : base, offset);
9755 : }
9756 99673346 : else if (TREE_CODE (rhs) == CONSTRUCTOR
9757 1121948 : && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
9758 101255618 : && known_eq (CONSTRUCTOR_NELTS (rhs),
9759 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
9760 : {
9761 437634 : unsigned i, nelts;
9762 437634 : tree val;
9763 :
9764 437634 : nelts = CONSTRUCTOR_NELTS (rhs);
9765 437634 : tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
9766 979110 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
9767 : {
9768 529493 : val = (*valueize) (val);
9769 529493 : if (TREE_CODE (val) == INTEGER_CST
9770 447013 : || TREE_CODE (val) == REAL_CST
9771 425651 : || TREE_CODE (val) == FIXED_CST)
9772 103842 : vec.quick_push (val);
9773 : else
9774 : return NULL_TREE;
9775 : }
9776 :
9777 11983 : return vec.build ();
9778 437634 : }
9779 105423439 : if (subcode == OBJ_TYPE_REF)
9780 : {
9781 405754 : tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
9782 : /* If callee is constant, we can fold away the wrapper. */
9783 405754 : if (is_gimple_min_invariant (val))
9784 : return val;
9785 : }
9786 :
9787 105423189 : if (kind == tcc_reference)
9788 : {
9789 70049910 : if ((TREE_CODE (rhs) == VIEW_CONVERT_EXPR
9790 67761768 : || TREE_CODE (rhs) == REALPART_EXPR
9791 66745581 : || TREE_CODE (rhs) == IMAGPART_EXPR)
9792 72240121 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9793 : {
9794 3547428 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9795 3547428 : return fold_unary_loc (EXPR_LOCATION (rhs),
9796 3547428 : TREE_CODE (rhs),
9797 7094856 : TREE_TYPE (rhs), val);
9798 : }
9799 66502482 : else if (TREE_CODE (rhs) == BIT_FIELD_REF
9800 66502482 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9801 : {
9802 726976 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9803 726976 : return fold_ternary_loc (EXPR_LOCATION (rhs),
9804 726976 : TREE_CODE (rhs),
9805 726976 : TREE_TYPE (rhs), val,
9806 726976 : TREE_OPERAND (rhs, 1),
9807 1453952 : TREE_OPERAND (rhs, 2));
9808 : }
9809 65775506 : else if (TREE_CODE (rhs) == MEM_REF
9810 65775506 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9811 : {
9812 13588247 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9813 13588247 : if (TREE_CODE (val) == ADDR_EXPR
9814 13588247 : && is_gimple_min_invariant (val))
9815 : {
9816 975665 : tree tem = fold_build2 (MEM_REF, TREE_TYPE (rhs),
9817 : unshare_expr (val),
9818 : TREE_OPERAND (rhs, 1));
9819 975665 : if (tem)
9820 65775506 : rhs = tem;
9821 : }
9822 : }
9823 65775506 : return fold_const_aggregate_ref_1 (rhs, valueize);
9824 : }
9825 35373279 : else if (kind == tcc_declaration)
9826 7849220 : return get_symbol_constant_value (rhs);
9827 : return rhs;
9828 : }
9829 :
9830 : case GIMPLE_UNARY_RHS:
9831 : return NULL_TREE;
9832 :
9833 169529251 : case GIMPLE_BINARY_RHS:
9834 : /* Translate &x + CST into an invariant form suitable for
9835 : further propagation. */
9836 169529251 : if (subcode == POINTER_PLUS_EXPR)
9837 : {
9838 25849949 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9839 25849949 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9840 25849949 : if (TREE_CODE (op0) == ADDR_EXPR
9841 5873545 : && TREE_CODE (op1) == INTEGER_CST)
9842 : {
9843 576579 : tree off = fold_convert (ptr_type_node, op1);
9844 576579 : return build1_loc
9845 1153158 : (loc, ADDR_EXPR, TREE_TYPE (op0),
9846 576579 : fold_build2 (MEM_REF,
9847 : TREE_TYPE (TREE_TYPE (op0)),
9848 576579 : unshare_expr (op0), off));
9849 : }
9850 : }
9851 : /* Canonicalize bool != 0 and bool == 0 appearing after
9852 : valueization. While gimple_simplify handles this
9853 : it can get confused by the ~X == 1 -> X == 0 transform
9854 : which we cant reduce to a SSA name or a constant
9855 : (and we have no way to tell gimple_simplify to not
9856 : consider those transforms in the first place). */
9857 143679302 : else if (subcode == EQ_EXPR
9858 143679302 : || subcode == NE_EXPR)
9859 : {
9860 3471091 : tree lhs = gimple_assign_lhs (stmt);
9861 3471091 : tree op0 = gimple_assign_rhs1 (stmt);
9862 3471091 : if (useless_type_conversion_p (TREE_TYPE (lhs),
9863 3471091 : TREE_TYPE (op0)))
9864 : {
9865 26682 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9866 26682 : op0 = (*valueize) (op0);
9867 26682 : if (TREE_CODE (op0) == INTEGER_CST)
9868 706 : std::swap (op0, op1);
9869 26682 : if (TREE_CODE (op1) == INTEGER_CST
9870 26682 : && ((subcode == NE_EXPR && integer_zerop (op1))
9871 2344 : || (subcode == EQ_EXPR && integer_onep (op1))))
9872 323 : return op0;
9873 : }
9874 : }
9875 : return NULL_TREE;
9876 :
9877 761940 : case GIMPLE_TERNARY_RHS:
9878 761940 : {
9879 : /* Handle ternary operators that can appear in GIMPLE form. */
9880 761940 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9881 761940 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9882 761940 : tree op2 = (*valueize) (gimple_assign_rhs3 (stmt));
9883 761940 : return fold_ternary_loc (loc, subcode,
9884 761940 : TREE_TYPE (gimple_assign_lhs (stmt)),
9885 761940 : op0, op1, op2);
9886 : }
9887 :
9888 0 : default:
9889 0 : gcc_unreachable ();
9890 : }
9891 : }
9892 :
9893 14748602 : case GIMPLE_CALL:
9894 14748602 : {
9895 14748602 : tree fn;
9896 14748602 : gcall *call_stmt = as_a <gcall *> (stmt);
9897 :
9898 14748602 : if (gimple_call_internal_p (stmt))
9899 : {
9900 1347963 : enum tree_code subcode = ERROR_MARK;
9901 1347963 : switch (gimple_call_internal_fn (stmt))
9902 : {
9903 : case IFN_UBSAN_CHECK_ADD:
9904 : subcode = PLUS_EXPR;
9905 : break;
9906 8220 : case IFN_UBSAN_CHECK_SUB:
9907 8220 : subcode = MINUS_EXPR;
9908 8220 : break;
9909 6847 : case IFN_UBSAN_CHECK_MUL:
9910 6847 : subcode = MULT_EXPR;
9911 6847 : break;
9912 144613 : case IFN_BUILTIN_EXPECT:
9913 144613 : {
9914 144613 : tree arg0 = gimple_call_arg (stmt, 0);
9915 144613 : tree op0 = (*valueize) (arg0);
9916 144613 : if (TREE_CODE (op0) == INTEGER_CST)
9917 : return op0;
9918 113183 : return NULL_TREE;
9919 : }
9920 : default:
9921 : return NULL_TREE;
9922 : }
9923 23250 : tree arg0 = gimple_call_arg (stmt, 0);
9924 23250 : tree arg1 = gimple_call_arg (stmt, 1);
9925 23250 : tree op0 = (*valueize) (arg0);
9926 23250 : tree op1 = (*valueize) (arg1);
9927 :
9928 23250 : if (TREE_CODE (op0) != INTEGER_CST
9929 2553 : || TREE_CODE (op1) != INTEGER_CST)
9930 : {
9931 22728 : switch (subcode)
9932 : {
9933 6747 : case MULT_EXPR:
9934 : /* x * 0 = 0 * x = 0 without overflow. */
9935 6747 : if (integer_zerop (op0) || integer_zerop (op1))
9936 20 : return build_zero_cst (TREE_TYPE (arg0));
9937 : break;
9938 7878 : case MINUS_EXPR:
9939 : /* y - y = 0 without overflow. */
9940 7878 : if (operand_equal_p (op0, op1, 0))
9941 0 : return build_zero_cst (TREE_TYPE (arg0));
9942 : break;
9943 : default:
9944 : break;
9945 : }
9946 : }
9947 23230 : tree res
9948 23230 : = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1);
9949 23230 : if (res
9950 3070 : && TREE_CODE (res) == INTEGER_CST
9951 23752 : && !TREE_OVERFLOW (res))
9952 0 : return res;
9953 : return NULL_TREE;
9954 : }
9955 :
9956 13400639 : fn = (*valueize) (gimple_call_fn (stmt));
9957 13400639 : if (TREE_CODE (fn) == ADDR_EXPR
9958 12753067 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
9959 12753003 : && fndecl_built_in_p (TREE_OPERAND (fn, 0))
9960 19617476 : && gimple_builtin_call_types_compatible_p (stmt,
9961 6216837 : TREE_OPERAND (fn, 0)))
9962 : {
9963 6114744 : tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
9964 6114744 : tree retval;
9965 6114744 : unsigned i;
9966 18954117 : for (i = 0; i < gimple_call_num_args (stmt); ++i)
9967 12839373 : args[i] = (*valueize) (gimple_call_arg (stmt, i));
9968 6114744 : retval = fold_builtin_call_array (loc,
9969 : gimple_call_return_type (call_stmt),
9970 : fn, gimple_call_num_args (stmt), args);
9971 6114744 : if (retval)
9972 : {
9973 : /* fold_call_expr wraps the result inside a NOP_EXPR. */
9974 61713 : STRIP_NOPS (retval);
9975 61713 : retval = fold_convert (gimple_call_return_type (call_stmt),
9976 : retval);
9977 : }
9978 : return retval;
9979 : }
9980 : return NULL_TREE;
9981 : }
9982 :
9983 : default:
9984 : return NULL_TREE;
9985 : }
9986 : }
9987 :
9988 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
9989 : Returns NULL_TREE if folding to a constant is not possible, otherwise
9990 : returns a constant according to is_gimple_min_invariant. */
9991 :
9992 : tree
9993 4371 : gimple_fold_stmt_to_constant (gimple *stmt, tree (*valueize) (tree))
9994 : {
9995 4371 : tree res = gimple_fold_stmt_to_constant_1 (stmt, valueize);
9996 4371 : if (res && is_gimple_min_invariant (res))
9997 2369 : return res;
9998 : return NULL_TREE;
9999 : }
10000 :
10001 :
10002 : /* The following set of functions are supposed to fold references using
10003 : their constant initializers. */
10004 :
10005 : /* See if we can find constructor defining value of BASE.
10006 : When we know the constructor with constant offset (such as
10007 : base is array[40] and we do know constructor of array), then
10008 : BIT_OFFSET is adjusted accordingly.
10009 :
10010 : As a special case, return error_mark_node when constructor
10011 : is not explicitly available, but it is known to be zero
10012 : such as 'static const int a;'. */
10013 : static tree
10014 125449029 : get_base_constructor (tree base, poly_int64 *bit_offset,
10015 : tree (*valueize)(tree))
10016 : {
10017 125548304 : poly_int64 bit_offset2, size, max_size;
10018 125548304 : bool reverse;
10019 :
10020 125548304 : if (TREE_CODE (base) == MEM_REF)
10021 : {
10022 133438376 : poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
10023 66719188 : if (!boff.to_shwi (bit_offset))
10024 66348970 : return NULL_TREE;
10025 :
10026 66718841 : if (valueize
10027 66718841 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
10028 34934671 : base = valueize (TREE_OPERAND (base, 0));
10029 66718841 : if (!base || TREE_CODE (base) != ADDR_EXPR)
10030 : return NULL_TREE;
10031 370218 : base = TREE_OPERAND (base, 0);
10032 : }
10033 58829116 : else if (valueize
10034 30477924 : && TREE_CODE (base) == SSA_NAME)
10035 0 : base = valueize (base);
10036 :
10037 : /* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its
10038 : DECL_INITIAL. If BASE is a nested reference into another
10039 : ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
10040 : the inner reference. */
10041 59199334 : switch (TREE_CODE (base))
10042 : {
10043 51494270 : case VAR_DECL:
10044 51494270 : case CONST_DECL:
10045 51494270 : {
10046 51494270 : tree init = ctor_for_folding (base);
10047 :
10048 : /* Our semantic is exact opposite of ctor_for_folding;
10049 : NULL means unknown, while error_mark_node is 0. */
10050 51494270 : if (init == error_mark_node)
10051 : return NULL_TREE;
10052 1278062 : if (!init)
10053 1174 : return error_mark_node;
10054 : return init;
10055 : }
10056 :
10057 99275 : case VIEW_CONVERT_EXPR:
10058 99275 : return get_base_constructor (TREE_OPERAND (base, 0),
10059 99275 : bit_offset, valueize);
10060 :
10061 359273 : case ARRAY_REF:
10062 359273 : case COMPONENT_REF:
10063 359273 : base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
10064 : &reverse);
10065 359273 : if (!known_size_p (max_size) || maybe_ne (size, max_size))
10066 : return NULL_TREE;
10067 298758 : *bit_offset += bit_offset2;
10068 298758 : return get_base_constructor (base, bit_offset, valueize);
10069 :
10070 : case CONSTRUCTOR:
10071 : return base;
10072 :
10073 7246516 : default:
10074 7246516 : if (CONSTANT_CLASS_P (base))
10075 96750 : return base;
10076 :
10077 : return NULL_TREE;
10078 : }
10079 : }
10080 :
10081 : /* CTOR is a CONSTRUCTOR of an array or vector type. Fold a reference of SIZE
10082 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10083 : the reference; otherwise the type of the referenced element is used instead.
10084 : When SIZE is zero, attempt to fold a reference to the entire element OFFSET
10085 : refers to. Increment *SUBOFF by the bit offset of the accessed element. */
10086 :
10087 : static tree
10088 692145 : fold_array_ctor_reference (tree type, tree ctor,
10089 : unsigned HOST_WIDE_INT offset,
10090 : unsigned HOST_WIDE_INT size,
10091 : tree from_decl,
10092 : unsigned HOST_WIDE_INT *suboff)
10093 : {
10094 692145 : offset_int low_bound;
10095 692145 : offset_int elt_size;
10096 692145 : offset_int access_index;
10097 692145 : tree domain_type = NULL_TREE;
10098 692145 : HOST_WIDE_INT inner_offset;
10099 :
10100 : /* Compute low bound and elt size. */
10101 692145 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
10102 692145 : domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
10103 692145 : if (domain_type && TYPE_MIN_VALUE (domain_type))
10104 : {
10105 : /* Static constructors for variably sized objects make no sense. */
10106 692145 : if (TREE_CODE (TYPE_MIN_VALUE (domain_type)) != INTEGER_CST)
10107 : return NULL_TREE;
10108 692145 : low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
10109 : }
10110 : else
10111 0 : low_bound = 0;
10112 : /* Static constructors for variably sized objects make no sense. */
10113 692145 : if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))) != INTEGER_CST)
10114 : return NULL_TREE;
10115 692145 : elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
10116 :
10117 : /* When TYPE is non-null, verify that it specifies a constant-sized
10118 : access of a multiple of the array element size. Avoid division
10119 : by zero below when ELT_SIZE is zero, such as with the result of
10120 : an initializer for a zero-length array or an empty struct. */
10121 692181 : if (elt_size == 0
10122 692145 : || (type
10123 692109 : && (!TYPE_SIZE_UNIT (type)
10124 692109 : || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
10125 : return NULL_TREE;
10126 :
10127 : /* Compute the array index we look for. */
10128 692109 : access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
10129 : elt_size);
10130 692109 : access_index += low_bound;
10131 :
10132 : /* And offset within the access. */
10133 692109 : inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
10134 :
10135 692109 : unsigned HOST_WIDE_INT elt_sz = elt_size.to_uhwi ();
10136 692109 : if (size > elt_sz * BITS_PER_UNIT)
10137 : {
10138 : /* native_encode_expr constraints. */
10139 21495 : if (size > MAX_BITSIZE_MODE_ANY_MODE
10140 17522 : || size % BITS_PER_UNIT != 0
10141 17522 : || inner_offset % BITS_PER_UNIT != 0
10142 17522 : || elt_sz > MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT)
10143 : return NULL_TREE;
10144 :
10145 17522 : unsigned ctor_idx;
10146 17522 : tree val = get_array_ctor_element_at_index (ctor, access_index,
10147 : &ctor_idx);
10148 17546 : if (!val && ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10149 23 : return build_zero_cst (type);
10150 :
10151 : /* native-encode adjacent ctor elements. */
10152 17499 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10153 17499 : unsigned bufoff = 0;
10154 17499 : offset_int index = 0;
10155 17499 : offset_int max_index = access_index;
10156 17499 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10157 17499 : if (!val)
10158 1 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10159 17498 : else if (!CONSTANT_CLASS_P (val))
10160 : return NULL_TREE;
10161 17325 : if (!elt->index)
10162 : ;
10163 17190 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10164 : {
10165 18 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10166 18 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10167 : }
10168 : else
10169 17172 : index = max_index = wi::to_offset (elt->index);
10170 17325 : index = wi::umax (index, access_index);
10171 112528 : do
10172 : {
10173 112528 : if (bufoff + elt_sz > sizeof (buf))
10174 0 : elt_sz = sizeof (buf) - bufoff;
10175 112528 : int len;
10176 112528 : if (TREE_CODE (val) == RAW_DATA_CST)
10177 : {
10178 20 : gcc_assert (inner_offset == 0);
10179 20 : if (!elt->index || TREE_CODE (elt->index) != INTEGER_CST)
10180 : return NULL_TREE;
10181 40 : inner_offset = (access_index
10182 20 : - wi::to_offset (elt->index)).to_uhwi ();
10183 20 : len = MIN (sizeof (buf) - bufoff,
10184 : (unsigned) (RAW_DATA_LENGTH (val) - inner_offset));
10185 20 : memcpy (buf + bufoff, RAW_DATA_POINTER (val) + inner_offset,
10186 : len);
10187 20 : access_index += len - 1;
10188 : }
10189 : else
10190 : {
10191 225016 : len = native_encode_expr (val, buf + bufoff, elt_sz,
10192 112508 : inner_offset / BITS_PER_UNIT);
10193 112508 : if (len != (int) elt_sz - inner_offset / BITS_PER_UNIT)
10194 : return NULL_TREE;
10195 : }
10196 112528 : inner_offset = 0;
10197 112528 : bufoff += len;
10198 :
10199 112528 : access_index += 1;
10200 112528 : if (wi::cmpu (access_index, index) == 0)
10201 2 : val = elt->value;
10202 112526 : else if (wi::cmpu (access_index, max_index) > 0)
10203 : {
10204 112304 : ctor_idx++;
10205 112304 : if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10206 : {
10207 15404 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10208 15404 : ++max_index;
10209 : }
10210 : else
10211 : {
10212 96900 : elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10213 96900 : index = 0;
10214 96900 : max_index = access_index;
10215 96900 : if (!elt->index)
10216 : ;
10217 96092 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10218 : {
10219 0 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10220 0 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10221 : }
10222 : else
10223 96092 : index = max_index = wi::to_offset (elt->index);
10224 96900 : index = wi::umax (index, access_index);
10225 96900 : if (wi::cmpu (access_index, index) == 0)
10226 96895 : val = elt->value;
10227 : else
10228 5 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10229 : }
10230 : }
10231 : }
10232 112528 : while (bufoff < size / BITS_PER_UNIT);
10233 17325 : *suboff += size;
10234 17325 : return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
10235 : }
10236 :
10237 670614 : unsigned ctor_idx;
10238 670614 : if (tree val = get_array_ctor_element_at_index (ctor, access_index,
10239 : &ctor_idx))
10240 : {
10241 669451 : if (TREE_CODE (val) == RAW_DATA_CST)
10242 : {
10243 2590 : if (size != BITS_PER_UNIT || elt_sz != 1 || inner_offset != 0)
10244 : return NULL_TREE;
10245 2582 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10246 2582 : if (elt->index == NULL_TREE || TREE_CODE (elt->index) != INTEGER_CST)
10247 : return NULL_TREE;
10248 2582 : unsigned o = (access_index - wi::to_offset (elt->index)).to_uhwi ();
10249 2582 : val = build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
10250 : }
10251 669443 : if (!size && TREE_CODE (val) != CONSTRUCTOR)
10252 : {
10253 : /* For the final reference to the entire accessed element
10254 : (SIZE is zero), reset INNER_OFFSET, disegard TYPE (which
10255 : may be null) in favor of the type of the element, and set
10256 : SIZE to the size of the accessed element. */
10257 23729 : inner_offset = 0;
10258 23729 : type = TREE_TYPE (val);
10259 23729 : size = elt_sz * BITS_PER_UNIT;
10260 : }
10261 1718638 : else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
10262 468082 : && TREE_CODE (val) == CONSTRUCTOR
10263 15674 : && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
10264 : /* If this isn't the last element in the CTOR and a CTOR itself
10265 : and it does not cover the whole object we are requesting give up
10266 : since we're not set up for combining from multiple CTORs. */
10267 26 : return NULL_TREE;
10268 :
10269 669417 : *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
10270 669417 : return fold_ctor_reference (type, val, inner_offset, size, from_decl,
10271 : suboff);
10272 : }
10273 :
10274 : /* Memory not explicitly mentioned in constructor is 0 (or
10275 : the reference is out of range). */
10276 1163 : return type ? build_zero_cst (type) : NULL_TREE;
10277 : }
10278 :
10279 : /* CTOR is a CONSTRUCTOR of a record or union type. Fold a reference of SIZE
10280 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10281 : the reference; otherwise the type of the referenced member is used instead.
10282 : When SIZE is zero, attempt to fold a reference to the entire member OFFSET
10283 : refers to. Increment *SUBOFF by the bit offset of the accessed member. */
10284 :
10285 : static tree
10286 83075 : fold_nonarray_ctor_reference (tree type, tree ctor,
10287 : unsigned HOST_WIDE_INT offset,
10288 : unsigned HOST_WIDE_INT size,
10289 : tree from_decl,
10290 : unsigned HOST_WIDE_INT *suboff)
10291 : {
10292 83075 : unsigned HOST_WIDE_INT cnt;
10293 83075 : tree cfield, cval;
10294 :
10295 125184 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
10296 : {
10297 116225 : tree byte_offset = DECL_FIELD_OFFSET (cfield);
10298 116225 : tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
10299 116225 : tree field_size = DECL_SIZE (cfield);
10300 :
10301 116225 : if (!field_size)
10302 : {
10303 : /* Determine the size of the flexible array member from
10304 : the size of the initializer provided for it. */
10305 847 : field_size = TYPE_SIZE (TREE_TYPE (cval));
10306 : }
10307 :
10308 : /* Variable sized objects in static constructors makes no sense,
10309 : but field_size can be NULL for flexible array members. */
10310 116225 : gcc_assert (TREE_CODE (field_offset) == INTEGER_CST
10311 : && TREE_CODE (byte_offset) == INTEGER_CST
10312 : && (field_size != NULL_TREE
10313 : ? TREE_CODE (field_size) == INTEGER_CST
10314 : : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
10315 :
10316 : /* Compute bit offset of the field. */
10317 116225 : offset_int bitoffset
10318 116225 : = (wi::to_offset (field_offset)
10319 116225 : + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
10320 : /* Compute bit offset where the field ends. */
10321 116225 : offset_int bitoffset_end;
10322 116225 : if (field_size != NULL_TREE)
10323 116225 : bitoffset_end = bitoffset + wi::to_offset (field_size);
10324 : else
10325 0 : bitoffset_end = 0;
10326 :
10327 : /* Compute the bit offset of the end of the desired access.
10328 : As a special case, if the size of the desired access is
10329 : zero, assume the access is to the entire field (and let
10330 : the caller make any necessary adjustments by storing
10331 : the actual bounds of the field in FIELDBOUNDS). */
10332 116225 : offset_int access_end = offset_int (offset);
10333 116225 : if (size)
10334 69684 : access_end += size;
10335 : else
10336 46541 : access_end = bitoffset_end;
10337 :
10338 : /* Is there any overlap between the desired access at
10339 : [OFFSET, OFFSET+SIZE) and the offset of the field within
10340 : the object at [BITOFFSET, BITOFFSET_END)? */
10341 116225 : if (wi::cmps (access_end, bitoffset) > 0
10342 116225 : && (field_size == NULL_TREE
10343 113520 : || wi::lts_p (offset, bitoffset_end)))
10344 : {
10345 74116 : *suboff += bitoffset.to_uhwi ();
10346 :
10347 74116 : if (!size && TREE_CODE (cval) != CONSTRUCTOR)
10348 : {
10349 : /* For the final reference to the entire accessed member
10350 : (SIZE is zero), reset OFFSET, disegard TYPE (which may
10351 : be null) in favor of the type of the member, and set
10352 : SIZE to the size of the accessed member. */
10353 21344 : offset = bitoffset.to_uhwi ();
10354 21344 : type = TREE_TYPE (cval);
10355 21344 : size = (bitoffset_end - bitoffset).to_uhwi ();
10356 : }
10357 :
10358 : /* We do have overlap. Now see if the field is large enough
10359 : to cover the access. Give up for accesses that extend
10360 : beyond the end of the object or that span multiple fields. */
10361 74116 : if (wi::cmps (access_end, bitoffset_end) > 0)
10362 : return NULL_TREE;
10363 73489 : if (offset < bitoffset)
10364 : return NULL_TREE;
10365 :
10366 73489 : offset_int inner_offset = offset_int (offset) - bitoffset;
10367 :
10368 : /* Integral bit-fields are left-justified on big-endian targets, so
10369 : we must arrange for native_encode_int to start at their MSB. */
10370 73489 : if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
10371 : {
10372 73489 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
10373 : return NULL_TREE;
10374 73489 : if (BYTES_BIG_ENDIAN)
10375 : {
10376 : tree ctype = TREE_TYPE (cfield);
10377 : unsigned int encoding_size;
10378 : if (TYPE_MODE (ctype) != BLKmode)
10379 : encoding_size
10380 : = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (ctype));
10381 : else
10382 : encoding_size = TREE_INT_CST_LOW (TYPE_SIZE (ctype));
10383 : inner_offset += encoding_size - wi::to_offset (field_size);
10384 : }
10385 : }
10386 :
10387 73489 : return fold_ctor_reference (type, cval,
10388 73489 : inner_offset.to_uhwi (), size,
10389 : from_decl, suboff);
10390 : }
10391 : }
10392 :
10393 8959 : if (!type)
10394 : return NULL_TREE;
10395 :
10396 8959 : return build_zero_cst (type);
10397 : }
10398 :
10399 : /* CTOR is a value initializing memory. Fold a reference of TYPE and
10400 : bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE
10401 : is zero, attempt to fold a reference to the entire subobject
10402 : which OFFSET refers to. This is used when folding accesses to
10403 : string members of aggregates. When non-null, set *SUBOFF to
10404 : the bit offset of the accessed subobject. */
10405 :
10406 : tree
10407 1608445 : fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
10408 : const poly_uint64 &poly_size, tree from_decl,
10409 : unsigned HOST_WIDE_INT *suboff /* = NULL */)
10410 : {
10411 1608445 : tree ret;
10412 :
10413 : /* We found the field with exact match. */
10414 1608445 : if (type
10415 1608445 : && useless_type_conversion_p (type, TREE_TYPE (ctor))
10416 2300517 : && known_eq (poly_offset, 0U))
10417 690808 : return canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10418 :
10419 : /* The remaining optimizations need a constant size and offset. */
10420 917637 : unsigned HOST_WIDE_INT size, offset;
10421 917637 : if (!poly_size.is_constant (&size) || !poly_offset.is_constant (&offset))
10422 : return NULL_TREE;
10423 :
10424 : /* We are at the end of walk, see if we can view convert the
10425 : result. */
10426 917637 : if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset
10427 : /* VIEW_CONVERT_EXPR is defined only for matching sizes. */
10428 23249 : && known_eq (wi::to_poly_widest (TYPE_SIZE (type)), size)
10429 23142 : && known_eq (wi::to_poly_widest (TYPE_SIZE (TREE_TYPE (ctor))), size))
10430 : {
10431 14441 : ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10432 14441 : if (ret)
10433 : {
10434 14441 : ret = fold_unary (VIEW_CONVERT_EXPR, type, ret);
10435 14441 : if (ret)
10436 14421 : STRIP_USELESS_TYPE_CONVERSION (ret);
10437 : }
10438 : return ret;
10439 : }
10440 :
10441 : /* For constants and byte-aligned/sized reads, try to go through
10442 : native_encode/interpret. */
10443 903196 : if (CONSTANT_CLASS_P (ctor)
10444 : && BITS_PER_UNIT == 8
10445 119712 : && offset % BITS_PER_UNIT == 0
10446 119708 : && offset / BITS_PER_UNIT <= INT_MAX
10447 119676 : && size % BITS_PER_UNIT == 0
10448 119667 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10449 1022565 : && can_native_interpret_type_p (type))
10450 : {
10451 104283 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10452 208566 : int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
10453 104283 : offset / BITS_PER_UNIT);
10454 104283 : if (len > 0)
10455 103567 : return native_interpret_expr (type, buf, len);
10456 : }
10457 :
10458 : /* For constructors, try first a recursive local processing, but in any case
10459 : this requires the native storage order. */
10460 799629 : if (TREE_CODE (ctor) == CONSTRUCTOR
10461 799629 : && !(AGGREGATE_TYPE_P (TREE_TYPE (ctor))
10462 775450 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (ctor))))
10463 : {
10464 775220 : unsigned HOST_WIDE_INT dummy = 0;
10465 775220 : if (!suboff)
10466 640425 : suboff = &dummy;
10467 :
10468 775220 : tree ret;
10469 775220 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE
10470 775220 : || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE)
10471 692145 : ret = fold_array_ctor_reference (type, ctor, offset, size,
10472 : from_decl, suboff);
10473 : else
10474 83075 : ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
10475 : from_decl, suboff);
10476 :
10477 : /* Otherwise fall back to native_encode_initializer. This may be done
10478 : only from the outermost fold_ctor_reference call (because it itself
10479 : recurses into CONSTRUCTORs and doesn't update suboff). */
10480 775220 : if (ret == NULL_TREE
10481 215660 : && suboff == &dummy
10482 : && BITS_PER_UNIT == 8
10483 207305 : && offset % BITS_PER_UNIT == 0
10484 207303 : && offset / BITS_PER_UNIT <= INT_MAX
10485 207303 : && size % BITS_PER_UNIT == 0
10486 207294 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10487 978541 : && can_native_interpret_type_p (type))
10488 : {
10489 189704 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10490 379408 : int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT,
10491 189704 : offset / BITS_PER_UNIT);
10492 189704 : if (len > 0)
10493 1310 : return native_interpret_expr (type, buf, len);
10494 : }
10495 :
10496 : return ret;
10497 : }
10498 :
10499 : return NULL_TREE;
10500 : }
10501 :
10502 : /* Return the tree representing the element referenced by T if T is an
10503 : ARRAY_REF or COMPONENT_REF into constant aggregates valuezing SSA
10504 : names using VALUEIZE. Return NULL_TREE otherwise. */
10505 :
10506 : tree
10507 130709952 : fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
10508 : {
10509 130709952 : tree ctor, idx, base;
10510 130709952 : poly_int64 offset, size, max_size;
10511 130709952 : tree tem;
10512 130709952 : bool reverse;
10513 :
10514 130709952 : if (TREE_THIS_VOLATILE (t))
10515 : return NULL_TREE;
10516 :
10517 130393041 : if (DECL_P (t))
10518 300961 : return get_symbol_constant_value (t);
10519 :
10520 130092080 : tem = fold_read_from_constant_string (t);
10521 130092080 : if (tem)
10522 : return tem;
10523 :
10524 130090224 : switch (TREE_CODE (t))
10525 : {
10526 10674005 : case ARRAY_REF:
10527 10674005 : case ARRAY_RANGE_REF:
10528 : /* Constant indexes are handled well by get_base_constructor.
10529 : Only special case variable offsets.
10530 : FIXME: This code can't handle nested references with variable indexes
10531 : (they will be handled only by iteration of ccp). Perhaps we can bring
10532 : get_ref_base_and_extent here and make it use a valueize callback. */
10533 10674005 : if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
10534 6217716 : && valueize
10535 4157612 : && (idx = (*valueize) (TREE_OPERAND (t, 1)))
10536 14831617 : && poly_int_tree_p (idx))
10537 : {
10538 1683078 : tree low_bound, unit_size;
10539 :
10540 : /* If the resulting bit-offset is constant, track it. */
10541 1683078 : if ((low_bound = array_ref_low_bound (t),
10542 1683078 : poly_int_tree_p (low_bound))
10543 1683078 : && (unit_size = array_ref_element_size (t),
10544 1683078 : tree_fits_uhwi_p (unit_size)))
10545 : {
10546 1683078 : poly_offset_int woffset
10547 1683078 : = wi::sext (wi::to_poly_offset (idx)
10548 3366156 : - wi::to_poly_offset (low_bound),
10549 1683078 : TYPE_PRECISION (sizetype));
10550 1683078 : woffset *= tree_to_uhwi (unit_size);
10551 1683078 : woffset *= BITS_PER_UNIT;
10552 1683078 : if (woffset.to_shwi (&offset))
10553 : {
10554 1682947 : base = TREE_OPERAND (t, 0);
10555 1682947 : ctor = get_base_constructor (base, &offset, valueize);
10556 : /* Empty constructor. Always fold to 0. */
10557 1682947 : if (ctor == error_mark_node)
10558 1682947 : return build_zero_cst (TREE_TYPE (t));
10559 : /* Out of bound array access. Value is undefined,
10560 : but don't fold. */
10561 1682869 : if (maybe_lt (offset, 0))
10562 : return NULL_TREE;
10563 : /* We cannot determine ctor. */
10564 1682475 : if (!ctor)
10565 : return NULL_TREE;
10566 174874 : return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
10567 174874 : tree_to_uhwi (unit_size)
10568 349748 : * BITS_PER_UNIT,
10569 : base);
10570 : }
10571 : }
10572 : }
10573 : /* Fallthru. */
10574 :
10575 123467324 : case COMPONENT_REF:
10576 123467324 : case BIT_FIELD_REF:
10577 123467324 : case TARGET_MEM_REF:
10578 123467324 : case MEM_REF:
10579 123467324 : base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
10580 123467324 : ctor = get_base_constructor (base, &offset, valueize);
10581 :
10582 : /* We cannot determine ctor. */
10583 123467324 : if (!ctor)
10584 : return NULL_TREE;
10585 : /* Empty constructor. Always fold to 0. */
10586 1199840 : if (ctor == error_mark_node)
10587 1096 : return build_zero_cst (TREE_TYPE (t));
10588 : /* We do not know precise access. */
10589 1198744 : if (!known_size_p (max_size) || maybe_ne (max_size, size))
10590 : return NULL_TREE;
10591 : /* Out of bound array access. Value is undefined, but don't fold. */
10592 503213 : if (maybe_lt (offset, 0))
10593 : return NULL_TREE;
10594 : /* Access with reverse storage order. */
10595 502832 : if (reverse)
10596 : return NULL_TREE;
10597 :
10598 502832 : tem = fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, base);
10599 502832 : if (tem)
10600 : return tem;
10601 :
10602 : /* For bit field reads try to read the representative and
10603 : adjust. */
10604 178150 : if (TREE_CODE (t) == COMPONENT_REF
10605 5149 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1))
10606 178234 : && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)))
10607 : {
10608 84 : HOST_WIDE_INT csize, coffset;
10609 84 : tree field = TREE_OPERAND (t, 1);
10610 84 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
10611 168 : if (INTEGRAL_TYPE_P (TREE_TYPE (repr))
10612 83 : && size.is_constant (&csize)
10613 83 : && offset.is_constant (&coffset)
10614 83 : && (coffset % BITS_PER_UNIT != 0
10615 81 : || csize % BITS_PER_UNIT != 0)
10616 84 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
10617 : {
10618 10 : poly_int64 bitoffset;
10619 10 : poly_uint64 field_offset, repr_offset;
10620 10 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
10621 20 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
10622 10 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
10623 : else
10624 : bitoffset = 0;
10625 10 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
10626 10 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
10627 10 : HOST_WIDE_INT bitoff;
10628 10 : int diff = (TYPE_PRECISION (TREE_TYPE (repr))
10629 10 : - TYPE_PRECISION (TREE_TYPE (field)));
10630 10 : if (bitoffset.is_constant (&bitoff)
10631 10 : && bitoff >= 0
10632 10 : && bitoff <= diff)
10633 : {
10634 10 : offset -= bitoff;
10635 10 : size = tree_to_uhwi (DECL_SIZE (repr));
10636 :
10637 20 : tem = fold_ctor_reference (TREE_TYPE (repr), ctor, offset,
10638 10 : size, base);
10639 10 : if (tem && TREE_CODE (tem) == INTEGER_CST)
10640 : {
10641 10 : if (!BYTES_BIG_ENDIAN)
10642 10 : tem = wide_int_to_tree (TREE_TYPE (field),
10643 10 : wi::lrshift (wi::to_wide (tem),
10644 : bitoff));
10645 : else
10646 : tem = wide_int_to_tree (TREE_TYPE (field),
10647 : wi::lrshift (wi::to_wide (tem),
10648 : diff - bitoff));
10649 10 : return tem;
10650 : }
10651 : }
10652 : }
10653 : }
10654 : break;
10655 :
10656 1813275 : case REALPART_EXPR:
10657 1813275 : case IMAGPART_EXPR:
10658 1813275 : {
10659 1813275 : tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize);
10660 1813275 : if (c && TREE_CODE (c) == COMPLEX_CST)
10661 2774 : return fold_build1_loc (EXPR_LOCATION (t),
10662 5548 : TREE_CODE (t), TREE_TYPE (t), c);
10663 : break;
10664 : }
10665 :
10666 : default:
10667 : break;
10668 : }
10669 :
10670 : return NULL_TREE;
10671 : }
10672 :
10673 : tree
10674 63121171 : fold_const_aggregate_ref (tree t)
10675 : {
10676 63121171 : return fold_const_aggregate_ref_1 (t, NULL);
10677 : }
10678 :
10679 : /* Lookup virtual method with index TOKEN in a virtual table V
10680 : at OFFSET.
10681 : Set CAN_REFER if non-NULL to false if method
10682 : is not referable or if the virtual table is ill-formed (such as rewritten
10683 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10684 :
10685 : tree
10686 277839 : gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
10687 : tree v,
10688 : unsigned HOST_WIDE_INT offset,
10689 : bool *can_refer)
10690 : {
10691 277839 : tree vtable = v, init, fn;
10692 277839 : unsigned HOST_WIDE_INT size;
10693 277839 : unsigned HOST_WIDE_INT elt_size, access_index;
10694 277839 : tree domain_type;
10695 :
10696 277839 : if (can_refer)
10697 277839 : *can_refer = true;
10698 :
10699 : /* First of all double check we have virtual table. */
10700 277839 : if (!VAR_P (v) || !DECL_VIRTUAL_P (v))
10701 : {
10702 : /* Pass down that we lost track of the target. */
10703 0 : if (can_refer)
10704 0 : *can_refer = false;
10705 : return NULL_TREE;
10706 : }
10707 :
10708 277839 : init = ctor_for_folding (v);
10709 :
10710 : /* The virtual tables should always be born with constructors
10711 : and we always should assume that they are available for
10712 : folding. At the moment we do not stream them in all cases,
10713 : but it should never happen that ctor seem unreachable. */
10714 277839 : gcc_assert (init);
10715 277839 : if (init == error_mark_node)
10716 : {
10717 : /* Pass down that we lost track of the target. */
10718 213 : if (can_refer)
10719 213 : *can_refer = false;
10720 : return NULL_TREE;
10721 : }
10722 277626 : gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
10723 277626 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))));
10724 277626 : offset *= BITS_PER_UNIT;
10725 277626 : offset += token * size;
10726 :
10727 : /* Lookup the value in the constructor that is assumed to be array.
10728 : This is equivalent to
10729 : fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
10730 : offset, size, NULL);
10731 : but in a constant time. We expect that frontend produced a simple
10732 : array without indexed initializers. */
10733 :
10734 277626 : gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
10735 277626 : domain_type = TYPE_DOMAIN (TREE_TYPE (init));
10736 277626 : gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
10737 277626 : elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
10738 :
10739 277626 : access_index = offset / BITS_PER_UNIT / elt_size;
10740 277626 : gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);
10741 :
10742 : /* This code makes an assumption that there are no
10743 : indexed fields produced by C++ FE, so we can directly index the array. */
10744 277626 : if (access_index < CONSTRUCTOR_NELTS (init))
10745 : {
10746 277625 : fn = CONSTRUCTOR_ELT (init, access_index)->value;
10747 277625 : gcc_checking_assert (!CONSTRUCTOR_ELT (init, access_index)->index);
10748 277625 : STRIP_NOPS (fn);
10749 : }
10750 : else
10751 : fn = NULL;
10752 :
10753 : /* For type inconsistent program we may end up looking up virtual method
10754 : in virtual table that does not contain TOKEN entries. We may overrun
10755 : the virtual table and pick up a constant or RTTI info pointer.
10756 : In any case the call is undefined. */
10757 277625 : if (!fn
10758 277625 : || (TREE_CODE (fn) != ADDR_EXPR && TREE_CODE (fn) != FDESC_EXPR)
10759 549466 : || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
10760 5785 : fn = builtin_decl_unreachable ();
10761 : else
10762 : {
10763 271841 : fn = TREE_OPERAND (fn, 0);
10764 :
10765 : /* When cgraph node is missing and function is not public, we cannot
10766 : devirtualize. This can happen in WHOPR when the actual method
10767 : ends up in other partition, because we found devirtualization
10768 : possibility too late. */
10769 271841 : if (!can_refer_decl_in_current_unit_p (fn, vtable))
10770 : {
10771 36557 : if (can_refer)
10772 : {
10773 36557 : *can_refer = false;
10774 36557 : return fn;
10775 : }
10776 : return NULL_TREE;
10777 : }
10778 : }
10779 :
10780 : /* Make sure we create a cgraph node for functions we'll reference.
10781 : They can be non-existent if the reference comes from an entry
10782 : of an external vtable for example. */
10783 241069 : cgraph_node::get_create (fn);
10784 :
10785 241069 : return fn;
10786 : }
10787 :
10788 : /* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
10789 : is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
10790 : KNOWN_BINFO carries the binfo describing the true type of
10791 : OBJ_TYPE_REF_OBJECT(REF).
10792 : Set CAN_REFER if non-NULL to false if method
10793 : is not referable or if the virtual table is ill-formed (such as rewritten
10794 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10795 :
10796 : tree
10797 269125 : gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
10798 : bool *can_refer)
10799 : {
10800 269125 : unsigned HOST_WIDE_INT offset;
10801 269125 : tree v;
10802 :
10803 269125 : v = BINFO_VTABLE (known_binfo);
10804 : /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone. */
10805 269125 : if (!v)
10806 : return NULL_TREE;
10807 :
10808 269125 : if (!vtable_pointer_value_to_vtable (v, &v, &offset))
10809 : {
10810 0 : if (can_refer)
10811 0 : *can_refer = false;
10812 : return NULL_TREE;
10813 : }
10814 269125 : return gimple_get_virt_method_for_vtable (token, v, offset, can_refer);
10815 : }
10816 :
10817 : /* Given a pointer value T, return a simplified version of an
10818 : indirection through T, or NULL_TREE if no simplification is
10819 : possible. Note that the resulting type may be different from
10820 : the type pointed to in the sense that it is still compatible
10821 : from the langhooks point of view. */
10822 :
10823 : tree
10824 2539974 : gimple_fold_indirect_ref (tree t)
10825 : {
10826 2539974 : tree ptype = TREE_TYPE (t), type = TREE_TYPE (ptype);
10827 2539974 : tree sub = t;
10828 2539974 : tree subtype;
10829 :
10830 2539974 : STRIP_NOPS (sub);
10831 2539974 : subtype = TREE_TYPE (sub);
10832 2539974 : if (!POINTER_TYPE_P (subtype)
10833 2539974 : || TYPE_REF_CAN_ALIAS_ALL (ptype))
10834 : return NULL_TREE;
10835 :
10836 2538265 : if (TREE_CODE (sub) == ADDR_EXPR)
10837 : {
10838 96186 : tree op = TREE_OPERAND (sub, 0);
10839 96186 : tree optype = TREE_TYPE (op);
10840 : /* *&p => p */
10841 96186 : if (useless_type_conversion_p (type, optype))
10842 : return op;
10843 :
10844 : /* *(foo *)&fooarray => fooarray[0] */
10845 993 : if (TREE_CODE (optype) == ARRAY_TYPE
10846 307 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
10847 1300 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10848 : {
10849 54 : tree type_domain = TYPE_DOMAIN (optype);
10850 54 : tree min_val = size_zero_node;
10851 54 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10852 54 : min_val = TYPE_MIN_VALUE (type_domain);
10853 54 : if (TREE_CODE (min_val) == INTEGER_CST)
10854 54 : return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
10855 : }
10856 : /* *(foo *)&complexfoo => __real__ complexfoo */
10857 939 : else if (TREE_CODE (optype) == COMPLEX_TYPE
10858 939 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10859 4 : return fold_build1 (REALPART_EXPR, type, op);
10860 : /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
10861 935 : else if (TREE_CODE (optype) == VECTOR_TYPE
10862 935 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10863 : {
10864 26 : tree part_width = TYPE_SIZE (type);
10865 26 : tree index = bitsize_int (0);
10866 26 : return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
10867 : }
10868 : }
10869 :
10870 : /* *(p + CST) -> ... */
10871 2442988 : if (TREE_CODE (sub) == POINTER_PLUS_EXPR
10872 2442988 : && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
10873 : {
10874 34148 : tree addr = TREE_OPERAND (sub, 0);
10875 34148 : tree off = TREE_OPERAND (sub, 1);
10876 34148 : tree addrtype;
10877 :
10878 34148 : STRIP_NOPS (addr);
10879 34148 : addrtype = TREE_TYPE (addr);
10880 :
10881 : /* ((foo*)&vectorfoo)[1] -> BIT_FIELD_REF<vectorfoo,...> */
10882 34148 : if (TREE_CODE (addr) == ADDR_EXPR
10883 92 : && TREE_CODE (TREE_TYPE (addrtype)) == VECTOR_TYPE
10884 39 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype)))
10885 34176 : && tree_fits_uhwi_p (off))
10886 : {
10887 28 : unsigned HOST_WIDE_INT offset = tree_to_uhwi (off);
10888 28 : tree part_width = TYPE_SIZE (type);
10889 28 : unsigned HOST_WIDE_INT part_widthi
10890 28 : = tree_to_shwi (part_width) / BITS_PER_UNIT;
10891 28 : unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
10892 28 : tree index = bitsize_int (indexi);
10893 28 : if (known_lt (offset / part_widthi,
10894 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
10895 28 : return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
10896 : part_width, index);
10897 : }
10898 :
10899 : /* ((foo*)&complexfoo)[1] -> __imag__ complexfoo */
10900 34120 : if (TREE_CODE (addr) == ADDR_EXPR
10901 64 : && TREE_CODE (TREE_TYPE (addrtype)) == COMPLEX_TYPE
10902 34121 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype))))
10903 : {
10904 1 : tree size = TYPE_SIZE_UNIT (type);
10905 1 : if (tree_int_cst_equal (size, off))
10906 1 : return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (addr, 0));
10907 : }
10908 :
10909 : /* *(p + CST) -> MEM_REF <p, CST>. */
10910 34119 : if (TREE_CODE (addr) != ADDR_EXPR
10911 34119 : || DECL_P (TREE_OPERAND (addr, 0)))
10912 34101 : return fold_build2 (MEM_REF, type,
10913 : addr,
10914 : wide_int_to_tree (ptype, wi::to_wide (off)));
10915 : }
10916 :
10917 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
10918 2408858 : if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
10919 2507 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
10920 2411335 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
10921 : {
10922 1 : tree type_domain;
10923 1 : tree min_val = size_zero_node;
10924 1 : tree osub = sub;
10925 1 : sub = gimple_fold_indirect_ref (sub);
10926 1 : if (! sub)
10927 1 : sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
10928 1 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
10929 1 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10930 1 : min_val = TYPE_MIN_VALUE (type_domain);
10931 1 : if (TREE_CODE (min_val) == INTEGER_CST)
10932 1 : return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
10933 : }
10934 :
10935 : return NULL_TREE;
10936 : }
10937 :
10938 : /* Return true if CODE is an operation that when operating on signed
10939 : integer types involves undefined behavior on overflow and the
10940 : operation can be expressed with unsigned arithmetic. */
10941 :
10942 : bool
10943 513305 : arith_code_with_undefined_signed_overflow (tree_code code)
10944 : {
10945 513305 : switch (code)
10946 : {
10947 : case ABS_EXPR:
10948 : case PLUS_EXPR:
10949 : case MINUS_EXPR:
10950 : case MULT_EXPR:
10951 : case NEGATE_EXPR:
10952 : case POINTER_PLUS_EXPR:
10953 : return true;
10954 203119 : default:
10955 203119 : return false;
10956 : }
10957 : }
10958 :
10959 : /* Return true if STMT has an operation that operates on a signed
10960 : integer types involves undefined behavior on overflow and the
10961 : operation can be expressed with unsigned arithmetic.
10962 : Also returns true if STMT is a VCE that needs to be rewritten
10963 : if moved to be executed unconditionally. */
10964 :
10965 : bool
10966 1347825 : gimple_needing_rewrite_undefined (gimple *stmt)
10967 : {
10968 1347825 : if (!is_gimple_assign (stmt))
10969 : return false;
10970 1120033 : tree lhs = gimple_assign_lhs (stmt);
10971 1120033 : if (!lhs)
10972 : return false;
10973 1120033 : tree lhs_type = TREE_TYPE (lhs);
10974 1120033 : if (!INTEGRAL_TYPE_P (lhs_type)
10975 122512 : && !POINTER_TYPE_P (lhs_type))
10976 : return false;
10977 1082750 : tree rhs = gimple_assign_rhs1 (stmt);
10978 : /* Boolean loads need special handling as they are treated as a full MODE load
10979 : and don't mask off the bits for the precision. */
10980 1082750 : if (gimple_assign_load_p (stmt)
10981 : /* Booleans are the integral type which has this non-masking issue. */
10982 96813 : && TREE_CODE (lhs_type) == BOOLEAN_TYPE
10983 : /* Only non mode precision booleans are need the masking. */
10984 429 : && !type_has_mode_precision_p (lhs_type)
10985 : /* BFR should be the correct thing and just grab the precision. */
10986 429 : && TREE_CODE (rhs) != BIT_FIELD_REF
10987 : /* Bit-fields loads don't need a rewrite as the masking
10988 : happens for them. */
10989 1083179 : && (TREE_CODE (rhs) != COMPONENT_REF
10990 139 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1))))
10991 : return true;
10992 : /* VCE from integral types to a integral types but with
10993 : a smaller precision need to be changed into casts
10994 : to be well defined. */
10995 1082321 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
10996 199 : && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
10997 172 : && is_gimple_val (TREE_OPERAND (rhs, 0))
10998 1082493 : && TYPE_PRECISION (lhs_type)
10999 172 : < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
11000 : return true;
11001 1082153 : if (!TYPE_OVERFLOW_UNDEFINED (lhs_type))
11002 : return false;
11003 390864 : if (!arith_code_with_undefined_signed_overflow
11004 390864 : (gimple_assign_rhs_code (stmt)))
11005 : return false;
11006 : return true;
11007 : }
11008 :
11009 : /* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
11010 : operation that can be transformed to unsigned arithmetic by converting
11011 : its operand, carrying out the operation in the corresponding unsigned
11012 : type and converting the result back to the original type.
11013 :
11014 : If IN_PLACE is true, *GSI points to STMT, adjust the stmt in place and
11015 : return NULL.
11016 : Otherwise returns a sequence of statements that replace STMT and also
11017 : contain a modified form of STMT itself. */
11018 :
11019 : static gimple_seq
11020 65617 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi, gimple *stmt,
11021 : bool in_place)
11022 : {
11023 65617 : gcc_assert (gimple_needing_rewrite_undefined (stmt));
11024 65617 : if (dump_file && (dump_flags & TDF_DETAILS))
11025 : {
11026 22 : fprintf (dump_file, "rewriting stmt for being unconditional defined");
11027 22 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
11028 : }
11029 65617 : gimple_seq stmts = NULL;
11030 65617 : tree lhs = gimple_assign_lhs (stmt);
11031 :
11032 : /* Boolean loads need to be rewritten to be a load from the same mode
11033 : and then a cast to the other type so the other bits are masked off
11034 : correctly since the load was done conditionally. It is similar to the VCE
11035 : case below. */
11036 65617 : if (gimple_assign_load_p (stmt)
11037 65617 : && TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
11038 : {
11039 124 : tree rhs = gimple_assign_rhs1 (stmt);
11040 :
11041 : /* Double check that gimple_needing_rewrite_undefined was called. */
11042 : /* Bit-fields loads will do the masking so don't need the rewriting. */
11043 124 : gcc_assert (TREE_CODE (rhs) != COMPONENT_REF
11044 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1)));
11045 : /* BFR is like a bit field load and will do the correct thing. */
11046 124 : gcc_assert (TREE_CODE (lhs) != BIT_FIELD_REF);
11047 : /* Complex boolean types are not valid so REAL/IMAG part will
11048 : never show up. */
11049 124 : gcc_assert (TREE_CODE (rhs) != REALPART_EXPR
11050 : && TREE_CODE (lhs) != IMAGPART_EXPR);
11051 :
11052 124 : auto bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (rhs)));
11053 124 : tree new_type = build_nonstandard_integer_type (bits, true);
11054 124 : location_t loc = gimple_location (stmt);
11055 124 : tree mem_ref = fold_build1_loc (loc, VIEW_CONVERT_EXPR, new_type, rhs);
11056 : /* Replace the original load with a new load and a new lhs. */
11057 124 : tree new_lhs = make_ssa_name (new_type);
11058 124 : gimple_assign_set_rhs1 (stmt, mem_ref);
11059 124 : gimple_assign_set_lhs (stmt, new_lhs);
11060 :
11061 124 : if (in_place)
11062 49 : update_stmt (stmt);
11063 : else
11064 : {
11065 75 : gimple_set_modified (stmt, true);
11066 75 : gimple_seq_add_stmt (&stmts, stmt);
11067 : }
11068 :
11069 : /* Build the conversion statement. */
11070 124 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
11071 124 : if (in_place)
11072 : {
11073 49 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11074 49 : update_stmt (stmt);
11075 : }
11076 : else
11077 75 : gimple_seq_add_stmt (&stmts, cvt);
11078 124 : return stmts;
11079 : }
11080 :
11081 : /* VCE from integral types to another integral types but with
11082 : smaller precisions need to be changed into casts
11083 : to be well defined. */
11084 65493 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
11085 : {
11086 60 : tree rhs = gimple_assign_rhs1 (stmt);
11087 60 : tree new_rhs = TREE_OPERAND (rhs, 0);
11088 60 : gcc_assert (TYPE_PRECISION (TREE_TYPE (rhs))
11089 : < TYPE_PRECISION (TREE_TYPE (new_rhs)));
11090 60 : gcc_assert (is_gimple_val (new_rhs));
11091 60 : gimple_assign_set_rhs_code (stmt, NOP_EXPR);
11092 60 : gimple_assign_set_rhs1 (stmt, new_rhs);
11093 60 : if (in_place)
11094 51 : update_stmt (stmt);
11095 : else
11096 : {
11097 9 : gimple_set_modified (stmt, true);
11098 9 : gimple_seq_add_stmt (&stmts, stmt);
11099 : }
11100 60 : return stmts;
11101 : }
11102 65433 : tree type = unsigned_type_for (TREE_TYPE (lhs));
11103 65433 : if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
11104 24 : gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
11105 : else
11106 195727 : for (unsigned i = 1; i < gimple_num_ops (stmt); ++i)
11107 : {
11108 130318 : tree op = gimple_op (stmt, i);
11109 130318 : op = gimple_convert (&stmts, type, op);
11110 130318 : gimple_set_op (stmt, i, op);
11111 : }
11112 65433 : gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
11113 65433 : if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
11114 9118 : gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
11115 65433 : gimple_set_modified (stmt, true);
11116 65433 : if (in_place)
11117 : {
11118 47634 : if (stmts)
11119 47274 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
11120 47634 : stmts = NULL;
11121 : }
11122 : else
11123 17799 : gimple_seq_add_stmt (&stmts, stmt);
11124 65433 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
11125 65433 : if (in_place)
11126 : {
11127 47634 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11128 47634 : update_stmt (stmt);
11129 : }
11130 : else
11131 17799 : gimple_seq_add_stmt (&stmts, cvt);
11132 :
11133 65433 : return stmts;
11134 : }
11135 :
11136 : void
11137 47734 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi)
11138 : {
11139 47734 : rewrite_to_defined_unconditional (gsi, gsi_stmt (*gsi), true);
11140 47734 : }
11141 :
11142 : gimple_seq
11143 17883 : rewrite_to_defined_unconditional (gimple *stmt)
11144 : {
11145 17883 : return rewrite_to_defined_unconditional (nullptr, stmt, false);
11146 : }
11147 :
11148 : /* The valueization hook we use for the gimple_build API simplification.
11149 : This makes us match fold_buildN behavior by only combining with
11150 : statements in the sequence(s) we are currently building. */
11151 :
11152 : static tree
11153 23359410 : gimple_build_valueize (tree op)
11154 : {
11155 23359410 : if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL)
11156 5548389 : return op;
11157 : return NULL_TREE;
11158 : }
11159 :
11160 : /* Helper for gimple_build to perform the final insertion of stmts on SEQ. */
11161 :
11162 : static inline void
11163 1439510 : gimple_build_insert_seq (gimple_stmt_iterator *gsi,
11164 : bool before, gsi_iterator_update update,
11165 : gimple_seq seq)
11166 : {
11167 1439510 : if (before)
11168 : {
11169 95981 : if (gsi->bb)
11170 95981 : gsi_insert_seq_before (gsi, seq, update);
11171 : else
11172 0 : gsi_insert_seq_before_without_update (gsi, seq, update);
11173 : }
11174 : else
11175 : {
11176 1343529 : if (gsi->bb)
11177 177 : gsi_insert_seq_after (gsi, seq, update);
11178 : else
11179 1343352 : gsi_insert_seq_after_without_update (gsi, seq, update);
11180 : }
11181 1439510 : }
11182 :
11183 : /* Build the expression CODE OP0 of type TYPE with location LOC,
11184 : simplifying it first if possible. Returns the built
11185 : expression value and inserts statements possibly defining it
11186 : before GSI if BEFORE is true or after GSI if false and advance
11187 : the iterator accordingly.
11188 : If gsi refers to a basic block simplifying is allowed to look
11189 : at all SSA defs while when it does not it is restricted to
11190 : SSA defs that are not associated with a basic block yet,
11191 : indicating they belong to the currently building sequence. */
11192 :
11193 : tree
11194 370043 : gimple_build (gimple_stmt_iterator *gsi,
11195 : bool before, gsi_iterator_update update,
11196 : location_t loc, enum tree_code code, tree type, tree op0)
11197 : {
11198 370043 : gimple_seq seq = NULL;
11199 370043 : tree res
11200 370043 : = gimple_simplify (code, type, op0, &seq,
11201 370043 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11202 370043 : if (!res)
11203 : {
11204 321763 : res = make_ssa_name (type);
11205 321763 : gimple *stmt;
11206 321763 : if (code == REALPART_EXPR
11207 : || code == IMAGPART_EXPR
11208 321763 : || code == VIEW_CONVERT_EXPR)
11209 16569 : stmt = gimple_build_assign (res, code, build1 (code, type, op0));
11210 : else
11211 305194 : stmt = gimple_build_assign (res, code, op0);
11212 321763 : gimple_set_location (stmt, loc);
11213 321763 : gimple_seq_add_stmt_without_update (&seq, stmt);
11214 : }
11215 370043 : gimple_build_insert_seq (gsi, before, update, seq);
11216 370043 : return res;
11217 : }
11218 :
11219 : /* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
11220 : simplifying it first if possible. Returns the built
11221 : expression value inserting any new statements at GSI honoring BEFORE
11222 : and UPDATE. */
11223 :
11224 : tree
11225 849286 : gimple_build (gimple_stmt_iterator *gsi,
11226 : bool before, gsi_iterator_update update,
11227 : location_t loc, enum tree_code code, tree type,
11228 : tree op0, tree op1)
11229 : {
11230 849286 : gimple_seq seq = NULL;
11231 849286 : tree res
11232 849286 : = gimple_simplify (code, type, op0, op1, &seq,
11233 849286 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11234 849286 : if (!res)
11235 : {
11236 742875 : res = make_ssa_name (type);
11237 742875 : gimple *stmt = gimple_build_assign (res, code, op0, op1);
11238 742875 : gimple_set_location (stmt, loc);
11239 742875 : gimple_seq_add_stmt_without_update (&seq, stmt);
11240 : }
11241 849286 : gimple_build_insert_seq (gsi, before, update, seq);
11242 849286 : return res;
11243 : }
11244 :
11245 : /* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
11246 : simplifying it first if possible. Returns the built
11247 : expression value inserting any new statements at GSI honoring BEFORE
11248 : and UPDATE. */
11249 :
11250 : tree
11251 49688 : gimple_build (gimple_stmt_iterator *gsi,
11252 : bool before, gsi_iterator_update update,
11253 : location_t loc, enum tree_code code, tree type,
11254 : tree op0, tree op1, tree op2)
11255 : {
11256 :
11257 49688 : gimple_seq seq = NULL;
11258 49688 : tree res
11259 49688 : = gimple_simplify (code, type, op0, op1, op2, &seq,
11260 49688 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11261 49688 : if (!res)
11262 : {
11263 35538 : res = make_ssa_name (type);
11264 35538 : gimple *stmt;
11265 35538 : if (code == BIT_FIELD_REF)
11266 27909 : stmt = gimple_build_assign (res, code,
11267 : build3 (code, type, op0, op1, op2));
11268 : else
11269 7629 : stmt = gimple_build_assign (res, code, op0, op1, op2);
11270 35538 : gimple_set_location (stmt, loc);
11271 35538 : gimple_seq_add_stmt_without_update (&seq, stmt);
11272 : }
11273 49688 : gimple_build_insert_seq (gsi, before, update, seq);
11274 49688 : return res;
11275 : }
11276 :
11277 : /* Build the call FN () with a result of type TYPE (or no result if TYPE is
11278 : void) with a location LOC. Returns the built expression value (or NULL_TREE
11279 : if TYPE is void) inserting any new statements at GSI honoring BEFORE
11280 : and UPDATE. */
11281 :
11282 : tree
11283 0 : gimple_build (gimple_stmt_iterator *gsi,
11284 : bool before, gsi_iterator_update update,
11285 : location_t loc, combined_fn fn, tree type)
11286 : {
11287 0 : tree res = NULL_TREE;
11288 0 : gimple_seq seq = NULL;
11289 0 : gcall *stmt;
11290 0 : if (internal_fn_p (fn))
11291 0 : stmt = gimple_build_call_internal (as_internal_fn (fn), 0);
11292 : else
11293 : {
11294 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11295 0 : stmt = gimple_build_call (decl, 0);
11296 : }
11297 0 : if (!VOID_TYPE_P (type))
11298 : {
11299 0 : res = make_ssa_name (type);
11300 0 : gimple_call_set_lhs (stmt, res);
11301 : }
11302 0 : gimple_set_location (stmt, loc);
11303 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11304 0 : gimple_build_insert_seq (gsi, before, update, seq);
11305 0 : return res;
11306 : }
11307 :
11308 : /* Build the call FN (ARG0) with a result of type TYPE
11309 : (or no result if TYPE is void) with location LOC,
11310 : simplifying it first if possible. Returns the built
11311 : expression value (or NULL_TREE if TYPE is void) inserting any new
11312 : statements at GSI honoring BEFORE and UPDATE. */
11313 :
11314 : tree
11315 25463 : gimple_build (gimple_stmt_iterator *gsi,
11316 : bool before, gsi_iterator_update update,
11317 : location_t loc, combined_fn fn,
11318 : tree type, tree arg0)
11319 : {
11320 25463 : gimple_seq seq = NULL;
11321 25463 : tree res = gimple_simplify (fn, type, arg0, &seq, gimple_build_valueize);
11322 25463 : if (!res)
11323 : {
11324 25463 : gcall *stmt;
11325 25463 : if (internal_fn_p (fn))
11326 25087 : stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
11327 : else
11328 : {
11329 376 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11330 376 : stmt = gimple_build_call (decl, 1, arg0);
11331 : }
11332 25463 : if (!VOID_TYPE_P (type))
11333 : {
11334 25087 : res = make_ssa_name (type);
11335 25087 : gimple_call_set_lhs (stmt, res);
11336 : }
11337 25463 : gimple_set_location (stmt, loc);
11338 25463 : gimple_seq_add_stmt_without_update (&seq, stmt);
11339 : }
11340 25463 : gimple_build_insert_seq (gsi, before, update, seq);
11341 25463 : return res;
11342 : }
11343 :
11344 : /* Build the call FN (ARG0, ARG1) with a result of type TYPE
11345 : (or no result if TYPE is void) with location LOC,
11346 : simplifying it first if possible. Returns the built
11347 : expression value (or NULL_TREE if TYPE is void) inserting any new
11348 : statements at GSI honoring BEFORE and UPDATE. */
11349 :
11350 : tree
11351 138 : gimple_build (gimple_stmt_iterator *gsi,
11352 : bool before, gsi_iterator_update update,
11353 : location_t loc, combined_fn fn,
11354 : tree type, tree arg0, tree arg1)
11355 : {
11356 138 : gimple_seq seq = NULL;
11357 138 : tree res = gimple_simplify (fn, type, arg0, arg1, &seq,
11358 : gimple_build_valueize);
11359 138 : if (!res)
11360 : {
11361 138 : gcall *stmt;
11362 138 : if (internal_fn_p (fn))
11363 138 : stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
11364 : else
11365 : {
11366 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11367 0 : stmt = gimple_build_call (decl, 2, arg0, arg1);
11368 : }
11369 138 : if (!VOID_TYPE_P (type))
11370 : {
11371 138 : res = make_ssa_name (type);
11372 138 : gimple_call_set_lhs (stmt, res);
11373 : }
11374 138 : gimple_set_location (stmt, loc);
11375 138 : gimple_seq_add_stmt_without_update (&seq, stmt);
11376 : }
11377 138 : gimple_build_insert_seq (gsi, before, update, seq);
11378 138 : return res;
11379 : }
11380 :
11381 : /* Build the call FN (ARG0, ARG1, ARG2) with a result of type TYPE
11382 : (or no result if TYPE is void) with location LOC,
11383 : simplifying it first if possible. Returns the built
11384 : expression value (or NULL_TREE if TYPE is void) inserting any new
11385 : statements at GSI honoring BEFORE and UPDATE. */
11386 :
11387 : tree
11388 0 : gimple_build (gimple_stmt_iterator *gsi,
11389 : bool before, gsi_iterator_update update,
11390 : location_t loc, combined_fn fn,
11391 : tree type, tree arg0, tree arg1, tree arg2)
11392 : {
11393 0 : gimple_seq seq = NULL;
11394 0 : tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
11395 : &seq, gimple_build_valueize);
11396 0 : if (!res)
11397 : {
11398 0 : gcall *stmt;
11399 0 : if (internal_fn_p (fn))
11400 0 : stmt = gimple_build_call_internal (as_internal_fn (fn),
11401 : 3, arg0, arg1, arg2);
11402 : else
11403 : {
11404 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11405 0 : stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
11406 : }
11407 0 : if (!VOID_TYPE_P (type))
11408 : {
11409 0 : res = make_ssa_name (type);
11410 0 : gimple_call_set_lhs (stmt, res);
11411 : }
11412 0 : gimple_set_location (stmt, loc);
11413 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11414 : }
11415 0 : gimple_build_insert_seq (gsi, before, update, seq);
11416 0 : return res;
11417 : }
11418 :
11419 : /* Build CODE (OP0) with a result of type TYPE (or no result if TYPE is
11420 : void) with location LOC, simplifying it first if possible. Returns the
11421 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11422 : statements at GSI honoring BEFORE and UPDATE. */
11423 :
11424 : tree
11425 21 : gimple_build (gimple_stmt_iterator *gsi,
11426 : bool before, gsi_iterator_update update,
11427 : location_t loc, code_helper code, tree type, tree op0)
11428 : {
11429 21 : if (code.is_tree_code ())
11430 0 : return gimple_build (gsi, before, update, loc, tree_code (code), type, op0);
11431 21 : return gimple_build (gsi, before, update, loc, combined_fn (code), type, op0);
11432 : }
11433 :
11434 : /* Build CODE (OP0, OP1) with a result of type TYPE (or no result if TYPE is
11435 : void) with location LOC, simplifying it first if possible. Returns the
11436 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11437 : statements at GSI honoring BEFORE and UPDATE. */
11438 :
11439 : tree
11440 24274 : gimple_build (gimple_stmt_iterator *gsi,
11441 : bool before, gsi_iterator_update update,
11442 : location_t loc, code_helper code, tree type, tree op0, tree op1)
11443 : {
11444 24274 : if (code.is_tree_code ())
11445 24136 : return gimple_build (gsi, before, update,
11446 24136 : loc, tree_code (code), type, op0, op1);
11447 138 : return gimple_build (gsi, before, update,
11448 138 : loc, combined_fn (code), type, op0, op1);
11449 : }
11450 :
11451 : /* Build CODE (OP0, OP1, OP2) with a result of type TYPE (or no result if TYPE
11452 : is void) with location LOC, simplifying it first if possible. Returns the
11453 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11454 : statements at GSI honoring BEFORE and UPDATE. */
11455 :
11456 : tree
11457 0 : gimple_build (gimple_stmt_iterator *gsi,
11458 : bool before, gsi_iterator_update update,
11459 : location_t loc, code_helper code,
11460 : tree type, tree op0, tree op1, tree op2)
11461 : {
11462 0 : if (code.is_tree_code ())
11463 0 : return gimple_build (gsi, before, update,
11464 0 : loc, tree_code (code), type, op0, op1, op2);
11465 0 : return gimple_build (gsi, before, update,
11466 0 : loc, combined_fn (code), type, op0, op1, op2);
11467 : }
11468 :
11469 : /* Build the conversion (TYPE) OP with a result of type TYPE
11470 : with location LOC if such conversion is necessary in GIMPLE,
11471 : simplifying it first.
11472 : Returns the built expression inserting any new statements
11473 : at GSI honoring BEFORE and UPDATE. */
11474 :
11475 : tree
11476 2061532 : gimple_convert (gimple_stmt_iterator *gsi,
11477 : bool before, gsi_iterator_update update,
11478 : location_t loc, tree type, tree op)
11479 : {
11480 2061532 : if (useless_type_conversion_p (type, TREE_TYPE (op)))
11481 : return op;
11482 190577 : return gimple_build (gsi, before, update, loc, NOP_EXPR, type, op);
11483 : }
11484 :
11485 : /* Build the conversion (ptrofftype) OP with a result of a type
11486 : compatible with ptrofftype with location LOC if such conversion
11487 : is necessary in GIMPLE, simplifying it first.
11488 : Returns the built expression value inserting any new statements
11489 : at GSI honoring BEFORE and UPDATE. */
11490 :
11491 : tree
11492 208 : gimple_convert_to_ptrofftype (gimple_stmt_iterator *gsi,
11493 : bool before, gsi_iterator_update update,
11494 : location_t loc, tree op)
11495 : {
11496 208 : if (ptrofftype_p (TREE_TYPE (op)))
11497 : return op;
11498 0 : return gimple_convert (gsi, before, update, loc, sizetype, op);
11499 : }
11500 :
11501 : /* Build a vector of type TYPE in which each element has the value OP.
11502 : Return a gimple value for the result, inserting any new statements
11503 : at GSI honoring BEFORE and UPDATE. */
11504 :
11505 : tree
11506 329969 : gimple_build_vector_from_val (gimple_stmt_iterator *gsi,
11507 : bool before, gsi_iterator_update update,
11508 : location_t loc, tree type, tree op)
11509 : {
11510 329969 : if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()
11511 : && !CONSTANT_CLASS_P (op))
11512 : return gimple_build (gsi, before, update,
11513 : loc, VEC_DUPLICATE_EXPR, type, op);
11514 :
11515 329969 : tree res, vec = build_vector_from_val (type, op);
11516 329969 : if (is_gimple_val (vec))
11517 : return vec;
11518 28313 : if (gimple_in_ssa_p (cfun))
11519 28313 : res = make_ssa_name (type);
11520 : else
11521 0 : res = create_tmp_reg (type);
11522 28313 : gimple_seq seq = NULL;
11523 28313 : gimple *stmt = gimple_build_assign (res, vec);
11524 28313 : gimple_set_location (stmt, loc);
11525 28313 : gimple_seq_add_stmt_without_update (&seq, stmt);
11526 28313 : gimple_build_insert_seq (gsi, before, update, seq);
11527 28313 : return res;
11528 : }
11529 :
11530 : /* Build a vector from BUILDER, handling the case in which some elements
11531 : are non-constant. Return a gimple value for the result, inserting
11532 : any new instructions to GSI honoring BEFORE and UPDATE.
11533 :
11534 : BUILDER must not have a stepped encoding on entry. This is because
11535 : the function is not geared up to handle the arithmetic that would
11536 : be needed in the variable case, and any code building a vector that
11537 : is known to be constant should use BUILDER->build () directly. */
11538 :
11539 : tree
11540 376034 : gimple_build_vector (gimple_stmt_iterator *gsi,
11541 : bool before, gsi_iterator_update update,
11542 : location_t loc, tree_vector_builder *builder)
11543 : {
11544 376034 : gcc_assert (builder->nelts_per_pattern () <= 2);
11545 376034 : unsigned int encoded_nelts = builder->encoded_nelts ();
11546 1321531 : for (unsigned int i = 0; i < encoded_nelts; ++i)
11547 1062076 : if (!CONSTANT_CLASS_P ((*builder)[i]))
11548 : {
11549 116579 : gimple_seq seq = NULL;
11550 116579 : tree type = builder->type ();
11551 116579 : unsigned int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
11552 116579 : vec<constructor_elt, va_gc> *v;
11553 116579 : vec_alloc (v, nelts);
11554 488172 : for (i = 0; i < nelts; ++i)
11555 255014 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));
11556 :
11557 116579 : tree res;
11558 116579 : if (gimple_in_ssa_p (cfun))
11559 116579 : res = make_ssa_name (type);
11560 : else
11561 0 : res = create_tmp_reg (type);
11562 116579 : gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
11563 116579 : gimple_set_location (stmt, loc);
11564 116579 : gimple_seq_add_stmt_without_update (&seq, stmt);
11565 116579 : gimple_build_insert_seq (gsi, before, update, seq);
11566 116579 : return res;
11567 : }
11568 259455 : return builder->build ();
11569 : }
11570 :
11571 : /* Emit gimple statements into &stmts that take a value given in OLD_SIZE
11572 : and generate a value guaranteed to be rounded upwards to ALIGN.
11573 :
11574 : Return the tree node representing this size, it is of TREE_TYPE TYPE. */
11575 :
11576 : tree
11577 0 : gimple_build_round_up (gimple_stmt_iterator *gsi,
11578 : bool before, gsi_iterator_update update,
11579 : location_t loc, tree type,
11580 : tree old_size, unsigned HOST_WIDE_INT align)
11581 : {
11582 0 : unsigned HOST_WIDE_INT tg_mask = align - 1;
11583 : /* tree new_size = (old_size + tg_mask) & ~tg_mask; */
11584 0 : gcc_assert (INTEGRAL_TYPE_P (type));
11585 0 : tree tree_mask = build_int_cst (type, tg_mask);
11586 0 : tree oversize = gimple_build (gsi, before, update,
11587 : loc, PLUS_EXPR, type, old_size, tree_mask);
11588 :
11589 0 : tree mask = build_int_cst (type, -align);
11590 0 : return gimple_build (gsi, before, update,
11591 0 : loc, BIT_AND_EXPR, type, oversize, mask);
11592 : }
11593 :
11594 : /* Return true if the result of assignment STMT is known to be non-negative.
11595 : DEPTH is the current nesting depth of the query. */
11596 :
11597 : static bool
11598 6137863 : gimple_assign_nonnegative_p (gimple *stmt, int depth)
11599 : {
11600 6137863 : enum tree_code code = gimple_assign_rhs_code (stmt);
11601 6137863 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
11602 6137863 : switch (get_gimple_rhs_class (code))
11603 : {
11604 453797 : case GIMPLE_UNARY_RHS:
11605 453797 : return tree_unary_nonnegative_p (gimple_assign_rhs_code (stmt),
11606 : type,
11607 : gimple_assign_rhs1 (stmt),
11608 453797 : depth);
11609 3443758 : case GIMPLE_BINARY_RHS:
11610 3443758 : return tree_binary_nonnegative_p (gimple_assign_rhs_code (stmt),
11611 : type,
11612 : gimple_assign_rhs1 (stmt),
11613 : gimple_assign_rhs2 (stmt),
11614 3443758 : depth);
11615 : case GIMPLE_TERNARY_RHS:
11616 : return false;
11617 2226574 : case GIMPLE_SINGLE_RHS:
11618 2226574 : return tree_single_nonnegative_p (gimple_assign_rhs1 (stmt),
11619 2226574 : depth);
11620 : case GIMPLE_INVALID_RHS:
11621 : break;
11622 : }
11623 0 : gcc_unreachable ();
11624 : }
11625 :
11626 : /* Return true if return value of call STMT is known to be non-negative.
11627 : DEPTH is the current nesting depth of the query. */
11628 :
11629 : static bool
11630 13626948 : gimple_call_nonnegative_p (gimple *stmt, int depth)
11631 : {
11632 13626948 : tree arg0
11633 13626948 : = gimple_call_num_args (stmt) > 0 ? gimple_call_arg (stmt, 0) : NULL_TREE;
11634 13626948 : tree arg1
11635 13626948 : = gimple_call_num_args (stmt) > 1 ? gimple_call_arg (stmt, 1) : NULL_TREE;
11636 13626948 : tree lhs = gimple_call_lhs (stmt);
11637 13626948 : return (lhs
11638 13626948 : && tree_call_nonnegative_p (TREE_TYPE (lhs),
11639 : gimple_call_combined_fn (stmt),
11640 13626948 : arg0, arg1, depth));
11641 : }
11642 :
11643 : /* Return true if return value of call STMT is known to be non-negative.
11644 : DEPTH is the current nesting depth of the query. */
11645 :
11646 : static bool
11647 959342 : gimple_phi_nonnegative_p (gimple *stmt, int depth)
11648 : {
11649 1309752 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11650 : {
11651 1304824 : tree arg = gimple_phi_arg_def (stmt, i);
11652 1304824 : if (!tree_single_nonnegative_p (arg, depth + 1))
11653 : return false;
11654 : }
11655 : return true;
11656 : }
11657 :
11658 : /* Return true if STMT is known to compute a non-negative value.
11659 : DEPTH is the current nesting depth of the query. */
11660 :
11661 : bool
11662 21406291 : gimple_stmt_nonnegative_p (gimple *stmt, int depth)
11663 : {
11664 21406291 : tree type = gimple_range_type (stmt);
11665 21406291 : if (type && frange::supports_p (type))
11666 : {
11667 1533450 : frange r;
11668 1533450 : bool sign;
11669 1533450 : if (get_global_range_query ()->range_of_stmt (r, stmt)
11670 1533450 : && r.signbit_p (sign))
11671 30363 : return !sign;
11672 1533450 : }
11673 21375928 : switch (gimple_code (stmt))
11674 : {
11675 6137863 : case GIMPLE_ASSIGN:
11676 6137863 : return gimple_assign_nonnegative_p (stmt, depth);
11677 13626948 : case GIMPLE_CALL:
11678 13626948 : return gimple_call_nonnegative_p (stmt, depth);
11679 959342 : case GIMPLE_PHI:
11680 959342 : return gimple_phi_nonnegative_p (stmt, depth);
11681 : default:
11682 : return false;
11683 : }
11684 : }
11685 :
11686 : /* Return true if the floating-point value computed by assignment STMT
11687 : is known to have an integer value. We also allow +Inf, -Inf and NaN
11688 : to be considered integer values. Return false for signaling NaN.
11689 :
11690 : DEPTH is the current nesting depth of the query. */
11691 :
11692 : static bool
11693 59447 : gimple_assign_integer_valued_real_p (gimple *stmt, int depth)
11694 : {
11695 59447 : enum tree_code code = gimple_assign_rhs_code (stmt);
11696 59447 : switch (get_gimple_rhs_class (code))
11697 : {
11698 15122 : case GIMPLE_UNARY_RHS:
11699 15122 : return integer_valued_real_unary_p (gimple_assign_rhs_code (stmt),
11700 15122 : gimple_assign_rhs1 (stmt), depth);
11701 13634 : case GIMPLE_BINARY_RHS:
11702 13634 : return integer_valued_real_binary_p (gimple_assign_rhs_code (stmt),
11703 : gimple_assign_rhs1 (stmt),
11704 13634 : gimple_assign_rhs2 (stmt), depth);
11705 : case GIMPLE_TERNARY_RHS:
11706 : return false;
11707 29536 : case GIMPLE_SINGLE_RHS:
11708 29536 : return integer_valued_real_single_p (gimple_assign_rhs1 (stmt), depth);
11709 : case GIMPLE_INVALID_RHS:
11710 : break;
11711 : }
11712 0 : gcc_unreachable ();
11713 : }
11714 :
11715 : /* Return true if the floating-point value computed by call STMT is known
11716 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11717 : considered integer values. Return false for signaling NaN.
11718 :
11719 : DEPTH is the current nesting depth of the query. */
11720 :
11721 : static bool
11722 1133 : gimple_call_integer_valued_real_p (gimple *stmt, int depth)
11723 : {
11724 1133 : tree arg0 = (gimple_call_num_args (stmt) > 0
11725 1133 : ? gimple_call_arg (stmt, 0)
11726 : : NULL_TREE);
11727 1133 : tree arg1 = (gimple_call_num_args (stmt) > 1
11728 1133 : ? gimple_call_arg (stmt, 1)
11729 : : NULL_TREE);
11730 1133 : return integer_valued_real_call_p (gimple_call_combined_fn (stmt),
11731 1133 : arg0, arg1, depth);
11732 : }
11733 :
11734 : /* Return true if the floating-point result of phi STMT is known to have
11735 : an integer value. We also allow +Inf, -Inf and NaN to be considered
11736 : integer values. Return false for signaling NaN.
11737 :
11738 : DEPTH is the current nesting depth of the query. */
11739 :
11740 : static bool
11741 1509 : gimple_phi_integer_valued_real_p (gimple *stmt, int depth)
11742 : {
11743 1672 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11744 : {
11745 1663 : tree arg = gimple_phi_arg_def (stmt, i);
11746 1663 : if (!integer_valued_real_single_p (arg, depth + 1))
11747 : return false;
11748 : }
11749 : return true;
11750 : }
11751 :
11752 : /* Return true if the floating-point value computed by STMT is known
11753 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11754 : considered integer values. Return false for signaling NaN.
11755 :
11756 : DEPTH is the current nesting depth of the query. */
11757 :
11758 : bool
11759 89492 : gimple_stmt_integer_valued_real_p (gimple *stmt, int depth)
11760 : {
11761 89492 : switch (gimple_code (stmt))
11762 : {
11763 59447 : case GIMPLE_ASSIGN:
11764 59447 : return gimple_assign_integer_valued_real_p (stmt, depth);
11765 1133 : case GIMPLE_CALL:
11766 1133 : return gimple_call_integer_valued_real_p (stmt, depth);
11767 1509 : case GIMPLE_PHI:
11768 1509 : return gimple_phi_integer_valued_real_p (stmt, depth);
11769 : default:
11770 : return false;
11771 : }
11772 : }
|