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 4468894 : can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
116 : {
117 4468894 : varpool_node *vnode;
118 4468894 : struct cgraph_node *node;
119 4468894 : symtab_node *snode;
120 :
121 4468894 : if (DECL_ABSTRACT_P (decl))
122 : return false;
123 :
124 : /* We are concerned only about static/external vars and functions. */
125 1505498 : if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
126 5569603 : || !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 4064105 : if (!TREE_PUBLIC (decl))
132 : {
133 1100933 : 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 1100888 : if (symtab->function_flags_ready)
138 : return true;
139 1063729 : snode = symtab_node::get (decl);
140 1063729 : if (!snode || !snode->definition)
141 : return false;
142 1063674 : node = dyn_cast <cgraph_node *> (snode);
143 8845 : 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 2963172 : if (!from_decl
150 490682 : || !VAR_P (from_decl)
151 489553 : || (!DECL_EXTERNAL (from_decl)
152 211144 : && (vnode = varpool_node::get (from_decl)) != NULL
153 146242 : && vnode->definition)
154 3306489 : || (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 343314 : if (DECL_VISIBILITY_SPECIFIED (decl)
162 336243 : && DECL_EXTERNAL (decl)
163 270134 : && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT
164 528879 : && (!(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 157749 : 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 111253 : if (!symtab->function_flags_ready)
183 : return true;
184 :
185 98293 : snode = symtab_node::get (decl);
186 98293 : if (!snode
187 98293 : || ((!snode->definition || DECL_EXTERNAL (decl))
188 12062 : && (!snode->in_other_partition
189 0 : || (!snode->forced_by_abi && !snode->force_output))))
190 : return false;
191 60661 : node = dyn_cast <cgraph_node *> (snode);
192 60661 : 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 15608494 : canonicalize_constructor_val (tree cval, tree from_decl)
201 : {
202 15608494 : if (CONSTANT_CLASS_P (cval))
203 : return cval;
204 :
205 9452456 : tree orig_cval = cval;
206 9452456 : STRIP_NOPS (cval);
207 9452456 : if (TREE_CODE (cval) == POINTER_PLUS_EXPR
208 9452456 : && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
209 : {
210 73201 : tree ptr = TREE_OPERAND (cval, 0);
211 73201 : if (is_gimple_min_invariant (ptr))
212 218892 : cval = build1_loc (EXPR_LOCATION (cval),
213 72964 : ADDR_EXPR, TREE_TYPE (ptr),
214 145928 : fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),
215 : ptr,
216 : fold_convert (ptr_type_node,
217 : TREE_OPERAND (cval, 1))));
218 : }
219 9452456 : if (TREE_CODE (cval) == ADDR_EXPR)
220 : {
221 5186230 : tree base = NULL_TREE;
222 5186230 : 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 5186037 : base = get_base_address (TREE_OPERAND (cval, 0));
230 5186230 : if (!base)
231 : return NULL_TREE;
232 :
233 2301596 : if (VAR_OR_FUNCTION_DECL_P (base)
234 6490813 : && !can_refer_decl_in_current_unit_p (base, from_decl))
235 : return NULL_TREE;
236 4999883 : if (TREE_TYPE (base) == error_mark_node)
237 : return NULL_TREE;
238 4999883 : 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 2300711 : 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 1303698 : cgraph_node::get_create (base);
248 : }
249 : /* Fixup types in global initializers. */
250 4999883 : if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
251 40519 : cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
252 :
253 4999883 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
254 215524 : cval = fold_convert (TREE_TYPE (orig_cval), cval);
255 : return cval;
256 : }
257 : /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0. */
258 4266226 : if (TREE_CODE (cval) == INTEGER_CST)
259 : {
260 67306 : if (TREE_OVERFLOW_P (cval))
261 0 : cval = drop_tree_overflow (cval);
262 67306 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
263 64105 : 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 20535346 : get_symbol_constant_value (tree sym)
274 : {
275 20535346 : tree val = ctor_for_folding (sym);
276 20535346 : if (val != error_mark_node)
277 : {
278 39791 : if (val)
279 : {
280 37494 : val = canonicalize_constructor_val (unshare_expr (val), sym);
281 37494 : if (val
282 37494 : && is_gimple_min_invariant (val)
283 66157 : && useless_type_conversion_p (TREE_TYPE (sym), TREE_TYPE (val)))
284 : return val;
285 : else
286 8937 : 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 2297 : if (!val
292 2297 : && is_gimple_reg_type (TREE_TYPE (sym)))
293 1960 : 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 66778076 : maybe_fold_reference (tree expr)
306 : {
307 66778076 : tree result = NULL_TREE;
308 :
309 : /* Avoid expensive fold_const_aggregate_ref early on aggregate loads
310 : and esp. replacing STRING_CSTs inline. */
311 66778076 : if (!is_gimple_reg_type (TREE_TYPE (expr)))
312 : return NULL_TREE;
313 :
314 63636870 : if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
315 62301632 : || TREE_CODE (expr) == REALPART_EXPR
316 61505657 : || TREE_CODE (expr) == IMAGPART_EXPR)
317 65365567 : && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
318 5839 : result = fold_unary_loc (EXPR_LOCATION (expr),
319 : TREE_CODE (expr),
320 5839 : TREE_TYPE (expr),
321 5839 : TREE_OPERAND (expr, 0));
322 63631031 : else if (TREE_CODE (expr) == BIT_FIELD_REF
323 63631031 : && 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 63630982 : result = fold_const_aggregate_ref (expr);
332 :
333 63636870 : if (result && is_gimple_min_invariant (result))
334 110887 : 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 265315447 : fold_gimple_assign (gimple_stmt_iterator *si)
462 : {
463 265315447 : gimple *stmt = gsi_stmt (*si);
464 265315447 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
465 265315447 : location_t loc = gimple_location (stmt);
466 :
467 265315447 : tree result = NULL_TREE;
468 :
469 265315447 : switch (get_gimple_rhs_class (subcode))
470 : {
471 176275653 : case GIMPLE_SINGLE_RHS:
472 176275653 : {
473 176275653 : tree rhs = gimple_assign_rhs1 (stmt);
474 :
475 176275653 : if (TREE_CLOBBER_P (rhs))
476 : return NULL_TREE;
477 :
478 161652000 : if (REFERENCE_CLASS_P (rhs))
479 64060905 : return maybe_fold_reference (rhs);
480 :
481 97591095 : else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
482 : {
483 182934 : tree val = OBJ_TYPE_REF_EXPR (rhs);
484 182934 : if (is_gimple_min_invariant (val))
485 : return val;
486 182903 : else if (flag_devirtualize && virtual_method_call_p (rhs))
487 : {
488 182863 : bool final;
489 182863 : vec <cgraph_node *>targets
490 182863 : = possible_polymorphic_call_targets (rhs, stmt, &final);
491 183135 : 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 97408161 : else if (TREE_CODE (rhs) == ADDR_EXPR)
519 : {
520 15501726 : tree ref = TREE_OPERAND (rhs, 0);
521 15501726 : if (TREE_CODE (ref) == MEM_REF
522 15501726 : && integer_zerop (TREE_OPERAND (ref, 1)))
523 : {
524 2676 : result = TREE_OPERAND (ref, 0);
525 2676 : if (!useless_type_conversion_p (TREE_TYPE (rhs),
526 2676 : TREE_TYPE (result)))
527 0 : result = build1 (NOP_EXPR, TREE_TYPE (rhs), result);
528 : return result;
529 : }
530 : }
531 :
532 81906435 : else if (TREE_CODE (rhs) == CONSTRUCTOR
533 81906435 : && 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 470755 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
540 466398 : if (! CONSTANT_CLASS_P (val))
541 : return NULL_TREE;
542 :
543 4357 : return build_vector_from_ctor (TREE_TYPE (rhs),
544 8714 : CONSTRUCTOR_ELTS (rhs));
545 : }
546 :
547 81533657 : else if (DECL_P (rhs)
548 81533657 : && is_gimple_reg_type (TREE_TYPE (rhs)))
549 12323885 : 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 564364 : case GIMPLE_TERNARY_RHS:
560 1128728 : result = fold_ternary_loc (loc, subcode,
561 564364 : TREE_TYPE (gimple_assign_lhs (stmt)),
562 : gimple_assign_rhs1 (stmt),
563 : gimple_assign_rhs2 (stmt),
564 : gimple_assign_rhs3 (stmt));
565 :
566 564364 : 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 135629 : gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
595 : {
596 135629 : gimple *stmt = gsi_stmt (*si_p);
597 :
598 135629 : if (gimple_has_location (stmt))
599 113510 : 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 135629 : gimple *laststore = NULL;
604 271258 : for (gimple_stmt_iterator i = gsi_last (stmts);
605 478497 : !gsi_end_p (i); gsi_prev (&i))
606 : {
607 207239 : gimple *new_stmt = gsi_stmt (i);
608 207239 : if ((gimple_assign_single_p (new_stmt)
609 131462 : && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
610 338431 : || (is_gimple_call (new_stmt)
611 14892 : && (gimple_call_flags (new_stmt)
612 14892 : & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0))
613 : {
614 2324 : tree vdef;
615 2324 : if (!laststore)
616 2318 : vdef = gimple_vdef (stmt);
617 : else
618 6 : vdef = make_ssa_name (gimple_vop (cfun), new_stmt);
619 2324 : gimple_set_vdef (new_stmt, vdef);
620 2324 : 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 135629 : tree reaching_vuse = gimple_vuse (stmt);
629 135629 : for (gimple_stmt_iterator i = gsi_start (stmts);
630 342868 : !gsi_end_p (i); gsi_next (&i))
631 : {
632 207239 : 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 207239 : if (gimple_has_mem_ops (new_stmt))
636 207237 : gimple_set_vuse (new_stmt, reaching_vuse);
637 207239 : gimple_set_modified (new_stmt, true);
638 620312 : 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 135629 : if (reaching_vuse
645 226439 : && reaching_vuse == gimple_vuse (stmt))
646 : {
647 89419 : tree vdef = gimple_vdef (stmt);
648 89419 : if (vdef
649 1523 : && TREE_CODE (vdef) == SSA_NAME)
650 : {
651 1467 : unlink_stmt_vdef (stmt);
652 1467 : release_ssa_name (vdef);
653 : }
654 : }
655 :
656 : /* Finally replace the original statement with the sequence. */
657 135629 : gsi_replace_with_seq (si_p, stmts, false);
658 135629 : }
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 2450 : finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
666 : gimple *stmt)
667 : {
668 2450 : tree lhs = gimple_call_lhs (stmt);
669 2450 : gimple_call_set_lhs (new_stmt, lhs);
670 2450 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
671 797 : SSA_NAME_DEF_STMT (lhs) = new_stmt;
672 2450 : gimple_move_vops (new_stmt, stmt);
673 2450 : gimple_set_location (new_stmt, gimple_location (stmt));
674 2450 : if (gimple_block (new_stmt) == NULL_TREE)
675 1 : gimple_set_block (new_stmt, gimple_block (stmt));
676 2450 : gsi_replace (si_p, new_stmt, false);
677 2450 : }
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 2447 : update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
685 : {
686 2447 : va_list ap;
687 2447 : gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));
688 :
689 2447 : gcc_assert (is_gimple_call (stmt));
690 2447 : va_start (ap, nargs);
691 2447 : new_stmt = gimple_build_call_valist (fn, nargs, ap);
692 2447 : finish_update_gimple_call (si_p, new_stmt, stmt);
693 2447 : va_end (ap);
694 2447 : 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 60850 : valid_gimple_call_p (tree expr)
703 : {
704 60850 : unsigned i, nargs;
705 :
706 60850 : 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 60850 : gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
738 : {
739 60850 : tree lhs;
740 60850 : gimple *stmt, *new_stmt;
741 60850 : gimple_stmt_iterator i;
742 60850 : gimple_seq stmts = NULL;
743 :
744 60850 : stmt = gsi_stmt (*si_p);
745 :
746 60850 : gcc_assert (is_gimple_call (stmt));
747 :
748 60850 : 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 60847 : lhs = gimple_call_lhs (stmt);
773 60847 : if (lhs == NULL_TREE)
774 : {
775 2500 : push_gimplify_context (gimple_in_ssa_p (cfun));
776 1250 : gimplify_and_add (expr, &stmts);
777 1250 : 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 1250 : if (gimple_seq_empty_p (stmts))
782 : {
783 1115 : if (gimple_in_ssa_p (cfun))
784 : {
785 1115 : unlink_stmt_vdef (stmt);
786 1115 : release_defs (stmt);
787 : }
788 1115 : gsi_replace (si_p, gimple_build_nop (), false);
789 1115 : return;
790 : }
791 : }
792 : else
793 : {
794 59597 : tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
795 59597 : new_stmt = gimple_build_assign (lhs, tmp);
796 59597 : i = gsi_last (stmts);
797 59597 : gsi_insert_after_without_update (&i, new_stmt,
798 : GSI_CONTINUE_LINKING);
799 : }
800 :
801 59732 : 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 40552 : dump_transformation (gcall *from, gcall *to)
808 : {
809 40552 : 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 40552 : }
813 :
814 : /* Replace the call at *GSI with the gimple value VAL. */
815 :
816 : void
817 87061 : replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
818 : {
819 87061 : gimple *stmt = gsi_stmt (*gsi);
820 87061 : tree lhs = gimple_call_lhs (stmt);
821 87061 : gimple *repl;
822 87061 : if (lhs)
823 : {
824 81998 : if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (val)))
825 2210 : val = fold_convert (TREE_TYPE (lhs), val);
826 81998 : repl = gimple_build_assign (lhs, val);
827 : }
828 : else
829 5063 : repl = gimple_build_nop ();
830 87061 : tree vdef = gimple_vdef (stmt);
831 87061 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
832 : {
833 5678 : unlink_stmt_vdef (stmt);
834 5678 : release_ssa_name (vdef);
835 : }
836 87061 : gsi_replace (gsi, repl, false);
837 87061 : }
838 :
839 : /* Replace the call at *GSI with the new call REPL and fold that
840 : again. */
841 :
842 : static void
843 40552 : replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
844 : {
845 40552 : gimple *stmt = gsi_stmt (*gsi);
846 40552 : dump_transformation (as_a <gcall *> (stmt), as_a <gcall *> (repl));
847 40552 : gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
848 40552 : gimple_set_location (repl, gimple_location (stmt));
849 40552 : gimple_move_vops (repl, stmt);
850 40552 : gsi_replace (gsi, repl, false);
851 40552 : fold_stmt (gsi);
852 40552 : }
853 :
854 : /* Return true if VAR is a VAR_DECL or a component thereof. */
855 :
856 : static bool
857 422503 : var_decl_component_p (tree var)
858 : {
859 422503 : tree inner = var;
860 605521 : while (handled_component_p (inner))
861 183018 : inner = TREE_OPERAND (inner, 0);
862 422503 : return (DECL_P (inner)
863 422503 : || (TREE_CODE (inner) == MEM_REF
864 43328 : && 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 1066814 : size_must_be_zero_p (tree size)
872 : {
873 1066814 : if (integer_zerop (size))
874 : return true;
875 :
876 1064189 : if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size)))
877 : return false;
878 :
879 649251 : tree type = TREE_TYPE (size);
880 649251 : 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 649251 : wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
885 649251 : wide_int zero = wi::zero (TYPE_PRECISION (type));
886 649251 : int_range_max valid_range (type, zero, ssize_max);
887 649251 : int_range_max vr;
888 1298502 : get_range_query (cfun)->range_of_expr (vr, size);
889 :
890 649251 : if (vr.undefined_p ())
891 85 : vr.set_varying (TREE_TYPE (size));
892 649251 : vr.intersect (valid_range);
893 649251 : return vr.zero_p ();
894 649251 : }
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 1066814 : gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
905 : tree dest, tree src, enum built_in_function code)
906 : {
907 1066814 : gimple *stmt = gsi_stmt (*gsi);
908 1066814 : tree lhs = gimple_call_lhs (stmt);
909 1066814 : tree len = gimple_call_arg (stmt, 2);
910 1066814 : 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 1066814 : if (size_must_be_zero_p (len))
915 : {
916 2674 : gimple *repl;
917 2674 : if (gimple_call_lhs (stmt))
918 60 : repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
919 : else
920 2614 : repl = gimple_build_nop ();
921 2674 : tree vdef = gimple_vdef (stmt);
922 2674 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
923 : {
924 484 : unlink_stmt_vdef (stmt);
925 484 : release_ssa_name (vdef);
926 : }
927 2674 : gsi_replace (gsi, repl, false);
928 2674 : return true;
929 : }
930 :
931 : /* If SRC and DEST are the same (and not volatile), return
932 : DEST{,+LEN,+LEN-1}. */
933 1064140 : 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 89 : unlink_stmt_vdef (stmt);
939 178 : if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
940 48 : release_ssa_name (gimple_vdef (stmt));
941 89 : if (!lhs)
942 : {
943 68 : gsi_replace (gsi, gimple_build_nop (), false);
944 68 : return true;
945 : }
946 21 : goto done;
947 : }
948 2128102 : 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 1064051 : tree srctype
956 1077941 : = POINTER_TYPE_P (TREE_TYPE (src))
957 1077941 : ? TREE_TYPE (TREE_TYPE (src)) : NULL_TREE;
958 1064051 : tree desttype
959 1084950 : = POINTER_TYPE_P (TREE_TYPE (dest))
960 1084950 : ? TREE_TYPE (TREE_TYPE (dest)) : NULL_TREE;
961 1064051 : tree destvar, srcvar, srcoff;
962 1064051 : unsigned int src_align, dest_align;
963 1064051 : unsigned HOST_WIDE_INT tmp_len;
964 1064051 : const char *tmp_str;
965 :
966 : /* Build accesses at offset zero with a ref-all character type. */
967 1064051 : tree off0
968 1064051 : = 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 1064051 : src_align = get_pointer_alignment (src);
976 1064051 : dest_align = get_pointer_alignment (dest);
977 1064051 : if (tree_fits_uhwi_p (len)
978 404443 : && 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 304226 : && !c_strlen (src, 1)
986 195431 : && !((tmp_str = getbyterep (src, &tmp_len)) != NULL
987 82335 : && memchr (tmp_str, 0, tmp_len) == NULL)
988 126825 : && !(srctype
989 126825 : && AGGREGATE_TYPE_P (srctype)
990 60513 : && TYPE_REVERSE_STORAGE_ORDER (srctype))
991 1190743 : && !(desttype
992 126692 : && AGGREGATE_TYPE_P (desttype)
993 69665 : && TYPE_REVERSE_STORAGE_ORDER (desttype)))
994 : {
995 126659 : unsigned ilen = tree_to_uhwi (len);
996 126659 : 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 25557 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1004 : dest, src, len, len,
1005 25557 : false, false))
1006 981 : if (warning != OPT_Wrestrict)
1007 1060504 : return false;
1008 :
1009 24635 : scalar_int_mode imode;
1010 24635 : machine_mode mode;
1011 24635 : if (int_mode_for_size (ilen * BITS_PER_UNIT, 0).exists (&imode)
1012 49270 : && bitwise_mode_for_size (ilen
1013 24635 : * BITS_PER_UNIT).exists (&mode)
1014 49270 : && 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 24635 : && (dest_align >= GET_MODE_ALIGNMENT (mode)
1018 13374 : || !targetm.slow_unaligned_access (mode, dest_align)
1019 0 : || (optab_handler (movmisalign_optab, mode)
1020 : != CODE_FOR_nothing)))
1021 : {
1022 24635 : tree type = bitwise_type_for_mode (mode);
1023 24635 : tree srctype = type;
1024 24635 : tree desttype = type;
1025 24635 : if (src_align < GET_MODE_ALIGNMENT (mode))
1026 12752 : srctype = build_aligned_type (type, src_align);
1027 24635 : tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
1028 24635 : tree tem = fold_const_aggregate_ref (srcmem);
1029 24635 : if (tem)
1030 : srcmem = tem;
1031 23552 : else if (src_align < GET_MODE_ALIGNMENT (mode)
1032 12489 : && targetm.slow_unaligned_access (mode, src_align)
1033 23552 : && (optab_handler (movmisalign_optab, mode)
1034 : == CODE_FOR_nothing))
1035 : srcmem = NULL_TREE;
1036 23552 : if (srcmem)
1037 : {
1038 24635 : gimple *new_stmt;
1039 24635 : if (is_gimple_reg_type (TREE_TYPE (srcmem)))
1040 : {
1041 24635 : new_stmt = gimple_build_assign (NULL_TREE, srcmem);
1042 24635 : srcmem
1043 24635 : = make_ssa_name (TREE_TYPE (srcmem), new_stmt);
1044 24635 : gimple_assign_set_lhs (new_stmt, srcmem);
1045 49270 : gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1046 24635 : gimple_set_location (new_stmt, loc);
1047 24635 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1048 : }
1049 24635 : if (dest_align < GET_MODE_ALIGNMENT (mode))
1050 13374 : desttype = build_aligned_type (type, dest_align);
1051 24635 : new_stmt
1052 24635 : = gimple_build_assign (fold_build2 (MEM_REF, desttype,
1053 : dest, off0),
1054 : srcmem);
1055 24635 : gimple_move_vops (new_stmt, stmt);
1056 24635 : if (!lhs)
1057 : {
1058 21272 : gsi_replace (gsi, new_stmt, false);
1059 21272 : return true;
1060 : }
1061 3363 : gimple_set_location (new_stmt, loc);
1062 3363 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1063 3363 : goto done;
1064 : }
1065 : }
1066 : }
1067 : }
1068 :
1069 1038494 : 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 211651 : if (!dest_align || !src_align)
1077 : return false;
1078 211651 : if (readonly_data_expr (src)
1079 211651 : || (tree_fits_uhwi_p (len)
1080 33212 : && (MIN (src_align, dest_align) / BITS_PER_UNIT
1081 33212 : >= tree_to_uhwi (len))))
1082 : {
1083 1081841 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1084 21337 : if (!fn)
1085 : return false;
1086 21337 : gimple_call_set_fndecl (stmt, fn);
1087 21337 : gimple_call_set_arg (stmt, 0, dest);
1088 21337 : gimple_call_set_arg (stmt, 1, src);
1089 21337 : fold_stmt (gsi);
1090 21337 : return true;
1091 : }
1092 :
1093 : /* If *src and *dest can't overlap, optimize into memcpy as well. */
1094 190314 : if (TREE_CODE (src) == ADDR_EXPR
1095 5514 : && TREE_CODE (dest) == ADDR_EXPR)
1096 : {
1097 1832 : tree src_base, dest_base, fn;
1098 1832 : poly_int64 src_offset = 0, dest_offset = 0;
1099 1832 : poly_uint64 maxsize;
1100 :
1101 1832 : srcvar = TREE_OPERAND (src, 0);
1102 1832 : src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
1103 1832 : if (src_base == NULL)
1104 0 : src_base = srcvar;
1105 1832 : destvar = TREE_OPERAND (dest, 0);
1106 1832 : dest_base = get_addr_base_and_unit_offset (destvar,
1107 : &dest_offset);
1108 1832 : if (dest_base == NULL)
1109 0 : dest_base = destvar;
1110 1832 : if (!poly_int_tree_p (len, &maxsize))
1111 229 : maxsize = -1;
1112 1832 : if (SSA_VAR_P (src_base)
1113 1822 : && SSA_VAR_P (dest_base))
1114 : {
1115 1822 : if (operand_equal_p (src_base, dest_base, 0)
1116 1822 : && 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 3219 : 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 188482 : if ((is_gimple_min_invariant (dest)
1150 184800 : || TREE_CODE (dest) == SSA_NAME)
1151 354309 : && (is_gimple_min_invariant (src)
1152 165848 : || TREE_CODE (src) == SSA_NAME))
1153 : {
1154 169066 : ao_ref destr, srcr;
1155 169066 : ao_ref_init_from_ptr_and_size (&destr, dest, len);
1156 169066 : ao_ref_init_from_ptr_and_size (&srcr, src, len);
1157 169066 : if (!refs_may_alias_p_1 (&destr, &srcr, false))
1158 : {
1159 10374 : tree fn;
1160 10374 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1161 10374 : if (!fn)
1162 10374 : return false;
1163 10374 : gimple_call_set_fndecl (stmt, fn);
1164 10374 : gimple_call_set_arg (stmt, 0, dest);
1165 10374 : gimple_call_set_arg (stmt, 1, src);
1166 10374 : fold_stmt (gsi);
1167 10374 : return true;
1168 : }
1169 : }
1170 :
1171 : return false;
1172 : }
1173 :
1174 826843 : if (!tree_fits_shwi_p (len))
1175 : return false;
1176 328305 : if (!srctype
1177 328305 : || (AGGREGATE_TYPE_P (srctype)
1178 206111 : && TYPE_REVERSE_STORAGE_ORDER (srctype)))
1179 : return false;
1180 328172 : if (!desttype
1181 328172 : || (AGGREGATE_TYPE_P (desttype)
1182 191438 : && 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 328139 : if (TREE_CODE (srctype) == ARRAY_TYPE
1191 328139 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
1192 131522 : srctype = TREE_TYPE (srctype);
1193 328139 : if (TREE_CODE (desttype) == ARRAY_TYPE
1194 328139 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
1195 103755 : desttype = TREE_TYPE (desttype);
1196 328139 : if (TREE_ADDRESSABLE (srctype)
1197 328050 : || 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 655401 : if (FLOAT_MODE_P (TYPE_MODE (desttype))
1203 327120 : || TREE_CODE (desttype) == BOOLEAN_TYPE
1204 655116 : || TREE_CODE (desttype) == ENUMERAL_TYPE)
1205 940 : desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
1206 655603 : if (FLOAT_MODE_P (TYPE_MODE (srctype))
1207 327473 : || TREE_CODE (srctype) == BOOLEAN_TYPE
1208 655474 : || TREE_CODE (srctype) == ENUMERAL_TYPE)
1209 582 : srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
1210 328018 : if (!srctype)
1211 120 : srctype = desttype;
1212 328018 : if (!desttype)
1213 0 : desttype = srctype;
1214 328018 : if (!srctype)
1215 : return false;
1216 :
1217 328018 : src_align = get_pointer_alignment (src);
1218 328018 : 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 328018 : destvar = NULL_TREE;
1227 328018 : srcvar = NULL_TREE;
1228 328018 : if (TREE_CODE (dest) == ADDR_EXPR
1229 114997 : && var_decl_component_p (TREE_OPERAND (dest, 0))
1230 114993 : && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)
1231 25133 : && dest_align >= TYPE_ALIGN (desttype)
1232 353151 : && (is_gimple_reg_type (desttype)
1233 24705 : || src_align >= TYPE_ALIGN (desttype)))
1234 19919 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1235 308099 : else if (TREE_CODE (src) == ADDR_EXPR
1236 243135 : && var_decl_component_p (TREE_OPERAND (src, 0))
1237 47216 : && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
1238 9115 : && src_align >= TYPE_ALIGN (srctype)
1239 317198 : && (is_gimple_reg_type (srctype)
1240 8936 : || dest_align >= TYPE_ALIGN (srctype)))
1241 3135 : 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 304964 : 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 304967 : && 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 23057 : if (srcvar == NULL_TREE)
1258 : {
1259 19919 : if (src_align >= TYPE_ALIGN (desttype))
1260 19901 : 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 3138 : else if (destvar == NULL_TREE)
1275 : {
1276 3138 : if (dest_align >= TYPE_ALIGN (srctype))
1277 3138 : 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 23057 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1298 : dest, src, len, len,
1299 23057 : false, false))
1300 1263 : if (warning != OPT_Wrestrict)
1301 : return false;
1302 :
1303 21802 : gimple *new_stmt;
1304 21802 : 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 21251 : 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 42496 : desttype = build_array_type_nelts (unsigned_char_type_node,
1333 21248 : tree_to_uhwi (len));
1334 21248 : srctype = desttype;
1335 21248 : if (src_align > TYPE_ALIGN (srctype))
1336 12744 : srctype = build_aligned_type (srctype, src_align);
1337 21248 : srcvar = fold_build2 (MEM_REF, srctype, src, off0);
1338 : }
1339 :
1340 21251 : if (dest_align > TYPE_ALIGN (desttype))
1341 13325 : desttype = build_aligned_type (desttype, dest_align);
1342 21251 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1343 21251 : new_stmt = gimple_build_assign (destvar, srcvar);
1344 :
1345 21802 : set_vop_and_replace:
1346 21802 : gimple_move_vops (new_stmt, stmt);
1347 21802 : if (!lhs)
1348 : {
1349 21618 : gsi_replace (gsi, new_stmt, false);
1350 21618 : 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 3568 : done:
1357 3568 : gimple_seq stmts = NULL;
1358 3568 : if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
1359 3568 : len = NULL_TREE;
1360 200 : else if (code == BUILT_IN_MEMPCPY)
1361 : {
1362 200 : len = gimple_convert_to_ptrofftype (&stmts, loc, len);
1363 200 : dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
1364 200 : TREE_TYPE (dest), dest, len);
1365 : }
1366 : else
1367 0 : gcc_unreachable ();
1368 :
1369 3568 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1370 3568 : gimple *repl = gimple_build_assign (lhs, dest);
1371 3568 : gsi_replace (gsi, repl, false);
1372 3568 : 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 317997 : gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
1463 : {
1464 317997 : gimple *stmt = gsi_stmt (*gsi);
1465 317997 : tree etype;
1466 317997 : unsigned HOST_WIDE_INT length, cval;
1467 :
1468 : /* If the LEN parameter is zero, return DEST. */
1469 317997 : if (integer_zerop (len))
1470 : {
1471 841 : replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
1472 841 : return true;
1473 : }
1474 :
1475 634312 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1476 : return false;
1477 :
1478 317078 : if (! tree_fits_uhwi_p (len))
1479 : return false;
1480 :
1481 208223 : length = tree_to_uhwi (len);
1482 :
1483 208223 : tree dest = gimple_call_arg (stmt, 0);
1484 208223 : if (length == 1
1485 208223 : && POINTER_TYPE_P (TREE_TYPE (dest)))
1486 : {
1487 : /* Keep the original call until object-size analysis has inspected it. */
1488 3507 : 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 597 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1497 : dest, NULL_TREE, len,
1498 597 : NULL_TREE, false, false))
1499 20 : if (warning != OPT_Wrestrict)
1500 : return false;
1501 :
1502 577 : etype = unsigned_char_type_node;
1503 577 : tree ptype = TREE_TYPE (TREE_TYPE (dest));
1504 577 : if (TYPE_VOLATILE (ptype))
1505 0 : etype = build_qualified_type (etype, TYPE_QUAL_VOLATILE);
1506 :
1507 577 : location_t loc = gimple_location (stmt);
1508 577 : tree cval_tree;
1509 577 : if (TREE_CODE (c) == INTEGER_CST)
1510 532 : 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 577 : tree off0
1516 577 : = build_int_cst (build_pointer_type_for_mode (char_type_node,
1517 : ptr_mode, true), 0);
1518 577 : tree var = fold_build2_loc (loc, MEM_REF, etype, dest, off0);
1519 577 : gimple *store = gimple_build_assign (var, cval_tree);
1520 577 : gimple_move_vops (store, stmt);
1521 577 : gimple_set_location (store, loc);
1522 577 : copy_warning (store, stmt);
1523 :
1524 577 : tree lhs = gimple_call_lhs (stmt);
1525 577 : if (!lhs)
1526 : {
1527 468 : gsi_replace (gsi, store, false);
1528 468 : 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 204716 : if (TREE_CODE (c) != INTEGER_CST)
1543 : return false;
1544 :
1545 199034 : tree var = dest;
1546 199034 : if (TREE_CODE (var) != ADDR_EXPR)
1547 : return false;
1548 :
1549 160902 : var = TREE_OPERAND (var, 0);
1550 160902 : if (TREE_THIS_VOLATILE (var))
1551 : return false;
1552 :
1553 160859 : etype = TREE_TYPE (var);
1554 160859 : if (TREE_CODE (etype) == ARRAY_TYPE)
1555 85020 : etype = TREE_TYPE (etype);
1556 :
1557 160859 : if ((!INTEGRAL_TYPE_P (etype)
1558 95613 : && !POINTER_TYPE_P (etype))
1559 161291 : || BITINT_TYPE_P (etype))
1560 : return false;
1561 :
1562 64371 : if (! var_decl_component_p (var))
1563 : return false;
1564 :
1565 64371 : if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
1566 1414 : || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
1567 65785 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
1568 65785 : || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
1569 : return false;
1570 :
1571 1414 : if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
1572 : return false;
1573 :
1574 1414 : 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 1414 : if (integer_zerop (c))
1579 : cval = 0;
1580 : else
1581 : {
1582 66 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
1583 : return NULL_TREE;
1584 :
1585 66 : cval = TREE_INT_CST_LOW (c);
1586 66 : cval &= 0xff;
1587 66 : cval |= cval << 8;
1588 66 : cval |= cval << 16;
1589 66 : cval |= (cval << 31) << 1;
1590 : }
1591 :
1592 1414 : var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
1593 1414 : gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
1594 1414 : gimple_move_vops (store, stmt);
1595 1414 : gimple_set_location (store, gimple_location (stmt));
1596 1414 : gsi_insert_before (gsi, store, GSI_SAME_STMT);
1597 1414 : 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 1414 : gimple_stmt_iterator gsi2 = *gsi;
1605 1414 : gsi_prev (gsi);
1606 1414 : 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 452546 : get_range_strlen_tree (tree arg, bitmap visited, strlen_range_kind rkind,
1616 : c_strlen_data *pdata, unsigned eltsize)
1617 : {
1618 452546 : gcc_assert (TREE_CODE (arg) != SSA_NAME);
1619 :
1620 : /* The length computed by this invocation of the function. */
1621 452546 : 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 452546 : bool tight_bound = false;
1628 :
1629 : /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
1630 452546 : if (TREE_CODE (arg) == ADDR_EXPR
1631 452546 : && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
1632 : {
1633 28790 : tree op = TREE_OPERAND (arg, 0);
1634 28790 : if (integer_zerop (TREE_OPERAND (op, 1)))
1635 : {
1636 12555 : tree aop0 = TREE_OPERAND (op, 0);
1637 12555 : if (TREE_CODE (aop0) == INDIRECT_REF
1638 12555 : && 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 16235 : else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
1643 16235 : && 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 452338 : 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 449255 : c_strlen_data lendata = { };
1672 449255 : val = c_strlen (arg, 1, &lendata, eltsize);
1673 :
1674 449255 : if (!val && lendata.decl)
1675 : {
1676 : /* ARG refers to an unterminated const character array.
1677 : DATA.DECL with size DATA.LEN. */
1678 4226 : val = lendata.minlen;
1679 4226 : 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 449765 : bool maxbound = false;
1686 :
1687 449765 : if (!val && rkind == SRK_LENRANGE)
1688 : {
1689 247521 : if (TREE_CODE (arg) == ADDR_EXPR)
1690 87563 : return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
1691 87563 : pdata, eltsize);
1692 :
1693 159958 : if (TREE_CODE (arg) == ARRAY_REF)
1694 : {
1695 18584 : tree optype = TREE_TYPE (TREE_OPERAND (arg, 0));
1696 :
1697 : /* Determine the "innermost" array type. */
1698 18584 : while (TREE_CODE (optype) == ARRAY_TYPE
1699 25540 : && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
1700 6956 : optype = TREE_TYPE (optype);
1701 :
1702 : /* Avoid arrays of pointers. */
1703 18584 : tree eltype = TREE_TYPE (optype);
1704 18584 : if (TREE_CODE (optype) != ARRAY_TYPE
1705 18584 : || !INTEGRAL_TYPE_P (eltype))
1706 : return false;
1707 :
1708 : /* Fail when the array bound is unknown or zero. */
1709 13664 : val = TYPE_SIZE_UNIT (optype);
1710 13664 : if (!val
1711 13592 : || TREE_CODE (val) != INTEGER_CST
1712 27228 : || integer_zerop (val))
1713 : return false;
1714 :
1715 13559 : 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 13559 : pdata->minlen = ssize_int (0);
1721 :
1722 13559 : tight_bound = true;
1723 : }
1724 141374 : else if (TREE_CODE (arg) == COMPONENT_REF
1725 141374 : && (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 10009 : tree fld = TREE_OPERAND (arg, 1);
1736 :
1737 10009 : tree optype = TREE_TYPE (fld);
1738 :
1739 : /* Determine the "innermost" array type. */
1740 10009 : while (TREE_CODE (optype) == ARRAY_TYPE
1741 10571 : && 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 10009 : val = TYPE_SIZE_UNIT (optype);
1746 10009 : if (!val
1747 9773 : || TREE_CODE (val) != INTEGER_CST
1748 19747 : || integer_zerop (val))
1749 : return false;
1750 9659 : 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 9659 : 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 9659 : tight_bound = true;
1764 : }
1765 131365 : else if (TREE_CODE (arg) == MEM_REF
1766 36319 : && TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
1767 10215 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == INTEGER_TYPE
1768 141142 : && 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 9777 : tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
1775 9777 : if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
1776 19541 : && (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 9651 : val = DECL_SIZE_UNIT (ref);
1782 9651 : if (!val
1783 9479 : || TREE_CODE (val) != INTEGER_CST
1784 19130 : || integer_zerop (val))
1785 371 : return false;
1786 :
1787 9477 : poly_offset_int psiz = wi::to_offset (val);
1788 9477 : poly_offset_int poff = mem_ref_offset (arg);
1789 9477 : if (known_le (psiz, poff))
1790 : return false;
1791 :
1792 9280 : pdata->minlen = ssize_int (0);
1793 :
1794 : /* Subtract the offset and one for the terminating nul. */
1795 9280 : psiz -= poff;
1796 9280 : psiz -= 1;
1797 9280 : 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 121588 : 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 71514 : tree argtype = TREE_TYPE (arg);
1808 71514 : if (TREE_CODE (argtype) == ARRAY_TYPE)
1809 : {
1810 43002 : val = TYPE_SIZE_UNIT (argtype);
1811 43002 : if (!val
1812 42236 : || TREE_CODE (val) != INTEGER_CST
1813 85238 : || integer_zerop (val))
1814 : return false;
1815 42121 : val = wide_int_to_tree (TREE_TYPE (val),
1816 42121 : 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 42121 : pdata->minlen = ssize_int (0);
1821 : }
1822 : }
1823 : maxbound = true;
1824 : }
1825 :
1826 355575 : if (!val)
1827 : return false;
1828 :
1829 : /* Adjust the lower bound on the string length as necessary. */
1830 252438 : if (!pdata->minlen
1831 252438 : || (rkind != SRK_STRLEN
1832 79053 : && TREE_CODE (pdata->minlen) == INTEGER_CST
1833 79053 : && TREE_CODE (val) == INTEGER_CST
1834 79048 : && tree_int_cst_lt (val, pdata->minlen)))
1835 173404 : pdata->minlen = val;
1836 :
1837 252438 : 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 7663 : if (TREE_CODE (val) == INTEGER_CST)
1843 : {
1844 7663 : if (tree_int_cst_lt (pdata->maxbound, val))
1845 671 : pdata->maxbound = val;
1846 : }
1847 : else
1848 0 : pdata->maxbound = val;
1849 : }
1850 244775 : 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 71379 : pdata->maxbound = val;
1855 :
1856 252438 : 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 23218 : if (rkind == SRK_LENRANGE)
1863 : {
1864 23218 : poly_int64 offset;
1865 23218 : tree base = get_addr_base_and_unit_offset (arg, &offset);
1866 23218 : 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 7845 : base = get_base_address (arg);
1872 7845 : 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 23218 : tree type = TREE_TYPE (base);
1879 23218 : if (POINTER_TYPE_P (type)
1880 23214 : || (TREE_CODE (base) != PARM_DECL && !VAR_P (base))
1881 41879 : || !(val = DECL_SIZE_UNIT (base)))
1882 5804 : val = build_all_ones_cst (size_type_node);
1883 : else
1884 : {
1885 17414 : val = DECL_SIZE_UNIT (base);
1886 17414 : val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
1887 : size_int (offset + 1));
1888 : }
1889 : }
1890 : else
1891 : return false;
1892 : }
1893 :
1894 252438 : if (pdata->maxlen)
1895 : {
1896 : /* Adjust the more conservative bound if possible/necessary
1897 : and fail otherwise. */
1898 15406 : if (rkind != SRK_STRLEN)
1899 : {
1900 14475 : if (TREE_CODE (pdata->maxlen) != INTEGER_CST
1901 14475 : || TREE_CODE (val) != INTEGER_CST)
1902 : return false;
1903 :
1904 14470 : if (tree_int_cst_lt (pdata->maxlen, val))
1905 1374 : 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 237156 : pdata->maxlen = val;
1917 237156 : 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 1373125 : get_range_strlen (tree arg, bitmap visited,
1938 : strlen_range_kind rkind,
1939 : c_strlen_data *pdata, unsigned eltsize)
1940 : {
1941 :
1942 1456901 : if (TREE_CODE (arg) != SSA_NAME)
1943 452546 : 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 1004355 : if (name_registered_for_update_p (arg))
1948 : return false;
1949 :
1950 : /* If we were already here, break the infinite cycle. */
1951 1004355 : if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
1952 : return true;
1953 :
1954 998797 : tree var = arg;
1955 998797 : gimple *def_stmt = SSA_NAME_DEF_STMT (var);
1956 :
1957 998797 : switch (gimple_code (def_stmt))
1958 : {
1959 127684 : 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 127684 : if (gimple_assign_single_p (def_stmt)
1964 127684 : || gimple_assign_unary_nop_p (def_stmt))
1965 : {
1966 83776 : tree rhs = gimple_assign_rhs1 (def_stmt);
1967 83776 : return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
1968 : }
1969 43908 : 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 87304 : for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
1997 : {
1998 63306 : 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 63306 : if (arg == gimple_phi_result (def_stmt))
2007 0 : continue;
2008 :
2009 63306 : if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
2010 : {
2011 30907 : 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 29136 : 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 1148738 : get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
2047 : {
2048 1148738 : auto_bitmap visited;
2049 1148738 : tree maxbound = pdata->maxbound;
2050 :
2051 1148738 : 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 923304 : pdata->minlen = ssize_int (0);
2057 923304 : pdata->maxlen = build_all_ones_cst (size_type_node);
2058 : }
2059 225434 : else if (!pdata->minlen)
2060 9214 : 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 1148738 : if (maxbound && pdata->maxbound == maxbound)
2065 650706 : pdata->maxbound = build_all_ones_cst (size_type_node);
2066 :
2067 1148738 : return !integer_all_onesp (pdata->maxlen);
2068 1148738 : }
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 95854 : 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 95854 : gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL);
2085 :
2086 : // If arg is already a constant, simply return it.
2087 95854 : 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 72927 : gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
2092 :
2093 73026 : auto_bitmap visited;
2094 :
2095 : /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
2096 : is unbounded. */
2097 73026 : c_strlen_data lendata = { };
2098 73026 : if (!get_range_strlen (arg, visited, rkind, &lendata, /* eltsize = */1))
2099 49895 : lendata.maxlen = NULL_TREE;
2100 23131 : else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
2101 0 : lendata.maxlen = NULL_TREE;
2102 :
2103 73026 : 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 23988 : *nonstr = lendata.decl;
2109 23988 : return lendata.maxlen;
2110 : }
2111 :
2112 : /* Fail if the constant array isn't nul-terminated. */
2113 49038 : return lendata.decl ? NULL_TREE : lendata.maxlen;
2114 73026 : }
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 26050 : gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
2145 : tree dest, tree src)
2146 : {
2147 26050 : gimple *stmt = gsi_stmt (*gsi);
2148 26050 : location_t loc = gimple_location (stmt);
2149 26050 : tree fn;
2150 :
2151 : /* If SRC and DEST are the same (and not volatile), return DEST. */
2152 26050 : 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 25964 : if (optimize_function_for_size_p (cfun))
2172 : return false;
2173 :
2174 23988 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2175 23988 : if (!fn)
2176 : return false;
2177 :
2178 : /* Set to non-null if ARG refers to an unterminated array. */
2179 23988 : tree nonstr = NULL;
2180 23988 : tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);
2181 :
2182 23988 : 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 26358 : if (!len || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
2192 : return false;
2193 :
2194 2901 : len = fold_convert_loc (loc, size_type_node, len);
2195 2901 : len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
2196 2901 : len = force_gimple_operand_gsi (gsi, len, true,
2197 : NULL_TREE, true, GSI_SAME_STMT);
2198 2901 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2199 2901 : replace_call_with_call_and_fold (gsi, repl);
2200 2901 : 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 4212 : gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
2373 : {
2374 4212 : gimple *stmt = gsi_stmt (*gsi);
2375 4212 : if (!gimple_call_lhs (stmt))
2376 : return false;
2377 :
2378 4209 : tree haystack = gimple_call_arg (stmt, 0);
2379 4209 : 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 4209 : if (!check_nul_terminated_array (NULL_TREE, haystack)
2384 4209 : || !check_nul_terminated_array (NULL_TREE, needle))
2385 : return false;
2386 :
2387 4190 : const char *q = c_getstr (needle);
2388 4190 : if (q == NULL)
2389 : return false;
2390 :
2391 3052 : 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 3038 : if (q[0] == '\0')
2413 : {
2414 6 : replace_call_with_value (gsi, haystack);
2415 6 : return true;
2416 : }
2417 :
2418 6064 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
2419 : return false;
2420 :
2421 : /* Transform strstr (x, "c") into strchr (x, 'c'). */
2422 3032 : 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 7330 : gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
2457 : {
2458 7330 : gimple *stmt = gsi_stmt (*gsi);
2459 7330 : location_t loc = gimple_location (stmt);
2460 :
2461 7330 : const char *p = c_getstr (src);
2462 :
2463 : /* If the string length is zero, return the dst parameter. */
2464 7330 : if (p && *p == '\0')
2465 : {
2466 72 : replace_call_with_value (gsi, dst);
2467 72 : return true;
2468 : }
2469 :
2470 7258 : if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
2471 : return false;
2472 :
2473 13342 : 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 6671 : tree newdst;
2478 6671 : tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2479 6671 : tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2480 :
2481 6671 : 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 6671 : tree len = get_maxval_strlen (src, SRK_STRLEN);
2487 6671 : if (! len)
2488 : return false;
2489 :
2490 : /* Create strlen (dst). */
2491 735 : gimple_seq stmts = NULL, stmts2;
2492 735 : gimple *repl = gimple_build_call (strlen_fn, 1, dst);
2493 735 : gimple_set_location (repl, loc);
2494 735 : newdst = make_ssa_name (size_type_node);
2495 735 : gimple_call_set_lhs (repl, newdst);
2496 735 : gimple_seq_add_stmt_without_update (&stmts, repl);
2497 :
2498 : /* Create (dst p+ strlen (dst)). */
2499 735 : newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
2500 735 : newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE);
2501 735 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2502 :
2503 735 : len = fold_convert_loc (loc, size_type_node, len);
2504 735 : len = size_binop_loc (loc, PLUS_EXPR, len,
2505 : build_int_cst (size_type_node, 1));
2506 735 : len = force_gimple_operand (len, &stmts2, true, NULL_TREE);
2507 735 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2508 :
2509 735 : repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
2510 735 : gimple_seq_add_stmt_without_update (&stmts, repl);
2511 735 : 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 570 : gsi_replace_with_seq_vops (gsi, stmts);
2527 570 : 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 1250934 : gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
2739 : {
2740 1250934 : gimple *stmt = gsi_stmt (*gsi);
2741 1250934 : tree callee = gimple_call_fndecl (stmt);
2742 1250934 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
2743 :
2744 1250934 : tree type = integer_type_node;
2745 1250934 : tree str1 = gimple_call_arg (stmt, 0);
2746 1250934 : tree str2 = gimple_call_arg (stmt, 1);
2747 1250934 : tree lhs = gimple_call_lhs (stmt);
2748 :
2749 1250934 : tree bound_node = NULL_TREE;
2750 1250934 : unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;
2751 :
2752 : /* Handle strncmp and strncasecmp functions. */
2753 1250934 : if (gimple_call_num_args (stmt) == 3)
2754 : {
2755 23132 : bound_node = gimple_call_arg (stmt, 2);
2756 23132 : if (tree_fits_uhwi_p (bound_node))
2757 17408 : bound = tree_to_uhwi (bound_node);
2758 : }
2759 :
2760 : /* If the BOUND parameter is zero, return zero. */
2761 17408 : 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 1250930 : 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 2501778 : 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 1250889 : unsigned HOST_WIDE_INT len1 = HOST_WIDE_INT_MAX, len2 = len1;
2783 1250889 : const char *p1 = getbyterep (str1, &len1);
2784 1250889 : 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 1250889 : unsigned HOST_WIDE_INT nulpos1 = HOST_WIDE_INT_MAX, nulpos2 = nulpos1;
2789 :
2790 1250889 : if (p1)
2791 : {
2792 42819 : size_t n = strnlen (p1, len1);
2793 42819 : if (n < len1)
2794 42712 : len1 = nulpos1 = n;
2795 : }
2796 :
2797 1250889 : if (p2)
2798 : {
2799 1219776 : size_t n = strnlen (p2, len2);
2800 1219776 : if (n < len2)
2801 1219717 : len2 = nulpos2 = n;
2802 : }
2803 :
2804 : /* For known strings, return an immediate value. */
2805 1250889 : 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 2425414 : bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U)
2869 1195443 : || fcode == BUILT_IN_STRCMP
2870 1195443 : || fcode == BUILT_IN_STRCMP_EQ
2871 1218621 : || fcode == BUILT_IN_STRCASECMP;
2872 :
2873 1212707 : location_t loc = gimple_location (stmt);
2874 :
2875 : /* If the second arg is "", return *(const unsigned char*)arg1. */
2876 1212707 : 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 1212557 : 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 1212458 : 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 1212348 : 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 38632 : gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
2959 : {
2960 38632 : gimple *stmt = gsi_stmt (*gsi);
2961 38632 : tree lhs = gimple_call_lhs (stmt);
2962 38632 : tree arg1 = gimple_call_arg (stmt, 0);
2963 38632 : tree arg2 = gimple_call_arg (stmt, 1);
2964 38632 : tree len = gimple_call_arg (stmt, 2);
2965 :
2966 : /* If the LEN parameter is zero, return zero. */
2967 38632 : 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 38631 : char c;
2974 38631 : if (TREE_CODE (arg2) != INTEGER_CST
2975 22900 : || !tree_fits_uhwi_p (len)
2976 39359 : || !target_char_cst_p (arg2, &c))
2977 : return false;
2978 :
2979 728 : unsigned HOST_WIDE_INT length = tree_to_uhwi (len);
2980 728 : unsigned HOST_WIDE_INT string_length;
2981 728 : const char *p1 = getbyterep (arg1, &string_length);
2982 :
2983 728 : if (p1)
2984 : {
2985 110 : const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
2986 110 : 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 96 : unsigned HOST_WIDE_INT offset = r - p1;
3005 96 : gimple_seq stmts = NULL;
3006 96 : if (lhs != NULL_TREE)
3007 : {
3008 94 : tree offset_cst = build_int_cst (sizetype, offset);
3009 94 : gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
3010 : arg1, offset_cst);
3011 94 : 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 96 : gsi_replace_with_seq_vops (gsi, stmts);
3018 96 : 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 20754 : gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
3034 : tree arg0, tree arg1,
3035 : bool unlocked)
3036 : {
3037 20754 : gimple *stmt = gsi_stmt (*gsi);
3038 :
3039 : /* If we're using an unlocked function, assume the other unlocked
3040 : functions exist explicitly. */
3041 20754 : tree const fn_fputc = (unlocked
3042 20754 : ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
3043 20754 : : builtin_decl_implicit (BUILT_IN_FPUTC));
3044 20711 : tree const fn_fwrite = (unlocked
3045 43 : ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
3046 20754 : : builtin_decl_implicit (BUILT_IN_FWRITE));
3047 :
3048 : /* If the return value is used, don't do the transformation. */
3049 20754 : 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 20683 : tree len = get_maxval_strlen (arg0, SRK_STRLEN);
3055 20683 : if (!len || TREE_CODE (len) != INTEGER_CST)
3056 : return false;
3057 :
3058 16247 : 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 15106 : case 1: /* length is greater than 1, call fwrite. */
3082 15106 : {
3083 : /* If optimizing for size keep fputs. */
3084 15106 : 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 16526 : if (!fn_fwrite || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3089 : return false;
3090 :
3091 8263 : gimple *repl
3092 8263 : = gimple_build_call (fn_fwrite, 4, arg0, size_one_node,
3093 : fold_convert (size_type_node, len), arg1);
3094 8263 : replace_call_with_call_and_fold (gsi, repl);
3095 8263 : 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 41123 : gimple_fold_builtin_fwrite (gimple_stmt_iterator *gsi, bool unlocked)
3110 : {
3111 41123 : 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 41123 : 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 39980 : if (!integer_onep (gimple_call_arg (stmt, 1))
3122 39980 : || !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 41136 : : 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 9545 : gimple_fold_builtin_mempcpy (gimple_stmt_iterator *gsi)
3465 : {
3466 9545 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3467 :
3468 9545 : 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 2347 : gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
3644 : {
3645 2347 : 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 2347 : if (gimple_call_num_args (stmt) > 3)
3651 : return false;
3652 :
3653 1946 : tree orig = NULL_TREE;
3654 1946 : if (gimple_call_num_args (stmt) == 3)
3655 1848 : orig = gimple_call_arg (stmt, 2);
3656 :
3657 : /* Check whether the format is a literal string constant. */
3658 1946 : tree fmt = gimple_call_arg (stmt, 1);
3659 1946 : const char *fmt_str = c_getstr (fmt);
3660 1946 : if (fmt_str == NULL)
3661 : return false;
3662 :
3663 1946 : tree dest = gimple_call_arg (stmt, 0);
3664 :
3665 1946 : if (!init_target_chars ())
3666 : return false;
3667 :
3668 1946 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3669 3892 : 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 1946 : 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 1836 : 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 1874 : gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
3774 : {
3775 1874 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3776 1874 : tree dest = gimple_call_arg (stmt, 0);
3777 1874 : tree destsize = gimple_call_arg (stmt, 1);
3778 1874 : tree fmt = gimple_call_arg (stmt, 2);
3779 1874 : tree orig = NULL_TREE;
3780 1874 : const char *fmt_str = NULL;
3781 :
3782 1874 : if (gimple_call_num_args (stmt) > 4
3783 2776 : || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3784 : return false;
3785 :
3786 899 : if (gimple_call_num_args (stmt) == 4)
3787 700 : orig = gimple_call_arg (stmt, 3);
3788 :
3789 : /* Check whether the format is a literal string constant. */
3790 899 : fmt_str = c_getstr (fmt);
3791 899 : if (fmt_str == NULL)
3792 : return false;
3793 :
3794 899 : if (!init_target_chars ())
3795 : return false;
3796 :
3797 : /* If the format doesn't contain % args or %%, use strcpy. */
3798 899 : 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 701 : 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 54595 : gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
3909 : tree fp, tree fmt, tree arg,
3910 : enum built_in_function fcode)
3911 : {
3912 54595 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3913 54595 : tree fn_fputc, fn_fputs;
3914 54595 : const char *fmt_str = NULL;
3915 :
3916 : /* If the return value is used, don't do the transformation. */
3917 54595 : if (gimple_call_lhs (stmt) != NULL_TREE)
3918 : return false;
3919 :
3920 : /* Check whether the format is a literal string constant. */
3921 50418 : fmt_str = c_getstr (fmt);
3922 50418 : if (fmt_str == NULL)
3923 : return false;
3924 :
3925 50088 : 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 50008 : fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
3935 50008 : fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
3936 : }
3937 :
3938 50088 : if (!init_target_chars ())
3939 : return false;
3940 :
3941 100176 : 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 50088 : if (strchr (fmt_str, target_percent) == NULL)
3946 : {
3947 9628 : if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
3948 9558 : && arg)
3949 : return false;
3950 :
3951 : /* If the format specifier was "", fprintf does nothing. */
3952 9628 : 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 9570 : if (fn_fputs)
3962 : {
3963 9570 : gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
3964 9570 : replace_call_with_call_and_fold (gsi, repl);
3965 9570 : return true;
3966 : }
3967 : }
3968 :
3969 : /* The other optimizations can be done only on the non-va_list variants. */
3970 40460 : 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 39411 : 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 38768 : 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 123921 : gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
4013 : tree arg, enum built_in_function fcode)
4014 : {
4015 123921 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
4016 123921 : tree fn_putchar, fn_puts, newarg;
4017 123921 : const char *fmt_str = NULL;
4018 :
4019 : /* If the return value is used, don't do the transformation. */
4020 123921 : if (gimple_call_lhs (stmt) != NULL_TREE)
4021 : return false;
4022 :
4023 241326 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
4024 : return false;
4025 :
4026 : /* Check whether the format is a literal string constant. */
4027 120663 : fmt_str = c_getstr (fmt);
4028 120663 : if (fmt_str == NULL)
4029 : return false;
4030 :
4031 117626 : 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 117546 : fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
4041 117546 : fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
4042 : }
4043 :
4044 117626 : if (!init_target_chars ())
4045 : return false;
4046 :
4047 117626 : if (strcmp (fmt_str, target_percent_s) == 0
4048 111240 : || strchr (fmt_str, target_percent) == NULL)
4049 : {
4050 14209 : const char *str;
4051 :
4052 14209 : 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 7823 : if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
4068 7691 : && arg)
4069 : return false;
4070 : str = fmt_str;
4071 : }
4072 :
4073 : /* If the string was "", printf does nothing. */
4074 5774 : 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 5665 : 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 5106 : size_t len = strlen (str);
4098 5106 : if ((unsigned char)str[len - 1] == target_newline
4099 4006 : && (size_t) (int) len == len
4100 4006 : && (int) len > 0)
4101 : {
4102 4006 : char *newstr;
4103 :
4104 : /* Create a NUL-terminated string that's one char shorter
4105 : than the original, stripping off the trailing '\n'. */
4106 4006 : newstr = xstrdup (str);
4107 4006 : newstr[len - 1] = '\0';
4108 4006 : newarg = build_string_literal (len, newstr);
4109 4006 : free (newstr);
4110 4006 : if (fn_puts)
4111 : {
4112 4006 : gcall *repl = gimple_build_call (fn_puts, 1, newarg);
4113 4006 : replace_call_with_call_and_fold (gsi, repl);
4114 4006 : 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 103417 : 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 103167 : else if (strcmp (fmt_str, target_percent_s_newline) == 0)
4130 : {
4131 175 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
4132 : return false;
4133 175 : if (fn_puts)
4134 : {
4135 175 : gcall *repl = gimple_build_call (fn_puts, 1, arg);
4136 175 : replace_call_with_call_and_fold (gsi, repl);
4137 175 : return true;
4138 : }
4139 : }
4140 :
4141 : /* If the format specifier was "%c", call __builtin_putchar(arg). */
4142 102992 : 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 150043 : gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
4164 : {
4165 150043 : gimple *stmt = gsi_stmt (*gsi);
4166 150043 : tree arg = gimple_call_arg (stmt, 0);
4167 :
4168 150043 : wide_int minlen;
4169 150043 : wide_int maxlen;
4170 :
4171 150043 : c_strlen_data lendata = { };
4172 150043 : if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
4173 35202 : && !lendata.decl
4174 32239 : && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
4175 182177 : && 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 32134 : minlen = wi::to_wide (lendata.minlen);
4183 32134 : maxlen = wi::to_wide (lendata.maxlen);
4184 : }
4185 : else
4186 : {
4187 117909 : unsigned prec = TYPE_PRECISION (sizetype);
4188 :
4189 117909 : minlen = wi::shwi (0, prec);
4190 117909 : 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 150043 : if (sanitize_flags_p (SANITIZE_ADDRESS))
4196 278 : maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED);
4197 :
4198 150043 : if (minlen == maxlen)
4199 : {
4200 : /* Fold the strlen call to a constant. */
4201 1654 : tree type = TREE_TYPE (lendata.minlen);
4202 3308 : tree len = force_gimple_operand_gsi (gsi,
4203 1654 : wide_int_to_tree (type, minlen),
4204 : true, NULL, true, GSI_SAME_STMT);
4205 1654 : replace_call_with_value (gsi, len);
4206 1654 : return true;
4207 : }
4208 :
4209 : /* Set the strlen() range to [0, MAXLEN]. */
4210 148389 : if (tree lhs = gimple_call_lhs (stmt))
4211 148384 : set_strlen_range (lhs, minlen, maxlen);
4212 :
4213 : return false;
4214 150043 : }
4215 :
4216 : static bool
4217 260 : 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 260 : if (!ENABLE_OFFLOADING || symtab->state == EXPANSION)
4224 : {
4225 0 : replace_call_with_value (gsi, integer_one_node);
4226 260 : 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 334 : gimple_fold_builtin_omp_get_num_devices (gimple_stmt_iterator *gsi)
4258 : {
4259 334 : if (!ENABLE_OFFLOADING)
4260 : {
4261 0 : replace_call_with_value (gsi, integer_zero_node);
4262 334 : 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 50563 : gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
4313 : {
4314 50563 : gimple *stmt = gsi_stmt (*gsi);
4315 50563 : tree arg = gimple_call_arg (stmt, 0);
4316 50563 : tree size = gimple_call_arg (stmt, 1);
4317 :
4318 101126 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
4319 : return false;
4320 :
4321 50563 : if (operand_equal_p (arg, null_pointer_node, 0))
4322 : {
4323 1428 : tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
4324 1428 : if (fn_malloc)
4325 : {
4326 1428 : gcall *repl = gimple_build_call (fn_malloc, 1, size);
4327 1428 : replace_call_with_call_and_fold (gsi, repl);
4328 1428 : 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 39986 : clear_padding_flush (clear_padding_struct *buf, bool full)
4378 : {
4379 39986 : gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0);
4380 39986 : if (!full && buf->size < 2 * clear_padding_unit)
4381 : return;
4382 41031 : gcc_assert ((buf->off % UNITS_PER_WORD) == 0);
4383 39944 : size_t end = buf->size;
4384 39944 : if (!full)
4385 42 : end = ((end - clear_padding_unit - 1) / clear_padding_unit
4386 : * clear_padding_unit);
4387 39944 : size_t padding_bytes = buf->padding_bytes;
4388 39944 : if (buf->union_ptr)
4389 : {
4390 39174 : 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 338810 : for (size_t i = 0; i < end; i++)
4395 : {
4396 300029 : if (buf->buf[i] == (unsigned char) ~0)
4397 9052 : padding_bytes++;
4398 : else
4399 : {
4400 290977 : memset (&buf->union_ptr[buf->off + i - padding_bytes],
4401 : 0, padding_bytes);
4402 290977 : padding_bytes = 0;
4403 290977 : buf->union_ptr[buf->off + i] &= ~buf->buf[i];
4404 : }
4405 : }
4406 38781 : if (full)
4407 : {
4408 38781 : memset (&buf->union_ptr[buf->off + end - padding_bytes],
4409 : 0, padding_bytes);
4410 38781 : buf->off = 0;
4411 38781 : buf->size = 0;
4412 38781 : 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 38781 : 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 770 : size_t wordsize = UNITS_PER_WORD;
4452 23525 : for (size_t i = 0; i < end; i += wordsize)
4453 : {
4454 22755 : size_t nonzero_first = wordsize;
4455 22755 : size_t nonzero_last = 0;
4456 22755 : size_t zero_first = wordsize;
4457 22755 : size_t zero_last = 0;
4458 22755 : bool all_ones = true, bytes_only = true;
4459 23046 : if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize)
4460 22755 : > (unsigned HOST_WIDE_INT) buf->sz)
4461 : {
4462 291 : gcc_assert (wordsize > 1);
4463 291 : wordsize /= 2;
4464 291 : i -= wordsize;
4465 291 : continue;
4466 : }
4467 22464 : size_t endsize = end - i > wordsize ? wordsize : end - i;
4468 200916 : for (size_t j = i; j < i + endsize; j++)
4469 : {
4470 178452 : if (buf->buf[j])
4471 : {
4472 168415 : if (nonzero_first == wordsize)
4473 : {
4474 21522 : nonzero_first = j - i;
4475 21522 : nonzero_last = j - i;
4476 : }
4477 168415 : if (nonzero_last != j - i)
4478 166 : all_ones = false;
4479 168415 : nonzero_last = j + 1 - i;
4480 : }
4481 : else
4482 : {
4483 10037 : if (zero_first == wordsize)
4484 1948 : zero_first = j - i;
4485 10037 : zero_last = j + 1 - i;
4486 : }
4487 178452 : if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
4488 : {
4489 104 : all_ones = false;
4490 104 : bytes_only = false;
4491 : }
4492 : }
4493 22464 : size_t padding_end = i;
4494 22464 : 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 2064 : if (nonzero_first == wordsize)
4540 : /* All bits in a word are 0, there are no padding bits. */
4541 946 : continue;
4542 1118 : 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 277 : 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 163 : for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
4589 : {
4590 163 : if (nonzero_last - nonzero_first <= eltsz
4591 50 : && ((nonzero_first & ~(eltsz - 1))
4592 50 : == ((nonzero_last - 1) & ~(eltsz - 1))))
4593 : {
4594 50 : tree type;
4595 50 : if (eltsz == 1)
4596 3 : type = char_type_node;
4597 : else
4598 47 : type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT,
4599 : 0);
4600 50 : size_t start = nonzero_first & ~(eltsz - 1);
4601 50 : HOST_WIDE_INT off = buf->off + i + start;
4602 50 : tree atype = type;
4603 50 : if (eltsz > 1 && buf->align < TYPE_ALIGN (type))
4604 8 : atype = build_aligned_type (type, buf->align);
4605 50 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4606 50 : build_int_cst (buf->alias_type, off));
4607 50 : tree src;
4608 50 : gimple *g;
4609 50 : if (all_ones
4610 50 : && nonzero_first == start
4611 0 : && nonzero_last == start + eltsz)
4612 0 : src = build_zero_cst (type);
4613 : else
4614 : {
4615 50 : src = make_ssa_name (type);
4616 50 : 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 50 : SET_EXPR_LOCATION (tmp_dst, UNKNOWN_LOCATION);
4625 50 : suppress_warning (tmp_dst, OPT_Wuninitialized);
4626 50 : g = gimple_build_assign (src, tmp_dst);
4627 50 : gimple_set_location (g, buf->loc);
4628 50 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4629 100 : tree mask = native_interpret_expr (type,
4630 50 : buf->buf + i + start,
4631 : eltsz);
4632 50 : gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
4633 50 : mask = fold_build1 (BIT_NOT_EXPR, type, mask);
4634 50 : tree src_masked = make_ssa_name (type);
4635 50 : g = gimple_build_assign (src_masked, BIT_AND_EXPR,
4636 : src, mask);
4637 50 : gimple_set_location (g, buf->loc);
4638 50 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4639 50 : src = src_masked;
4640 : }
4641 50 : g = gimple_build_assign (dst, src);
4642 50 : gimple_set_location (g, buf->loc);
4643 50 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4644 50 : break;
4645 : }
4646 : }
4647 : }
4648 770 : if (full)
4649 : {
4650 728 : 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 728 : size_t end_rem = end % UNITS_PER_WORD;
4672 728 : buf->off += end - end_rem;
4673 728 : buf->size = end_rem;
4674 728 : memset (buf->buf, 0, buf->size);
4675 728 : 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 39255 : clear_padding_real_needs_padding_p (tree type)
4820 : {
4821 39255 : const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
4822 39255 : return (fmt->b == 2
4823 38644 : && fmt->signbit_ro == fmt->signbit_rw
4824 77899 : && (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 60 : clear_padding_bitint_needs_padding_p (tree type)
4832 : {
4833 60 : struct bitint_info info;
4834 60 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
4835 60 : gcc_assert (ok);
4836 60 : if (info.extended)
4837 : return false;
4838 60 : scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.abi_limb_mode);
4839 60 : 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 951279 : clear_padding_type_may_have_padding_p (tree type)
4852 : {
4853 1090838 : switch (TREE_CODE (type))
4854 : {
4855 : case RECORD_TYPE:
4856 : case UNION_TYPE:
4857 : return true;
4858 139559 : case ARRAY_TYPE:
4859 139559 : case COMPLEX_TYPE:
4860 139559 : case VECTOR_TYPE:
4861 139559 : return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
4862 1932 : case REAL_TYPE:
4863 1932 : 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 60 : case BITINT_TYPE:
4869 60 : 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 1204120 : type_has_padding_at_level_p (tree type)
4880 : {
4881 1204120 : switch (TREE_CODE (type))
4882 : {
4883 1061667 : case RECORD_TYPE:
4884 1061667 : {
4885 1061667 : tree bitpos = size_zero_node;
4886 : /* Expect fields to be sorted by bit position. */
4887 8727834 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4888 7671892 : if (TREE_CODE (f) == FIELD_DECL)
4889 : {
4890 2309294 : if (DECL_PADDING_P (f))
4891 : return true;
4892 2309291 : tree pos = bit_position (f);
4893 2309291 : if (simple_cst_equal (bitpos, pos) != 1)
4894 : return true;
4895 2303592 : if (!DECL_SIZE (f))
4896 : return true;
4897 2303569 : bitpos = int_const_binop (PLUS_EXPR, pos, DECL_SIZE (f));
4898 : }
4899 1055942 : if (simple_cst_equal (bitpos, TYPE_SIZE (type)) != 1)
4900 12395 : 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 74864 : clear_padding_type (clear_padding_struct *buf, tree type,
4983 : HOST_WIDE_INT sz, bool for_auto_init)
4984 : {
4985 74864 : 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 37323 : case REAL_TYPE:
5142 37323 : gcc_assert ((size_t) sz <= clear_padding_unit);
5143 37323 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5144 0 : clear_padding_flush (buf, false);
5145 37323 : 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 35736 : memset (buf->buf + buf->size, 0, sz);
5159 37323 : buf->size += sz;
5160 37323 : 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 7 : case BITINT_TYPE:
5180 7 : do_bitint:
5181 7 : {
5182 7 : struct bitint_info info;
5183 7 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
5184 7 : gcc_assert (ok);
5185 7 : scalar_int_mode limb_mode
5186 7 : = as_a <scalar_int_mode> (info.abi_limb_mode);
5187 7 : if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
5188 : {
5189 5 : gcc_assert ((size_t) sz <= clear_padding_unit);
5190 5 : if ((unsigned HOST_WIDE_INT) sz + buf->size
5191 : > clear_padding_buf_size)
5192 0 : clear_padding_flush (buf, false);
5193 5 : if (!info.extended
5194 5 : && TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
5195 : {
5196 5 : int tprec = GET_MODE_PRECISION (limb_mode);
5197 5 : int prec = TYPE_PRECISION (type);
5198 5 : tree t = build_nonstandard_integer_type (tprec, 1);
5199 5 : tree cst = wide_int_to_tree (t, wi::mask (prec, true, tprec));
5200 5 : int len = native_encode_expr (cst, buf->buf + buf->size, sz);
5201 5 : gcc_assert (len > 0 && (size_t) len == (size_t) sz);
5202 : }
5203 : else
5204 0 : memset (buf->buf + buf->size, 0, sz);
5205 5 : buf->size += sz;
5206 5 : 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 74864 : }
5246 :
5247 : /* Clear padding bits of TYPE in MASK. */
5248 :
5249 : void
5250 38781 : clear_type_padding_in_mask (tree type, unsigned char *mask)
5251 : {
5252 38781 : clear_padding_struct buf;
5253 38781 : buf.loc = UNKNOWN_LOCATION;
5254 38781 : buf.clear_in_mask = true;
5255 38781 : buf.base = NULL_TREE;
5256 38781 : buf.alias_type = NULL_TREE;
5257 38781 : buf.gsi = NULL;
5258 38781 : buf.align = 0;
5259 38781 : buf.off = 0;
5260 38781 : buf.padding_bytes = 0;
5261 38781 : buf.sz = int_size_in_bytes (type);
5262 38781 : buf.size = 0;
5263 38781 : buf.union_ptr = mask;
5264 38781 : clear_padding_type (&buf, type, buf.sz, false);
5265 38781 : clear_padding_flush (&buf, true);
5266 38781 : }
5267 :
5268 : /* Fold __builtin_clear_padding builtin. */
5269 :
5270 : static bool
5271 634 : gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
5272 : {
5273 634 : gimple *stmt = gsi_stmt (*gsi);
5274 634 : gcc_assert (gimple_call_num_args (stmt) == 2);
5275 634 : tree ptr = gimple_call_arg (stmt, 0);
5276 634 : 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 634 : bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg);
5281 634 : tree type = TREE_TYPE (TREE_TYPE (typearg));
5282 634 : location_t loc = gimple_location (stmt);
5283 634 : clear_padding_struct buf;
5284 634 : gimple_stmt_iterator gsiprev = *gsi;
5285 : /* This should be folded during the lower pass. */
5286 1268 : gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL);
5287 634 : gcc_assert (COMPLETE_TYPE_P (type));
5288 634 : gsi_prev (&gsiprev);
5289 :
5290 634 : buf.loc = loc;
5291 634 : buf.clear_in_mask = false;
5292 634 : buf.base = ptr;
5293 634 : buf.alias_type = NULL_TREE;
5294 634 : buf.gsi = gsi;
5295 634 : buf.align = get_pointer_alignment (ptr);
5296 634 : unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT;
5297 634 : buf.align = MAX (buf.align, talign);
5298 634 : buf.off = 0;
5299 634 : buf.padding_bytes = 0;
5300 634 : buf.size = 0;
5301 634 : buf.sz = int_size_in_bytes (type);
5302 634 : buf.union_ptr = NULL;
5303 634 : 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 633 : else if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
5310 : sorry_at (loc, "%s not supported on this target",
5311 : "__builtin_clear_padding");
5312 633 : else if (!clear_padding_type_may_have_padding_p (type))
5313 : ;
5314 596 : 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 548 : 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 548 : buf.alias_type = build_pointer_type (type);
5350 548 : clear_padding_type (&buf, type, buf.sz, for_auto_init);
5351 548 : clear_padding_flush (&buf, true);
5352 : }
5353 :
5354 634 : gimple_stmt_iterator gsiprev2 = *gsi;
5355 634 : gsi_prev (&gsiprev2);
5356 634 : if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
5357 126 : gsi_replace (gsi, gimple_build_nop (), true);
5358 : else
5359 : {
5360 508 : gsi_remove (gsi, true);
5361 508 : *gsi = gsiprev2;
5362 : }
5363 634 : return true;
5364 : }
5365 :
5366 : /* Fold __builtin_constant_p builtin. */
5367 :
5368 : static bool
5369 170968 : gimple_fold_builtin_constant_p (gimple_stmt_iterator *gsi)
5370 : {
5371 170968 : gcall *call = as_a<gcall*>(gsi_stmt (*gsi));
5372 :
5373 170968 : if (gimple_call_num_args (call) != 1)
5374 : return false;
5375 :
5376 170963 : tree arg = gimple_call_arg (call, 0);
5377 170963 : 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 339857 : if (!result && fold_before_rtl_expansion_p ())
5383 3 : result = integer_zero_node;
5384 :
5385 170963 : if (!result)
5386 : return false;
5387 :
5388 2072 : gimplify_and_update_call_from_tree (gsi, result);
5389 2072 : 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 115321 : gimple_fold_builtin_stdarg (gimple_stmt_iterator *gsi, gcall *call)
5399 : {
5400 : /* These shouldn't be folded before pass_stdarg. */
5401 115321 : if (!fold_before_rtl_expansion_p ())
5402 : return false;
5403 :
5404 10848 : tree callee, lhs, rhs, cfun_va_list;
5405 10848 : bool va_list_simple_ptr;
5406 10848 : location_t loc = gimple_location (call);
5407 10848 : gimple *nstmt0, *nstmt;
5408 10848 : tree tlhs, oldvdef, newvdef;
5409 :
5410 10848 : callee = gimple_call_fndecl (call);
5411 :
5412 10848 : cfun_va_list = targetm.fn_abi_va_list (callee);
5413 21696 : va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
5414 10848 : && (TREE_TYPE (cfun_va_list) == void_type_node
5415 436 : || TREE_TYPE (cfun_va_list) == char_type_node);
5416 :
5417 10848 : switch (DECL_FUNCTION_CODE (callee))
5418 : {
5419 7024 : case BUILT_IN_VA_START:
5420 7024 : if (!va_list_simple_ptr
5421 172 : || targetm.expand_builtin_va_start != NULL
5422 7180 : || !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 3580 : case BUILT_IN_VA_END:
5497 : /* No effect, so the statement will be deleted. */
5498 3580 : 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 3580 : unlink_stmt_vdef (call);
5504 3580 : release_defs (call);
5505 3580 : gsi_replace (gsi, gimple_build_nop (), false);
5506 3580 : 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 9687458 : gimple_fold_builtin (gimple_stmt_iterator *gsi)
5545 : {
5546 9687458 : gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
5547 9687458 : tree callee = gimple_call_fndecl (stmt);
5548 :
5549 : /* Give up for always_inline inline builtins until they are
5550 : inlined. */
5551 9687458 : if (avoid_folding_inline_builtin (callee))
5552 : return false;
5553 :
5554 9686281 : unsigned n = gimple_call_num_args (stmt);
5555 9686281 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
5556 9686281 : switch (fcode)
5557 : {
5558 115321 : case BUILT_IN_VA_START:
5559 115321 : case BUILT_IN_VA_END:
5560 115321 : case BUILT_IN_VA_COPY:
5561 115321 : 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 317997 : case BUILT_IN_MEMSET:
5570 317997 : return gimple_fold_builtin_memset (gsi,
5571 : gimple_call_arg (stmt, 1),
5572 317997 : gimple_call_arg (stmt, 2));
5573 10287 : case BUILT_IN_MEMPCPY:
5574 10287 : if (gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5575 : gimple_call_arg (stmt, 1), fcode))
5576 : return true;
5577 9545 : return gimple_fold_builtin_mempcpy (gsi);
5578 1056527 : case BUILT_IN_MEMCPY:
5579 1056527 : case BUILT_IN_MEMMOVE:
5580 1056527 : return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5581 1056527 : 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 150043 : case BUILT_IN_STRLEN:
5590 150043 : return gimple_fold_builtin_strlen (gsi);
5591 26050 : case BUILT_IN_STRCPY:
5592 26050 : return gimple_fold_builtin_strcpy (gsi,
5593 : gimple_call_arg (stmt, 0),
5594 26050 : 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 7330 : case BUILT_IN_STRCAT:
5601 7330 : return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
5602 7330 : 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 4212 : case BUILT_IN_STRSTR:
5612 4212 : return gimple_fold_builtin_strstr (gsi);
5613 1250934 : case BUILT_IN_STRCMP:
5614 1250934 : case BUILT_IN_STRCMP_EQ:
5615 1250934 : case BUILT_IN_STRCASECMP:
5616 1250934 : case BUILT_IN_STRNCMP:
5617 1250934 : case BUILT_IN_STRNCMP_EQ:
5618 1250934 : case BUILT_IN_STRNCASECMP:
5619 1250934 : return gimple_fold_builtin_string_compare (gsi);
5620 38632 : case BUILT_IN_MEMCHR:
5621 38632 : return gimple_fold_builtin_memchr (gsi);
5622 20711 : case BUILT_IN_FPUTS:
5623 20711 : return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5624 20711 : 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 40856 : case BUILT_IN_FWRITE:
5629 40856 : return gimple_fold_builtin_fwrite (gsi, false);
5630 267 : case BUILT_IN_FWRITE_UNLOCKED:
5631 267 : 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 849461 : case BUILT_IN_FPRINTF:
5664 849461 : case BUILT_IN_FPRINTF_UNLOCKED:
5665 849461 : case BUILT_IN_VFPRINTF:
5666 849461 : if (n == 2 || n == 3)
5667 95115 : return gimple_fold_builtin_fprintf (gsi,
5668 : gimple_call_arg (stmt, 0),
5669 : gimple_call_arg (stmt, 1),
5670 : n == 3
5671 42590 : ? gimple_call_arg (stmt, 2)
5672 : : NULL_TREE,
5673 52525 : 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 199022 : case BUILT_IN_PRINTF:
5687 199022 : case BUILT_IN_PRINTF_UNLOCKED:
5688 199022 : case BUILT_IN_VPRINTF:
5689 199022 : if (n == 1 || n == 2)
5690 234498 : return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
5691 : n == 2
5692 112699 : ? gimple_call_arg (stmt, 1)
5693 121799 : : 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 260 : case BUILT_IN_OMP_IS_INITIAL_DEVICE:
5707 260 : 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 334 : case BUILT_IN_OMP_GET_NUM_DEVICES:
5713 334 : return gimple_fold_builtin_omp_get_num_devices (gsi);
5714 :
5715 50563 : case BUILT_IN_REALLOC:
5716 50563 : return gimple_fold_builtin_realloc (gsi);
5717 :
5718 634 : case BUILT_IN_CLEAR_PADDING:
5719 634 : return gimple_fold_builtin_clear_padding (gsi);
5720 :
5721 170968 : case BUILT_IN_CONSTANT_P:
5722 170968 : 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 6168429 : default:;
5729 : }
5730 :
5731 : /* Try the generic builtin folder. */
5732 6168429 : bool ignore = (gimple_call_lhs (stmt) == NULL);
5733 6168429 : tree result = fold_call_stmt (stmt, ignore);
5734 6168429 : if (result)
5735 : {
5736 5119 : if (ignore)
5737 1253 : STRIP_NOPS (result);
5738 : else
5739 3866 : result = fold_convert (gimple_call_return_type (stmt), result);
5740 5119 : gimplify_and_update_call_from_tree (gsi, result);
5741 5119 : 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 61916976 : optimize_atomic_compare_exchange_p (gimple *stmt)
5783 : {
5784 61916976 : if (gimple_call_num_args (stmt) != 6
5785 1659788 : || !flag_inline_atomics
5786 1659788 : || !optimize
5787 1659788 : || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
5788 1659707 : || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
5789 1113419 : || !gimple_vdef (stmt)
5790 62910149 : || !gimple_vuse (stmt))
5791 : return false;
5792 :
5793 993173 : tree fndecl = gimple_call_fndecl (stmt);
5794 993173 : switch (DECL_FUNCTION_CODE (fndecl))
5795 : {
5796 51880 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
5797 51880 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
5798 51880 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
5799 51880 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
5800 51880 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
5801 51880 : break;
5802 : default:
5803 : return false;
5804 : }
5805 :
5806 51880 : tree expected = gimple_call_arg (stmt, 1);
5807 51880 : if (TREE_CODE (expected) != ADDR_EXPR
5808 51880 : || !SSA_VAR_P (TREE_OPERAND (expected, 0)))
5809 : return false;
5810 :
5811 49492 : tree etype = TREE_TYPE (TREE_OPERAND (expected, 0));
5812 49492 : if (!is_gimple_reg_type (etype)
5813 49057 : || !auto_var_in_fn_p (TREE_OPERAND (expected, 0), current_function_decl)
5814 46652 : || TREE_THIS_VOLATILE (etype)
5815 46652 : || 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 67524 : || maybe_ne (TYPE_PRECISION (etype),
5821 36064 : GET_MODE_BITSIZE (TYPE_MODE (etype))))
5822 : return false;
5823 :
5824 11624 : tree weak = gimple_call_arg (stmt, 3);
5825 11624 : if (!integer_zerop (weak) && !integer_onep (weak))
5826 : return false;
5827 :
5828 11624 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5829 11624 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5830 11624 : machine_mode mode = TYPE_MODE (itype);
5831 :
5832 11624 : if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
5833 : == CODE_FOR_nothing
5834 11624 : && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
5835 : return false;
5836 :
5837 23248 : 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 5737 : fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
5853 : {
5854 5737 : gimple *stmt = gsi_stmt (*gsi);
5855 5737 : tree fndecl = gimple_call_fndecl (stmt);
5856 5737 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5857 5737 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5858 5737 : tree ctype = build_complex_type (itype);
5859 5737 : tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
5860 5737 : bool throws = false;
5861 5737 : edge e = NULL;
5862 5737 : gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5863 : expected);
5864 5737 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5865 5737 : gimple_stmt_iterator gsiret = gsi_for_stmt (g);
5866 5737 : if (!useless_type_conversion_p (itype, TREE_TYPE (expected)))
5867 : {
5868 2655 : g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
5869 : build1 (VIEW_CONVERT_EXPR, itype,
5870 : gimple_assign_lhs (g)));
5871 2655 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5872 : }
5873 5737 : int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
5874 11091 : + int_size_in_bytes (itype);
5875 5737 : 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 5737 : build_int_cst (integer_type_node, flag),
5880 : gimple_call_arg (stmt, 4),
5881 : gimple_call_arg (stmt, 5));
5882 5737 : tree lhs = make_ssa_name (ctype);
5883 5737 : gimple_call_set_lhs (g, lhs);
5884 5737 : gimple_move_vops (g, stmt);
5885 5737 : tree oldlhs = gimple_call_lhs (stmt);
5886 5737 : if (stmt_can_throw_internal (cfun, stmt))
5887 : {
5888 203 : throws = true;
5889 203 : e = find_fallthru_edge (gsi_bb (*gsi)->succs);
5890 : }
5891 5737 : gimple_call_set_nothrow (as_a <gcall *> (g),
5892 5737 : gimple_call_nothrow_p (as_a <gcall *> (stmt)));
5893 5737 : gimple_call_set_lhs (stmt, NULL_TREE);
5894 5737 : gsi_replace (gsi, g, true);
5895 5737 : if (oldlhs)
5896 : {
5897 5690 : g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
5898 : build1 (IMAGPART_EXPR, itype, lhs));
5899 5690 : if (throws)
5900 : {
5901 197 : gsi_insert_on_edge_immediate (e, g);
5902 197 : *gsi = gsi_for_stmt (g);
5903 : }
5904 : else
5905 5493 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5906 5690 : g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
5907 5690 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5908 : }
5909 5737 : g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
5910 : build1 (REALPART_EXPR, itype, lhs));
5911 5737 : 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 5731 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5918 5737 : if (!useless_type_conversion_p (TREE_TYPE (expected), itype))
5919 : {
5920 5310 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5921 : VIEW_CONVERT_EXPR,
5922 2655 : build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected),
5923 : gimple_assign_lhs (g)));
5924 2655 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5925 : }
5926 5737 : g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
5927 5737 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5928 5737 : *gsi = gsiret;
5929 5737 : }
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 450715 : arith_overflowed_p (enum tree_code code, const_tree type,
5937 : const_tree arg0, const_tree arg1)
5938 : {
5939 450715 : widest2_int warg0 = widest2_int_cst (arg0);
5940 450715 : widest2_int warg1 = widest2_int_cst (arg1);
5941 450715 : widest2_int wres;
5942 450715 : switch (code)
5943 : {
5944 97456 : case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
5945 115798 : case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
5946 238912 : case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
5947 0 : default: gcc_unreachable ();
5948 : }
5949 450715 : signop sign = TYPE_SIGN (type);
5950 450715 : if (sign == UNSIGNED && wi::neg_p (wres))
5951 : return true;
5952 378777 : return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
5953 450855 : }
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 7899 : partial_load_store_mask_state (gcall *call, tree vectype)
5968 : {
5969 7899 : internal_fn ifn = gimple_call_internal_fn (call);
5970 7899 : int mask_index = internal_fn_mask_index (ifn);
5971 7899 : int len_index = internal_fn_len_index (ifn);
5972 :
5973 : /* Extract length and mask arguments up front. */
5974 7899 : 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 7899 : tree mask = mask_index != -1 ? gimple_call_arg (call, mask_index) : NULL_TREE;
5977 :
5978 15798 : poly_int64 nelts = GET_MODE_NUNITS (TYPE_MODE (vectype));
5979 :
5980 7899 : poly_widest_int wlen = -1;
5981 7899 : bool full_length_p = !len; /* No length means full length. */
5982 :
5983 : /* Compute effective length. */
5984 7899 : 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 7899 : full_length_p = false;
5996 : }
5997 :
5998 : /* Check mask for early return cases. */
5999 7899 : if (mask)
6000 : {
6001 7899 : if (integer_zerop (mask))
6002 : return MASK_ALL_INACTIVE;
6003 :
6004 7884 : 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 7734 : if (!nelts.is_constant ())
6013 : return MASK_UNKNOWN;
6014 :
6015 : /* Same for VLS vectors with non-constant mask. */
6016 7734 : 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 7899 : }
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 3942 : gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype)
6051 : {
6052 : /* Only fold if all lanes are active (unconditional). */
6053 3942 : 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 3957 : gimple_fold_partial_load_store (gimple_stmt_iterator *gsi, gcall *call)
6072 : {
6073 3957 : internal_fn ifn = gimple_call_internal_fn (call);
6074 3957 : tree lhs = gimple_call_lhs (call);
6075 3957 : bool is_load = (lhs != NULL_TREE);
6076 3957 : tree vectype;
6077 :
6078 3957 : if (is_load)
6079 1965 : 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 3957 : enum mask_load_store_state state
6087 3957 : = partial_load_store_mask_state (call, vectype);
6088 :
6089 : /* Handle all-inactive case. */
6090 3957 : 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 3942 : if (internal_gather_scatter_fn_p (ifn)
6124 3942 : || TREE_CODE (vectype) == ARRAY_TYPE)
6125 : return false;
6126 :
6127 : /* Handle all-active case by folding to regular memory operation. */
6128 3942 : 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 59001067 : gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
6155 : {
6156 59001067 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
6157 59001067 : tree callee;
6158 59001067 : bool changed = false;
6159 :
6160 : /* Check for virtual calls that became direct calls. */
6161 59001067 : callee = gimple_call_fn (stmt);
6162 59001067 : if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
6163 : {
6164 473946 : 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 473544 : else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
6183 : {
6184 468467 : bool final;
6185 468467 : vec <cgraph_node *>targets
6186 468467 : = possible_polymorphic_call_targets (callee, stmt, &final);
6187 471131 : 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 59001028 : if (gimple_call_chain (stmt))
6254 : {
6255 246682 : tree fn = gimple_call_fndecl (stmt);
6256 295791 : if (fn && !DECL_STATIC_CHAIN (fn))
6257 : {
6258 2054 : gimple_call_set_chain (stmt, NULL);
6259 2054 : changed = true;
6260 : }
6261 : }
6262 :
6263 59001028 : if (inplace)
6264 : return changed;
6265 :
6266 : /* Don't constant fold functions which can change the control. */
6267 58997812 : 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 50990650 : if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
6273 : {
6274 9687458 : if (gimple_fold_builtin (gsi))
6275 212620 : changed = true;
6276 : }
6277 41303192 : else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
6278 : {
6279 1157333 : changed |= targetm.gimple_fold_builtin (gsi);
6280 : }
6281 40145859 : else if (gimple_call_internal_p (stmt))
6282 : {
6283 1953822 : enum tree_code subcode = ERROR_MARK;
6284 1953822 : tree result = NULL_TREE;
6285 1953822 : bool cplx_result = false;
6286 1953822 : bool uaddc_usubc = false;
6287 1953822 : tree overflow = NULL_TREE;
6288 1953822 : switch (gimple_call_internal_fn (stmt))
6289 : {
6290 872 : case IFN_ASSUME:
6291 : /* Remove .ASSUME calls during the last fold since it is no
6292 : longer needed. */
6293 872 : if (fold_before_rtl_expansion_p ())
6294 118 : replace_call_with_value (gsi, NULL_TREE);
6295 : break;
6296 166733 : case IFN_BUILTIN_EXPECT:
6297 166733 : 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 166733 : 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 11660 : case IFN_UBSAN_PTR:
6318 11660 : 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 3957 : case IFN_LEN_LOAD:
6377 3957 : case IFN_MASK_LOAD:
6378 3957 : case IFN_MASK_LEN_LOAD:
6379 3957 : case IFN_MASK_GATHER_LOAD:
6380 3957 : case IFN_MASK_LEN_GATHER_LOAD:
6381 3957 : case IFN_MASK_LOAD_LANES:
6382 3957 : case IFN_MASK_LEN_LOAD_LANES:
6383 3957 : case IFN_LEN_STORE:
6384 3957 : case IFN_MASK_STORE:
6385 3957 : case IFN_MASK_LEN_STORE:
6386 3957 : case IFN_MASK_SCATTER_STORE:
6387 3957 : case IFN_MASK_LEN_SCATTER_STORE:
6388 3957 : case IFN_MASK_STORE_LANES:
6389 3957 : case IFN_MASK_LEN_STORE_LANES:
6390 3957 : changed |= gimple_fold_partial_load_store (gsi, stmt);
6391 3957 : break;
6392 : default:
6393 : break;
6394 : }
6395 191397 : if (subcode != ERROR_MARK)
6396 : {
6397 499025 : tree arg0 = gimple_call_arg (stmt, 0);
6398 499025 : tree arg1 = gimple_call_arg (stmt, 1);
6399 499025 : tree arg2 = NULL_TREE;
6400 499025 : tree type = TREE_TYPE (arg0);
6401 499025 : if (cplx_result)
6402 : {
6403 479654 : tree lhs = gimple_call_lhs (stmt);
6404 479654 : if (lhs == NULL_TREE)
6405 : type = NULL_TREE;
6406 : else
6407 479654 : type = TREE_TYPE (TREE_TYPE (lhs));
6408 479654 : if (uaddc_usubc)
6409 32988 : arg2 = gimple_call_arg (stmt, 2);
6410 : }
6411 499025 : if (type == NULL_TREE)
6412 : ;
6413 499025 : else if (uaddc_usubc)
6414 : {
6415 32988 : if (!integer_zerop (arg2))
6416 : ;
6417 : /* x = y + 0 + 0; x = y - 0 - 0; */
6418 5218 : 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 466037 : else if (integer_zerop (arg1))
6430 10103 : result = subcode == MULT_EXPR ? integer_zero_node : arg0;
6431 : /* x = 0 + y; x = 0 * y; */
6432 455934 : else if (subcode != MINUS_EXPR && integer_zerop (arg0))
6433 0 : result = subcode == MULT_EXPR ? integer_zero_node : arg1;
6434 : /* x = y - y; */
6435 455934 : 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 455921 : else if (subcode == MULT_EXPR && integer_onep (arg1))
6439 : result = arg0;
6440 450504 : else if (subcode == MULT_EXPR && integer_onep (arg0))
6441 : result = arg1;
6442 499025 : if (result)
6443 : {
6444 16171 : if (result == integer_zero_node)
6445 2148 : result = build_zero_cst (type);
6446 14023 : else if (cplx_result && TREE_TYPE (result) != type)
6447 : {
6448 9708 : 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 9708 : else if ((!TYPE_UNSIGNED (TREE_TYPE (result))
6455 6988 : && TYPE_UNSIGNED (type))
6456 9890 : || (TYPE_PRECISION (type)
6457 2902 : < (TYPE_PRECISION (TREE_TYPE (result))
6458 2902 : + (TYPE_UNSIGNED (TREE_TYPE (result))
6459 3297 : && !TYPE_UNSIGNED (type)))))
6460 : result = NULL_TREE;
6461 64 : if (result)
6462 64 : result = fold_convert (type, result);
6463 : }
6464 : }
6465 : }
6466 :
6467 1459469 : if (result)
6468 : {
6469 29074 : if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
6470 0 : result = drop_tree_overflow (result);
6471 29074 : if (cplx_result)
6472 : {
6473 6516 : if (overflow == NULL_TREE)
6474 6516 : overflow = build_zero_cst (TREE_TYPE (result));
6475 6516 : tree ctype = build_complex_type (TREE_TYPE (result));
6476 6516 : if (TREE_CODE (result) == INTEGER_CST
6477 2148 : && TREE_CODE (overflow) == INTEGER_CST)
6478 2148 : result = build_complex (ctype, result, overflow);
6479 : else
6480 4368 : result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
6481 : ctype, result, overflow);
6482 : }
6483 29074 : gimplify_and_update_call_from_tree (gsi, result);
6484 29074 : 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 1699 : has_use_on_stmt (tree name, gimple *stmt)
6498 : {
6499 1699 : ssa_op_iter iter;
6500 1699 : tree op;
6501 3434 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
6502 1781 : 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 4983228 : mark_lhs_in_seq_for_dce (bitmap dce_worklist, gimple_seq seq)
6511 : {
6512 4983228 : if (!dce_worklist)
6513 : return;
6514 :
6515 1759285 : for (gimple_stmt_iterator i = gsi_start (seq);
6516 2061768 : !gsi_end_p (i); gsi_next (&i))
6517 : {
6518 302483 : gimple *stmt = gsi_stmt (i);
6519 302483 : tree name = gimple_get_lhs (stmt);
6520 302483 : if (name && TREE_CODE (name) == SSA_NAME)
6521 302483 : 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 9547666 : 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 9547666 : gimple *stmt = gsi_stmt (*gsi);
6539 9547666 : tree *ops = res_op->ops;
6540 9547666 : 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 21152483 : for (unsigned int i = 0; i < num_ops; ++i)
6547 11606470 : if (TREE_CODE (ops[i]) == SSA_NAME
6548 6977807 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i])
6549 11608169 : && !has_use_on_stmt (ops[i], stmt))
6550 : return false;
6551 :
6552 9546013 : 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 9546013 : if (inplace && !gimple_seq_empty_p (*seq))
6562 : return false;
6563 :
6564 9546013 : if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
6565 : {
6566 7143392 : gcc_assert (res_op->code.is_tree_code ());
6567 7143392 : auto code = tree_code (res_op->code);
6568 7143392 : if (TREE_CODE_CLASS (code) == tcc_comparison
6569 : /* GIMPLE_CONDs condition may not throw. */
6570 7143392 : && ((cfun
6571 1179982 : && (!flag_exceptions
6572 800233 : || !cfun->can_throw_non_call_exceptions))
6573 569063 : || !operation_could_trap_p (code,
6574 569063 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6575 : false, NULL_TREE)))
6576 1168538 : gimple_cond_set_condition (cond_stmt, code, ops[0], ops[1]);
6577 5974854 : else if (code == SSA_NAME)
6578 : {
6579 : /* If setting the gimple cond to the same thing,
6580 : return false as nothing changed. */
6581 4086318 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6582 4061556 : && operand_equal_p (gimple_cond_lhs (cond_stmt), ops[0])
6583 8145127 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6584 : return false;
6585 27509 : gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
6586 27509 : build_zero_cst (TREE_TYPE (ops[0])));
6587 : }
6588 1888536 : 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 1331007 : if (integer_zerop (ops[0]))
6594 : {
6595 922947 : if (gimple_cond_false_canonical_p (cond_stmt))
6596 : return false;
6597 535983 : gimple_cond_make_false (cond_stmt);
6598 : }
6599 : else
6600 : {
6601 408060 : if (gimple_cond_true_canonical_p (cond_stmt))
6602 : return false;
6603 215173 : gimple_cond_make_true (cond_stmt);
6604 : }
6605 : }
6606 557529 : 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 557529 : if (TREE_CODE_CLASS (code) == tcc_comparison
6614 11444 : && (!cfun
6615 11444 : || (flag_exceptions
6616 11444 : && cfun->can_throw_non_call_exceptions))
6617 568973 : && operation_could_trap_p (code,
6618 11444 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6619 : false, NULL_TREE))
6620 : {
6621 11444 : tree lhs = gimple_cond_lhs (cond_stmt);
6622 11444 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6623 11444 : && TREE_CODE (lhs) == SSA_NAME
6624 11444 : && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6625 22888 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6626 : {
6627 11444 : gimple *s = SSA_NAME_DEF_STMT (lhs);
6628 11444 : if (is_gimple_assign (s)
6629 11444 : && gimple_assign_rhs_code (s) == code
6630 11444 : && operand_equal_p (gimple_assign_rhs1 (s), ops[0])
6631 22888 : && operand_equal_p (gimple_assign_rhs2 (s), ops[1]))
6632 : return false;
6633 : }
6634 : }
6635 546085 : tree res = maybe_push_res_to_seq (res_op, seq);
6636 546085 : if (!res)
6637 : return false;
6638 546085 : gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
6639 546085 : build_zero_cst (TREE_TYPE (res)));
6640 : }
6641 : else
6642 : return false;
6643 2493288 : 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 2493288 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6653 2493288 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6654 2493288 : return true;
6655 : }
6656 2402621 : else if (is_gimple_assign (stmt)
6657 2402621 : && res_op->code.is_tree_code ())
6658 : {
6659 2320347 : auto code = tree_code (res_op->code);
6660 2320347 : if (!inplace
6661 2320347 : || gimple_num_ops (stmt) > get_gimple_rhs_num_ops (code))
6662 : {
6663 2320347 : maybe_build_generic_op (res_op);
6664 5463941 : 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 2320347 : if (dump_file && (dump_flags & TDF_DETAILS))
6669 : {
6670 17016 : fprintf (dump_file, "gimple_simplified to ");
6671 17016 : if (!gimple_seq_empty_p (*seq))
6672 330 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6673 17016 : 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 2320347 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6678 2320347 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6679 2320347 : return true;
6680 : }
6681 : }
6682 82274 : else if (res_op->code.is_fn_code ()
6683 82274 : && gimple_call_combined_fn (stmt) == combined_fn (res_op->code))
6684 : {
6685 8288 : gcc_assert (num_ops == gimple_call_num_args (stmt));
6686 24363 : for (unsigned int i = 0; i < num_ops; ++i)
6687 16075 : gimple_call_set_arg (stmt, i, ops[i]);
6688 8288 : 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 8288 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6697 8288 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6698 8288 : return true;
6699 : }
6700 73986 : else if (!inplace)
6701 : {
6702 145947 : if (gimple_has_lhs (stmt))
6703 : {
6704 73986 : tree lhs = gimple_get_lhs (stmt);
6705 73986 : if (!maybe_push_res_to_seq (res_op, seq, lhs))
6706 : return false;
6707 73003 : 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 73003 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6714 73003 : gsi_replace_with_seq_vops (gsi, *seq);
6715 73003 : 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 202385772 : maybe_canonicalize_mem_ref_addr (tree *t, bool is_debug = false)
6728 : {
6729 202385772 : bool res = false;
6730 202385772 : tree *orig_t = t;
6731 :
6732 202385772 : if (TREE_CODE (*t) == ADDR_EXPR)
6733 69961035 : 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 202385772 : if (TREE_CODE (*t) == ARRAY_REF
6741 11121889 : && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
6742 174652 : && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
6743 202439213 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
6744 : {
6745 24779 : tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
6746 24779 : if (VECTOR_TYPE_P (vtype))
6747 : {
6748 24779 : tree low = array_ref_low_bound (*t);
6749 24779 : if (TREE_CODE (low) == INTEGER_CST)
6750 : {
6751 24779 : if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
6752 : {
6753 49498 : widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
6754 49498 : wi::to_widest (low));
6755 24749 : idx = wi::mul (idx, wi::to_widest
6756 49498 : (TYPE_SIZE (TREE_TYPE (*t))));
6757 24749 : widest_int ext
6758 24749 : = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
6759 24749 : if (maybe_le (ext, wi::to_poly_widest (TYPE_SIZE (vtype))))
6760 : {
6761 48346 : *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
6762 24173 : TREE_TYPE (*t),
6763 24173 : TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
6764 24173 : TYPE_SIZE (TREE_TYPE (*t)),
6765 24173 : wide_int_to_tree (bitsizetype, idx));
6766 24173 : res = true;
6767 : }
6768 24749 : }
6769 : }
6770 : }
6771 : }
6772 :
6773 381405952 : while (handled_component_p (*t))
6774 179020180 : 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 202385772 : if (TREE_CODE (*t) == MEM_REF
6779 202385772 : || TREE_CODE (*t) == TARGET_MEM_REF)
6780 : {
6781 106799617 : tree addr = TREE_OPERAND (*t, 0);
6782 106799617 : if (TREE_CODE (addr) == ADDR_EXPR
6783 106799617 : && (TREE_CODE (TREE_OPERAND (addr, 0)) == MEM_REF
6784 32482292 : || handled_component_p (TREE_OPERAND (addr, 0))))
6785 : {
6786 575986 : tree base;
6787 575986 : poly_int64 coffset;
6788 575986 : base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
6789 : &coffset);
6790 575986 : if (!base)
6791 : {
6792 18 : if (is_debug)
6793 18 : return false;
6794 0 : gcc_unreachable ();
6795 : }
6796 :
6797 575968 : TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
6798 575968 : TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
6799 575968 : TREE_OPERAND (*t, 1),
6800 575968 : size_int (coffset));
6801 575968 : res = true;
6802 : }
6803 106799599 : 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 202385754 : if (TREE_CODE (*t) == MEM_REF
6810 104814611 : && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
6811 32191517 : && integer_zerop (TREE_OPERAND (*t, 1))
6812 219895873 : && MR_DEPENDENCE_CLIQUE (*t) == 0)
6813 : {
6814 12384850 : tree decl = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6815 12384850 : tree alias_type = TREE_TYPE (TREE_OPERAND (*t, 1));
6816 12384850 : if (/* Same volatile qualification. */
6817 12384850 : TREE_THIS_VOLATILE (*t) == TREE_THIS_VOLATILE (decl)
6818 : /* Same TBAA behavior with -fstrict-aliasing. */
6819 12381830 : && !TYPE_REF_CAN_ALIAS_ALL (alias_type)
6820 12028174 : && (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
6821 12028174 : == TYPE_MAIN_VARIANT (TREE_TYPE (alias_type)))
6822 : /* Same alignment. */
6823 4976662 : && 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 17074996 : && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (decl)))
6829 : {
6830 2624823 : *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6831 2624823 : res = true;
6832 : }
6833 : }
6834 :
6835 190000904 : else if (TREE_CODE (*orig_t) == ADDR_EXPR
6836 67021066 : && TREE_CODE (*t) == MEM_REF
6837 213196554 : && TREE_CODE (TREE_OPERAND (*t, 0)) == INTEGER_CST)
6838 : {
6839 857 : tree base;
6840 857 : poly_int64 coffset;
6841 857 : base = get_addr_base_and_unit_offset (TREE_OPERAND (*orig_t, 0),
6842 : &coffset);
6843 857 : if (base)
6844 : {
6845 753 : gcc_assert (TREE_CODE (base) == MEM_REF);
6846 753 : poly_int64 moffset;
6847 753 : if (mem_ref_offset (base).to_shwi (&moffset))
6848 : {
6849 753 : coffset += moffset;
6850 753 : if (wi::to_poly_wide (TREE_OPERAND (base, 0)).to_shwi (&moffset))
6851 : {
6852 753 : coffset += moffset;
6853 753 : *orig_t = build_int_cst (TREE_TYPE (*orig_t), coffset);
6854 753 : return true;
6855 : }
6856 : }
6857 : }
6858 : }
6859 :
6860 : /* Canonicalize TARGET_MEM_REF in particular with respect to
6861 : the indexes becoming constant. */
6862 190000047 : else if (TREE_CODE (*t) == TARGET_MEM_REF)
6863 : {
6864 1984988 : tree tem = maybe_fold_tmr (*t);
6865 1984988 : if (tem)
6866 : {
6867 4154 : *t = tem;
6868 4154 : 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 826447612 : fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree),
6882 : bitmap dce_worklist = nullptr)
6883 : {
6884 826447612 : bool changed = false;
6885 826447612 : gimple *stmt = gsi_stmt (*gsi);
6886 826447612 : 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 826447612 : switch (gimple_code (stmt))
6895 : {
6896 265260253 : case GIMPLE_ASSIGN:
6897 265260253 : if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
6898 : {
6899 175342392 : tree *rhs = gimple_assign_rhs1_ptr (stmt);
6900 175342392 : if ((REFERENCE_CLASS_P (*rhs)
6901 110844386 : || TREE_CODE (*rhs) == ADDR_EXPR)
6902 190902063 : && maybe_canonicalize_mem_ref_addr (rhs))
6903 : changed = true;
6904 175342392 : tree *lhs = gimple_assign_lhs_ptr (stmt);
6905 175342392 : if (REFERENCE_CLASS_P (*lhs)
6906 175342392 : && 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 175342392 : if (!inplace && TREE_CODE (*rhs) == ADDR_EXPR)
6915 : {
6916 15347319 : tree inner = TREE_OPERAND (*rhs, 0);
6917 15347319 : if (TREE_CODE (inner) == MEM_REF
6918 1107343 : && TREE_CODE (TREE_OPERAND (inner, 0)) == SSA_NAME
6919 15411653 : && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6920 : {
6921 64334 : tree ptr = TREE_OPERAND (inner, 0);
6922 64334 : tree addon = TREE_OPERAND (inner, 1);
6923 64334 : addon = fold_convert (sizetype, addon);
6924 64334 : gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR,
6925 : ptr, addon);
6926 64334 : changed = true;
6927 64334 : stmt = gsi_stmt (*gsi);
6928 : }
6929 : }
6930 : }
6931 : else
6932 : {
6933 : /* Canonicalize operand order. */
6934 89917861 : enum tree_code code = gimple_assign_rhs_code (stmt);
6935 89917861 : if (TREE_CODE_CLASS (code) == tcc_comparison
6936 83602461 : || commutative_tree_code (code)
6937 135310876 : || commutative_ternary_tree_code (code))
6938 : {
6939 44525854 : tree rhs1 = gimple_assign_rhs1 (stmt);
6940 44525854 : tree rhs2 = gimple_assign_rhs2 (stmt);
6941 44525854 : if (tree_swap_operands_p (rhs1, rhs2))
6942 : {
6943 2648570 : gimple_assign_set_rhs1 (stmt, rhs2);
6944 2648570 : gimple_assign_set_rhs2 (stmt, rhs1);
6945 2648570 : if (TREE_CODE_CLASS (code) == tcc_comparison)
6946 324279 : gimple_assign_set_rhs_code (stmt,
6947 : swap_tree_comparison (code));
6948 : changed = true;
6949 : }
6950 : }
6951 : }
6952 : break;
6953 59061089 : case GIMPLE_CALL:
6954 59061089 : {
6955 59061089 : gcall *call = as_a<gcall *> (stmt);
6956 235903466 : for (i = 0; i < gimple_call_num_args (call); ++i)
6957 : {
6958 117781288 : tree *arg = gimple_call_arg_ptr (call, i);
6959 117781288 : if (REFERENCE_CLASS_P (*arg)
6960 117781288 : && maybe_canonicalize_mem_ref_addr (arg))
6961 : changed = true;
6962 : }
6963 59061089 : tree *lhs = gimple_call_lhs_ptr (call);
6964 59061089 : if (*lhs
6965 23876436 : && REFERENCE_CLASS_P (*lhs)
6966 59186816 : && maybe_canonicalize_mem_ref_addr (lhs))
6967 : changed = true;
6968 59061089 : if (*lhs)
6969 : {
6970 23876436 : combined_fn cfn = gimple_call_combined_fn (call);
6971 23876436 : internal_fn ifn = associated_internal_fn (cfn, TREE_TYPE (*lhs));
6972 23876436 : int opno = first_commutative_argument (ifn);
6973 23876436 : if (opno >= 0)
6974 : {
6975 360148 : tree arg1 = gimple_call_arg (call, opno);
6976 360148 : tree arg2 = gimple_call_arg (call, opno + 1);
6977 360148 : if (tree_swap_operands_p (arg1, arg2))
6978 : {
6979 22766 : gimple_call_set_arg (call, opno, arg2);
6980 22766 : gimple_call_set_arg (call, opno + 1, arg1);
6981 22766 : changed = true;
6982 : }
6983 : }
6984 : }
6985 : break;
6986 : }
6987 546349 : case GIMPLE_ASM:
6988 546349 : {
6989 546349 : gasm *asm_stmt = as_a <gasm *> (stmt);
6990 1768805 : for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
6991 : {
6992 676107 : tree link = gimple_asm_output_op (asm_stmt, i);
6993 676107 : tree op = TREE_VALUE (link);
6994 676107 : if (REFERENCE_CLASS_P (op)
6995 676107 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
6996 : changed = true;
6997 : }
6998 968868 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
6999 : {
7000 422519 : tree link = gimple_asm_input_op (asm_stmt, i);
7001 422519 : tree op = TREE_VALUE (link);
7002 422519 : if ((REFERENCE_CLASS_P (op)
7003 400108 : || TREE_CODE (op) == ADDR_EXPR)
7004 454429 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
7005 : changed = true;
7006 : }
7007 : }
7008 : break;
7009 433504571 : case GIMPLE_DEBUG:
7010 433504571 : if (gimple_debug_bind_p (stmt))
7011 : {
7012 335542590 : tree *val = gimple_debug_bind_get_value_ptr (stmt);
7013 335542590 : if (*val
7014 191502060 : && (REFERENCE_CLASS_P (*val)
7015 188782946 : || TREE_CODE (*val) == ADDR_EXPR)
7016 392631158 : && maybe_canonicalize_mem_ref_addr (val, true))
7017 : changed = true;
7018 : }
7019 : break;
7020 46638644 : case GIMPLE_COND:
7021 46638644 : {
7022 : /* Canonicalize operand order. */
7023 46638644 : tree lhs = gimple_cond_lhs (stmt);
7024 46638644 : tree rhs = gimple_cond_rhs (stmt);
7025 46638644 : if (tree_swap_operands_p (lhs, rhs))
7026 : {
7027 1465075 : gcond *gc = as_a <gcond *> (stmt);
7028 1465075 : gimple_cond_set_lhs (gc, rhs);
7029 1465075 : gimple_cond_set_rhs (gc, lhs);
7030 1465075 : gimple_cond_set_code (gc,
7031 : swap_tree_comparison (gimple_cond_code (gc)));
7032 1465075 : changed = true;
7033 : }
7034 : }
7035 824866742 : default:;
7036 : }
7037 :
7038 : /* Dispatch to pattern-based folding. */
7039 824866742 : if (!inplace
7040 3320695 : || is_gimple_assign (stmt)
7041 825809802 : || gimple_code (stmt) == GIMPLE_COND)
7042 : {
7043 825504552 : gimple_seq seq = NULL;
7044 825504552 : gimple_match_op res_op;
7045 1648631469 : if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
7046 : valueize, valueize)
7047 825504552 : && replace_stmt_with_simplification (gsi, &res_op, &seq, inplace,
7048 : dce_worklist))
7049 : changed = true;
7050 : else
7051 820609626 : gimple_seq_discard (seq);
7052 : }
7053 :
7054 826447612 : stmt = gsi_stmt (*gsi);
7055 :
7056 : /* Fold the main computation performed by the statement. */
7057 826447612 : switch (gimple_code (stmt))
7058 : {
7059 265320275 : case GIMPLE_ASSIGN:
7060 265320275 : {
7061 : /* Try to canonicalize for boolean-typed X the comparisons
7062 : X == 0, X == 1, X != 0, and X != 1. */
7063 265320275 : if (gimple_assign_rhs_code (stmt) == EQ_EXPR
7064 265320275 : || gimple_assign_rhs_code (stmt) == NE_EXPR)
7065 : {
7066 3535387 : tree lhs = gimple_assign_lhs (stmt);
7067 3535387 : tree op1 = gimple_assign_rhs1 (stmt);
7068 3535387 : tree op2 = gimple_assign_rhs2 (stmt);
7069 3535387 : 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 3535387 : if (TREE_CODE (op2) == INTEGER_CST
7076 2430680 : && (integer_zerop (op2) || integer_onep (op2))
7077 5341237 : && useless_type_conversion_p (TREE_TYPE (lhs), type))
7078 : {
7079 4828 : enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
7080 4828 : 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 4008 : if ((cmp_code == EQ_EXPR && integer_zerop (op2))
7085 4828 : || (cmp_code == NE_EXPR && integer_onep (op2)))
7086 4771 : is_logical_not = true;
7087 :
7088 4828 : 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 4771 : else if (TYPE_PRECISION (type) == 1)
7093 4771 : 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 265315447 : unsigned old_num_ops = gimple_num_ops (stmt);
7104 265315447 : tree lhs = gimple_assign_lhs (stmt);
7105 265315447 : tree new_rhs = fold_gimple_assign (gsi);
7106 265315447 : if (new_rhs
7107 265436653 : && !useless_type_conversion_p (TREE_TYPE (lhs),
7108 121206 : TREE_TYPE (new_rhs)))
7109 0 : new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
7110 265315447 : if (new_rhs
7111 265315447 : && (!inplace
7112 1064 : || get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
7113 : {
7114 121206 : gimple_assign_set_rhs_from_tree (gsi, new_rhs);
7115 121206 : changed = true;
7116 : }
7117 : break;
7118 : }
7119 :
7120 59001067 : case GIMPLE_CALL:
7121 59001067 : changed |= gimple_fold_call (gsi, inplace);
7122 59001067 : break;
7123 :
7124 433504571 : case GIMPLE_DEBUG:
7125 433504571 : if (gimple_debug_bind_p (stmt))
7126 : {
7127 335542590 : tree val = gimple_debug_bind_get_value (stmt);
7128 335542590 : if (val && REFERENCE_CLASS_P (val))
7129 : {
7130 2717171 : tree tem = maybe_fold_reference (val);
7131 2717171 : if (tem)
7132 : {
7133 4428 : gimple_debug_bind_set_value (stmt, tem);
7134 4428 : changed = true;
7135 : }
7136 : }
7137 : }
7138 : break;
7139 :
7140 11149520 : case GIMPLE_RETURN:
7141 11149520 : {
7142 11149520 : greturn *ret_stmt = as_a<greturn *> (stmt);
7143 11149520 : tree ret = gimple_return_retval(ret_stmt);
7144 :
7145 11149520 : if (ret && TREE_CODE (ret) == SSA_NAME && valueize)
7146 : {
7147 4679532 : tree val = valueize (ret);
7148 4679532 : if (val && val != ret
7149 4679532 : && 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 826447612 : default:;
7159 : }
7160 :
7161 826447612 : return changed;
7162 : }
7163 :
7164 : /* Valueziation callback that ends up not following SSA edges. */
7165 :
7166 : tree
7167 6419018340 : no_follow_ssa_edges (tree)
7168 : {
7169 6419018340 : return NULL_TREE;
7170 : }
7171 :
7172 : /* Valueization callback that ends up following single-use SSA edges only. */
7173 :
7174 : tree
7175 984749429 : follow_single_use_edges (tree val)
7176 : {
7177 984749429 : if (TREE_CODE (val) == SSA_NAME
7178 984749429 : && !has_single_use (val))
7179 505463129 : return NULL_TREE;
7180 : return val;
7181 : }
7182 :
7183 : /* Valueization callback that follows all SSA edges. */
7184 :
7185 : tree
7186 198470254 : follow_all_ssa_edges (tree val)
7187 : {
7188 198470254 : 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 164585989 : fold_stmt (gimple_stmt_iterator *gsi, bitmap dce_bitmap)
7200 : {
7201 164585989 : return fold_stmt_1 (gsi, false, no_follow_ssa_edges, dce_bitmap);
7202 : }
7203 :
7204 : bool
7205 658540928 : fold_stmt (gimple_stmt_iterator *gsi, tree (*valueize) (tree), bitmap dce_bitmap)
7206 : {
7207 658540928 : 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 3320695 : fold_stmt_inplace (gimple_stmt_iterator *gsi, tree (*valueize) (tree))
7220 : {
7221 3320695 : gimple *stmt = gsi_stmt (*gsi);
7222 3320695 : bool changed = fold_stmt_1 (gsi, true, valueize);
7223 3320695 : gcc_assert (gsi_stmt (*gsi) == stmt);
7224 3320695 : 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 228792 : canonicalize_bool (tree expr, bool invert)
7233 : {
7234 228792 : if (!expr)
7235 : return NULL_TREE;
7236 26 : else if (invert)
7237 : {
7238 14 : if (integer_nonzerop (expr))
7239 0 : return boolean_false_node;
7240 14 : else if (integer_zerop (expr))
7241 0 : return boolean_true_node;
7242 14 : 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 14 : else if (COMPARISON_CLASS_P (expr))
7246 14 : 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 12 : 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 1076 : same_bool_comparison_p (const_tree expr, enum tree_code code,
7280 : const_tree op1, const_tree op2)
7281 : {
7282 1076 : gimple *s;
7283 :
7284 : /* The obvious case. */
7285 1076 : if (TREE_CODE (expr) == code
7286 17 : && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
7287 1093 : && 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 1069 : if (TREE_CODE (expr) == SSA_NAME
7293 1069 : && 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 1069 : if (TREE_CODE (op1) == SSA_NAME
7309 1069 : && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
7310 : {
7311 206 : s = SSA_NAME_DEF_STMT (op1);
7312 206 : if (is_gimple_assign (s)
7313 206 : && 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 8 : same_bool_result_p (const_tree op1, const_tree op2)
7337 : {
7338 : /* Simple cases first. */
7339 8 : 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 5 : if (COMPARISON_CLASS_P (op2)
7346 10 : && same_bool_comparison_p (op1, TREE_CODE (op2),
7347 5 : TREE_OPERAND (op2, 0),
7348 5 : TREE_OPERAND (op2, 1)))
7349 : return true;
7350 5 : if (COMPARISON_CLASS_P (op1)
7351 10 : && same_bool_comparison_p (op2, TREE_CODE (op1),
7352 5 : TREE_OPERAND (op1, 0),
7353 5 : 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 182064 : 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 182064 : tree t;
7397 182064 : gimple *stmt = SSA_NAME_DEF_STMT (var);
7398 :
7399 : /* We can only deal with variables whose definitions are assignments. */
7400 182064 : 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 181753 : if (invert)
7407 64298 : t = or_var_with_comparison_1 (type, stmt,
7408 : invert_tree_comparison (code2, false),
7409 : op2a, op2b, outer_cond_bb);
7410 : else
7411 117455 : t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
7412 : outer_cond_bb);
7413 181753 : 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 140372 : 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 140372 : tree var = gimple_assign_lhs (stmt);
7426 140372 : tree true_test_var = NULL_TREE;
7427 140372 : tree false_test_var = NULL_TREE;
7428 140372 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
7429 :
7430 : /* Check for identities like (var AND (var == 0)) => false. */
7431 140372 : if (TREE_CODE (op2a) == SSA_NAME
7432 140372 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
7433 : {
7434 6327 : if ((code2 == NE_EXPR && integer_zerop (op2b))
7435 14889 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
7436 : {
7437 6721 : true_test_var = op2a;
7438 6721 : if (var == true_test_var)
7439 : return var;
7440 : }
7441 3148 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
7442 9496 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
7443 : {
7444 1345 : false_test_var = op2a;
7445 1345 : 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 140372 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
7452 : {
7453 247 : 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 247 : 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 140372 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
7466 140372 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
7467 : {
7468 9440 : tree inner1 = gimple_assign_rhs1 (stmt);
7469 9440 : tree inner2 = gimple_assign_rhs2 (stmt);
7470 9440 : gimple *s;
7471 9440 : tree t;
7472 9440 : tree partial = NULL_TREE;
7473 9440 : 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 9440 : if (inner1 == true_test_var)
7483 0 : return (is_and ? var : inner1);
7484 9440 : else if (inner2 == true_test_var)
7485 0 : return (is_and ? var : inner2);
7486 9440 : 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 9440 : 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 9440 : if (TREE_CODE (inner1) == SSA_NAME
7500 9440 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
7501 8995 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7502 17294 : && (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 18 : if (is_and)
7514 : {
7515 0 : if (integer_onep (t))
7516 : return inner2;
7517 0 : 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 18 : 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 9440 : if (TREE_CODE (inner2) == SSA_NAME
7533 9440 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
7534 9201 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7535 17430 : && (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 58 : if (is_and)
7545 : {
7546 19 : if (integer_onep (t))
7547 : return inner1;
7548 19 : 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 18 : 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 39 : if (integer_onep (t))
7563 0 : return boolean_true_node;
7564 39 : 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 608366 : 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 608366 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
7597 :
7598 : /* First check for ((x CODE1 y) AND (x CODE2 y)). */
7599 608366 : if (operand_equal_p (op1a, op2a, 0)
7600 608366 : && operand_equal_p (op1b, op2b, 0))
7601 : {
7602 : /* Result will be either NULL_TREE, or a combined comparison. */
7603 3182 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7604 : TRUTH_ANDIF_EXPR, code1, code2,
7605 : truth_type, op1a, op1b);
7606 3182 : if (t)
7607 : return t;
7608 : }
7609 :
7610 : /* Likewise the swapped case of the above. */
7611 606614 : if (operand_equal_p (op1a, op2b, 0)
7612 606614 : && operand_equal_p (op1b, op2a, 0))
7613 : {
7614 : /* Result will be either NULL_TREE, or a combined comparison. */
7615 5 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7616 : TRUTH_ANDIF_EXPR, code1,
7617 : swap_tree_comparison (code2),
7618 : truth_type, op1a, op1b);
7619 5 : 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 : /* ??? Do the same for op2a, but as we are recursing we have to track
7627 : whether we swap the order of the comparsions since that's important
7628 : with respect to exceptions. */
7629 606613 : if (TREE_CODE (op1a) == SSA_NAME
7630 606601 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
7631 1086724 : && (integer_zerop (op1b) || integer_onep (op1b)))
7632 : {
7633 93247 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
7634 236453 : || (code1 == NE_EXPR && integer_onep (op1b)));
7635 216780 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
7636 216780 : switch (gimple_code (stmt))
7637 : {
7638 181089 : case GIMPLE_ASSIGN:
7639 : /* Try to simplify by copy-propagating the definition. */
7640 181089 : return and_var_with_comparison (type, op1a, invert, code2, op2a,
7641 181089 : op2b, outer_cond_bb);
7642 :
7643 15205 : case GIMPLE_PHI:
7644 : /* If every argument to the PHI produces the same result when
7645 : ANDed with the second comparison, we win.
7646 : Do not do this unless the type is bool since we need a bool
7647 : result here anyway. */
7648 15205 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
7649 : {
7650 : tree result = NULL_TREE;
7651 : unsigned i;
7652 6532 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
7653 : {
7654 6532 : tree arg = gimple_phi_arg_def (stmt, i);
7655 :
7656 : /* If this PHI has itself as an argument, ignore it.
7657 : If all the other args produce the same result,
7658 : we're still OK. */
7659 6532 : if (arg == gimple_phi_result (stmt))
7660 0 : continue;
7661 6532 : else if (TREE_CODE (arg) == INTEGER_CST)
7662 : {
7663 5175 : if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
7664 : {
7665 3305 : if (!result)
7666 1152 : result = boolean_false_node;
7667 2153 : else if (!integer_zerop (result))
7668 : return NULL_TREE;
7669 : }
7670 1870 : else if (!result)
7671 1010 : result = fold_build2 (code2, boolean_type_node,
7672 : op2a, op2b);
7673 860 : else if (!same_bool_comparison_p (result,
7674 : code2, op2a, op2b))
7675 : return NULL_TREE;
7676 : }
7677 1357 : else if (TREE_CODE (arg) == SSA_NAME
7678 1357 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
7679 : {
7680 1354 : tree temp;
7681 1354 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
7682 : /* In simple cases we can look through PHI nodes,
7683 : but we have to be careful with loops.
7684 : See PR49073. */
7685 1354 : if (! dom_info_available_p (CDI_DOMINATORS)
7686 1354 : || gimple_bb (def_stmt) == gimple_bb (stmt)
7687 2708 : || dominated_by_p (CDI_DOMINATORS,
7688 1354 : gimple_bb (def_stmt),
7689 1354 : gimple_bb (stmt)))
7690 : return NULL_TREE;
7691 975 : temp = and_var_with_comparison (type, arg, invert, code2,
7692 : op2a, op2b,
7693 : outer_cond_bb);
7694 975 : if (!temp)
7695 : return NULL_TREE;
7696 0 : else if (!result)
7697 : result = temp;
7698 0 : else if (!same_bool_result_p (result, temp))
7699 : return NULL_TREE;
7700 : }
7701 : else
7702 : return NULL_TREE;
7703 : }
7704 : return result;
7705 : }
7706 :
7707 : default:
7708 : break;
7709 : }
7710 : }
7711 : return NULL_TREE;
7712 : }
7713 :
7714 : static basic_block fosa_bb;
7715 : static vec<std::pair<tree, flow_sensitive_info_storage> > *fosa_unwind;
7716 : static tree
7717 54405340 : follow_outer_ssa_edges (tree val)
7718 : {
7719 54405340 : if (TREE_CODE (val) == SSA_NAME
7720 54405340 : && !SSA_NAME_IS_DEFAULT_DEF (val))
7721 : {
7722 53494121 : basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (val));
7723 53494121 : if (!def_bb
7724 18655058 : || def_bb == fosa_bb
7725 63342665 : || (dom_info_available_p (CDI_DOMINATORS)
7726 9848544 : && (def_bb == fosa_bb
7727 9848544 : || dominated_by_p (CDI_DOMINATORS, fosa_bb, def_bb))))
7728 : return val;
7729 6925623 : flow_sensitive_info_storage storage;
7730 6925623 : storage.save_and_clear (val);
7731 : /* If the definition does not dominate fosa_bb temporarily reset
7732 : flow-sensitive info. */
7733 6925623 : fosa_unwind->safe_push (std::make_pair (val, storage));
7734 : /* We cannot temporarily rewrite stmts with undefined overflow
7735 : behavior, so avoid expanding them. But still save off the
7736 : flow-sensitive info as we might be using the ssa name as the leaf. */
7737 13813571 : if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val))
7738 840970 : || POINTER_TYPE_P (TREE_TYPE (val)))
7739 13390997 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val)))
7740 3981961 : return NULL_TREE;
7741 : return val;
7742 : }
7743 : return val;
7744 : }
7745 :
7746 : /* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
7747 : : try to simplify the AND/OR of the ssa variable VAR with the comparison
7748 : specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't
7749 : simplify this to a single expression. As we are going to lower the cost
7750 : of building SSA names / gimple stmts significantly, we need to allocate
7751 : them ont the stack. This will cause the code to be a bit ugly. */
7752 :
7753 : static tree
7754 861485 : maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
7755 : enum tree_code code1,
7756 : tree op1a, tree op1b,
7757 : enum tree_code code2, tree op2a,
7758 : tree op2b,
7759 : basic_block outer_cond_bb)
7760 : {
7761 : /* Allocate gimple stmt1 on the stack. */
7762 861485 : gassign *stmt1
7763 861485 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7764 861485 : gimple_init (stmt1, GIMPLE_ASSIGN, 3);
7765 861485 : gimple_assign_set_rhs_code (stmt1, code1);
7766 861485 : gimple_assign_set_rhs1 (stmt1, op1a);
7767 861485 : gimple_assign_set_rhs2 (stmt1, op1b);
7768 861485 : gimple_set_bb (stmt1, NULL);
7769 :
7770 : /* Allocate gimple stmt2 on the stack. */
7771 861485 : gassign *stmt2
7772 861485 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7773 861485 : gimple_init (stmt2, GIMPLE_ASSIGN, 3);
7774 861485 : gimple_assign_set_rhs_code (stmt2, code2);
7775 861485 : gimple_assign_set_rhs1 (stmt2, op2a);
7776 861485 : gimple_assign_set_rhs2 (stmt2, op2b);
7777 861485 : gimple_set_bb (stmt2, NULL);
7778 :
7779 : /* Allocate SSA names(lhs1) on the stack. */
7780 861485 : alignas (tree_node) unsigned char lhs1buf[sizeof (tree_ssa_name)];
7781 861485 : tree lhs1 = (tree) &lhs1buf[0];
7782 861485 : memset (lhs1, 0, sizeof (tree_ssa_name));
7783 861485 : TREE_SET_CODE (lhs1, SSA_NAME);
7784 861485 : TREE_TYPE (lhs1) = type;
7785 861485 : init_ssa_name_imm_use (lhs1);
7786 :
7787 : /* Allocate SSA names(lhs2) on the stack. */
7788 861485 : alignas (tree_node) unsigned char lhs2buf[sizeof (tree_ssa_name)];
7789 861485 : tree lhs2 = (tree) &lhs2buf[0];
7790 861485 : memset (lhs2, 0, sizeof (tree_ssa_name));
7791 861485 : TREE_SET_CODE (lhs2, SSA_NAME);
7792 861485 : TREE_TYPE (lhs2) = type;
7793 861485 : init_ssa_name_imm_use (lhs2);
7794 :
7795 861485 : gimple_assign_set_lhs (stmt1, lhs1);
7796 861485 : gimple_assign_set_lhs (stmt2, lhs2);
7797 :
7798 861485 : gimple_match_op op (gimple_match_cond::UNCOND, code,
7799 : type, gimple_assign_lhs (stmt1),
7800 861485 : gimple_assign_lhs (stmt2));
7801 861485 : fosa_bb = outer_cond_bb;
7802 861485 : auto_vec<std::pair<tree, flow_sensitive_info_storage>, 8> unwind_stack;
7803 861485 : fosa_unwind = &unwind_stack;
7804 1376860 : if (op.resimplify (NULL, (!outer_cond_bb
7805 : ? follow_all_ssa_edges : follow_outer_ssa_edges)))
7806 : {
7807 2257 : fosa_unwind = NULL;
7808 8050 : for (auto p : unwind_stack)
7809 1279 : p.second.restore (p.first);
7810 2257 : if (gimple_simplified_result_is_gimple_val (&op))
7811 : {
7812 1328 : tree res = op.ops[0];
7813 1328 : if (res == lhs1)
7814 163 : return build2 (code1, type, op1a, op1b);
7815 1165 : else if (res == lhs2)
7816 1132 : return build2 (code2, type, op2a, op2b);
7817 : else
7818 : return res;
7819 : }
7820 929 : else if (op.code.is_tree_code ()
7821 929 : && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
7822 : {
7823 929 : tree op0 = op.ops[0];
7824 929 : tree op1 = op.ops[1];
7825 929 : if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
7826 : return NULL_TREE; /* not simple */
7827 :
7828 929 : return build2 ((enum tree_code)op.code, op.type, op0, op1);
7829 : }
7830 : }
7831 859228 : fosa_unwind = NULL;
7832 9502028 : for (auto p : unwind_stack)
7833 6924344 : p.second.restore (p.first);
7834 :
7835 859228 : return NULL_TREE;
7836 861485 : }
7837 :
7838 : /* Return TRUE and set op[0] if T, following all SSA edges, is a type
7839 : conversion. Reject loads if LOAD is NULL, otherwise set *LOAD if a
7840 : converting load is found. */
7841 :
7842 : static bool
7843 3327156 : gimple_convert_def_p (tree t, tree op[1], gimple **load = NULL)
7844 : {
7845 3327156 : bool ret = false;
7846 :
7847 3327156 : if (TREE_CODE (t) == SSA_NAME
7848 3327156 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7849 1849628 : if (gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7850 : {
7851 1757420 : bool load_p = gimple_assign_load_p (def);
7852 1757420 : if (load_p && !load)
7853 : return false;
7854 1744770 : switch (gimple_assign_rhs_code (def))
7855 : {
7856 14573 : CASE_CONVERT:
7857 14573 : op[0] = gimple_assign_rhs1 (def);
7858 14573 : ret = true;
7859 14573 : break;
7860 :
7861 4093 : case VIEW_CONVERT_EXPR:
7862 4093 : op[0] = TREE_OPERAND (gimple_assign_rhs1 (def), 0);
7863 4093 : ret = true;
7864 4093 : break;
7865 :
7866 : default:
7867 : break;
7868 : }
7869 :
7870 18666 : if (ret && load_p)
7871 0 : *load = def;
7872 : }
7873 :
7874 : return ret;
7875 : }
7876 :
7877 : /* Return TRUE and set op[*] if T, following all SSA edges, resolves to a
7878 : binary expression with code CODE. */
7879 :
7880 : static bool
7881 3363102 : gimple_binop_def_p (enum tree_code code, tree t, tree op[2])
7882 : {
7883 3363102 : if (TREE_CODE (t) == SSA_NAME
7884 3363102 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7885 1883079 : if (gimple *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7886 1788301 : if (gimple_assign_rhs_code (def) == code)
7887 : {
7888 58675 : op[0] = gimple_assign_rhs1 (def);
7889 58675 : op[1] = gimple_assign_rhs2 (def);
7890 58675 : return true;
7891 : }
7892 : return false;
7893 : }
7894 : /* Subroutine for fold_truth_andor_1: decode a field reference.
7895 :
7896 : If *PEXP is a comparison reference, we return the innermost reference.
7897 :
7898 : *PBITSIZE is set to the number of bits in the reference, *PBITPOS is
7899 : set to the starting bit number.
7900 :
7901 : *PVOLATILEP is set to 1 if the any expression encountered is volatile;
7902 : otherwise it is not changed.
7903 :
7904 : *PUNSIGNEDP is set to the signedness of the field.
7905 :
7906 : *PREVERSEP is set to the storage order of the field.
7907 :
7908 : *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If
7909 : *PAND_MASK is initially set to a mask with nonzero precision, that mask is
7910 : combined with the found mask, or adjusted in precision to match.
7911 :
7912 : *PSIGNBIT is set to 1 if, before clipping to *PBITSIZE, the mask
7913 : encompassed bits that corresponded to extensions of the sign bit, or to -1
7914 : if the mask encompassed bits that would be extensions of the sign bit
7915 : and zeroed them out. Otherwise, it is set to 0.
7916 :
7917 : *PXORP is to be FALSE if EXP might be a XOR used in a compare, in which
7918 : case, if PXOR_CMP_OP is a zero constant, it will be overridden with *PEXP,
7919 : *PXORP will be set to TRUE, *PXOR_AND_MASK will be copied from *PAND_MASK,
7920 : and the left-hand operand of the XOR will be decoded. If *PXORP is TRUE,
7921 : PXOR_CMP_OP and PXOR_AND_MASK are supposed to be NULL, and then the
7922 : right-hand operand of the XOR will be decoded.
7923 :
7924 : *LOAD is set to the load stmt of the innermost reference, if any,
7925 : *and NULL otherwise.
7926 :
7927 : LOC[0..3] are filled in as conversion, masking, shifting and loading
7928 : operations are located.
7929 :
7930 : Return 0 if this is not a component reference or is one that we can't
7931 : do anything with. */
7932 :
7933 : static tree
7934 1191755 : decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize,
7935 : HOST_WIDE_INT *pbitpos,
7936 : bool *punsignedp, bool *preversep, bool *pvolatilep,
7937 : wide_int *pand_mask, int *psignbit,
7938 : bool *pxorp, tree *pxor_cmp_op, wide_int *pxor_and_mask,
7939 : gimple **pload, location_t loc[4])
7940 : {
7941 1191755 : tree exp = *pexp;
7942 1191755 : tree outer_type = 0;
7943 1191755 : wide_int and_mask;
7944 1191755 : tree inner, offset;
7945 1191755 : int shiftrt = 0;
7946 1191755 : tree res_ops[2];
7947 1191755 : machine_mode mode;
7948 1191755 : bool convert_before_shift = false;
7949 1191755 : int signbit = 0;
7950 1191755 : bool xorp = false;
7951 1191755 : tree xor_cmp_op;
7952 1191755 : wide_int xor_and_mask;
7953 1191755 : gimple *load = NULL;
7954 :
7955 : /* All the optimizations using this function assume integer fields.
7956 : There are problems with FP fields since the type_for_size call
7957 : below can fail for, e.g., XFmode. */
7958 1191755 : if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
7959 : return NULL_TREE;
7960 :
7961 : /* Drop casts, saving only the outermost type, effectively used in
7962 : the compare. We can deal with at most one conversion, and it may
7963 : appear at various points in the chain of recognized preparation
7964 : statements. Earlier optimizers will often have already dropped
7965 : unneeded extensions, but they may survive, as in PR118046. ???
7966 : Can we do better and allow multiple conversions, perhaps taking
7967 : note of the narrowest intermediate type, sign extensions and
7968 : whatnot? */
7969 1121052 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
7970 : {
7971 17246 : outer_type = TREE_TYPE (exp);
7972 17246 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
7973 17246 : exp = res_ops[0];
7974 : }
7975 :
7976 : /* Recognize and save a masking operation. Combine it with an
7977 : incoming mask. */
7978 1121052 : if (gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops)
7979 1121052 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
7980 : {
7981 34257 : loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp));
7982 34257 : exp = res_ops[0];
7983 34257 : and_mask = wi::to_wide (res_ops[1]);
7984 34257 : unsigned prec_in = pand_mask->get_precision ();
7985 34257 : if (prec_in)
7986 : {
7987 0 : unsigned prec_op = and_mask.get_precision ();
7988 0 : if (prec_in >= prec_op)
7989 : {
7990 0 : if (prec_in > prec_op)
7991 0 : and_mask = wide_int::from (and_mask, prec_in, UNSIGNED);
7992 0 : and_mask &= *pand_mask;
7993 : }
7994 : else
7995 0 : and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED);
7996 : }
7997 : }
7998 : else
7999 1086795 : and_mask = *pand_mask;
8000 :
8001 : /* Turn (a ^ b) [!]= 0 into a [!]= b. */
8002 1121052 : if (pxorp && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops))
8003 : {
8004 : /* No location recorded for this one, it's entirely subsumed by the
8005 : compare. */
8006 11150 : if (*pxorp)
8007 : {
8008 5547 : exp = res_ops[1];
8009 5547 : gcc_checking_assert (!pxor_cmp_op && !pxor_and_mask);
8010 5547 : if (outer_type && TREE_CODE (exp) == INTEGER_CST)
8011 2 : exp = fold_convert (outer_type, exp);
8012 : }
8013 5603 : else if (!pxor_cmp_op)
8014 : /* Not much we can do when xor appears in the right-hand compare
8015 : operand. */
8016 : return NULL_TREE;
8017 5549 : else if (integer_zerop (*pxor_cmp_op))
8018 : {
8019 5547 : xorp = true;
8020 5547 : exp = res_ops[0];
8021 5547 : xor_cmp_op = *pexp;
8022 5547 : xor_and_mask = *pand_mask;
8023 : }
8024 : }
8025 :
8026 : /* Another chance to drop conversions. */
8027 1120998 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
8028 : {
8029 1400 : outer_type = TREE_TYPE (exp);
8030 1400 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
8031 1400 : exp = res_ops[0];
8032 : }
8033 :
8034 : /* Take note of shifts. */
8035 1120998 : if (gimple_binop_def_p (RSHIFT_EXPR, exp, res_ops)
8036 1120998 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
8037 : {
8038 622 : loc[2] = gimple_location (SSA_NAME_DEF_STMT (exp));
8039 622 : exp = res_ops[0];
8040 622 : if (!tree_fits_shwi_p (res_ops[1]))
8041 : return NULL_TREE;
8042 622 : shiftrt = tree_to_shwi (res_ops[1]);
8043 622 : if (shiftrt <= 0)
8044 : return NULL_TREE;
8045 : }
8046 :
8047 : /* Yet another chance to drop conversions. This one is allowed to
8048 : match a converting load, subsuming the load identification block
8049 : below. */
8050 1120998 : if (!outer_type && gimple_convert_def_p (exp, res_ops, &load))
8051 : {
8052 20 : outer_type = TREE_TYPE (exp);
8053 20 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
8054 20 : if (load)
8055 0 : loc[3] = gimple_location (load);
8056 20 : exp = res_ops[0];
8057 : /* This looks backwards, but we're going back the def chain, so if we
8058 : find the conversion here, after finding a shift, that's because the
8059 : convert appears before the shift, and we should thus adjust the bit
8060 : pos and size because of the shift after adjusting it due to type
8061 : conversion. */
8062 20 : convert_before_shift = true;
8063 : }
8064 :
8065 : /* Identify the load, if there is one. */
8066 1120998 : if (!load && TREE_CODE (exp) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (exp))
8067 : {
8068 626870 : gimple *def = SSA_NAME_DEF_STMT (exp);
8069 626870 : if (gimple_assign_load_p (def))
8070 : {
8071 403017 : loc[3] = gimple_location (def);
8072 403017 : load = def;
8073 403017 : exp = gimple_assign_rhs1 (def);
8074 : }
8075 : }
8076 :
8077 : /* Identify the relevant bits. */
8078 1120998 : poly_int64 poly_bitsize, poly_bitpos;
8079 1120998 : int unsignedp, reversep = *preversep, volatilep = *pvolatilep;
8080 1120998 : inner = get_inner_reference (exp, &poly_bitsize, &poly_bitpos, &offset,
8081 : &mode, &unsignedp, &reversep, &volatilep);
8082 :
8083 1120998 : HOST_WIDE_INT bs, bp;
8084 1120998 : if (!poly_bitsize.is_constant (&bs)
8085 1120998 : || !poly_bitpos.is_constant (&bp)
8086 1120998 : || bs <= shiftrt
8087 1120998 : || offset != 0
8088 1119761 : || TREE_CODE (inner) == PLACEHOLDER_EXPR
8089 : /* Reject out-of-bound accesses (PR79731, PR118514). */
8090 1169913 : || !access_in_bounds_of_type_p (TREE_TYPE (inner), bs, bp)
8091 1119727 : || (INTEGRAL_TYPE_P (TREE_TYPE (inner))
8092 760481 : && !type_has_mode_precision_p (TREE_TYPE (inner))))
8093 : return NULL_TREE;
8094 :
8095 : /* Adjust shifts... */
8096 1070812 : if (convert_before_shift
8097 1070812 : && outer_type && bs > TYPE_PRECISION (outer_type))
8098 : {
8099 2 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8100 2 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8101 0 : bp += excess;
8102 : bs -= excess;
8103 : }
8104 :
8105 1070812 : if (shiftrt)
8106 : {
8107 : /* Punt if we're shifting by more than the loaded bitfield (after
8108 : adjustment), or if there's a shift after a change of signedness, punt.
8109 : When comparing this field with a constant, we'll check that the
8110 : constant is a proper sign- or zero-extension (depending on signedness)
8111 : of a value that would fit in the selected portion of the bitfield. A
8112 : shift after a change of signedness would make the extension
8113 : non-uniform, and we can't deal with that (yet ???). See
8114 : gcc.dg/field-merge-22.c for a test that would go wrong. */
8115 622 : if (bs <= shiftrt
8116 622 : || (convert_before_shift
8117 20 : && outer_type && unsignedp != TYPE_UNSIGNED (outer_type)))
8118 : return NULL_TREE;
8119 603 : if (!reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8120 603 : bp += shiftrt;
8121 603 : bs -= shiftrt;
8122 : }
8123 :
8124 : /* ... and bit position. */
8125 1070793 : if (!convert_before_shift
8126 1070793 : && outer_type && bs > TYPE_PRECISION (outer_type))
8127 : {
8128 8014 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8129 8014 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8130 0 : bp += excess;
8131 : bs -= excess;
8132 : }
8133 :
8134 : /* If the number of bits in the reference is the same as the bitsize of
8135 : the outer type, then the outer type gives the signedness. Otherwise
8136 : (in case of a small bitfield) the signedness is unchanged. */
8137 1070793 : if (outer_type && bs == TYPE_PRECISION (outer_type))
8138 13720 : unsignedp = TYPE_UNSIGNED (outer_type);
8139 :
8140 : /* Make the mask the expected width. */
8141 1070793 : if (and_mask.get_precision () != 0)
8142 : {
8143 : /* If the AND_MASK encompasses bits that would be extensions of
8144 : the sign bit, set SIGNBIT to 1 if any such bit is set, or -1 if
8145 : they are all clear. */
8146 39661 : if (!unsignedp
8147 39661 : && and_mask.get_precision () > bs)
8148 : {
8149 30 : if ((and_mask & wi::mask (bs, true, and_mask.get_precision ())) != 0)
8150 : signbit = 1;
8151 : else
8152 8 : signbit = -1;
8153 : }
8154 39661 : and_mask = wide_int::from (and_mask, bs, UNSIGNED);
8155 : }
8156 :
8157 1070793 : *pexp = exp;
8158 1070793 : *pload = load;
8159 1070793 : *pbitsize = bs;
8160 1070793 : *pbitpos = bp;
8161 1070793 : *punsignedp = unsignedp;
8162 1070793 : *preversep = reversep;
8163 1070793 : *pvolatilep = volatilep;
8164 1070793 : *psignbit = signbit;
8165 1070793 : *pand_mask = and_mask;
8166 1070793 : if (xorp)
8167 : {
8168 5547 : *pxorp = xorp;
8169 5547 : *pxor_cmp_op = xor_cmp_op;
8170 5547 : *pxor_and_mask = xor_and_mask;
8171 : }
8172 :
8173 : return inner;
8174 1191755 : }
8175 :
8176 : /* Return the one bitpos within bit extents L or R that is at an
8177 : ALIGN-bit alignment boundary, or -1 if there is more than one such
8178 : boundary, if there isn't any, or if there is any such boundary
8179 : between the extents. L and R are given by bitpos and bitsize. If
8180 : it doesn't return -1, there are two consecutive ALIGN-bit words
8181 : that contain both extents, and at least one of the extents
8182 : straddles across the returned alignment boundary. */
8183 :
8184 : static inline HOST_WIDE_INT
8185 49785 : compute_split_boundary_from_align (HOST_WIDE_INT align,
8186 : HOST_WIDE_INT l_bitpos,
8187 : HOST_WIDE_INT l_bitsize,
8188 : HOST_WIDE_INT r_bitpos,
8189 : HOST_WIDE_INT r_bitsize)
8190 : {
8191 49785 : HOST_WIDE_INT amask = ~(align - 1);
8192 :
8193 49785 : HOST_WIDE_INT first_bit = MIN (l_bitpos, r_bitpos);
8194 49785 : HOST_WIDE_INT end_bit = MAX (l_bitpos + l_bitsize, r_bitpos + r_bitsize);
8195 :
8196 49785 : HOST_WIDE_INT boundary = (end_bit - 1) & amask;
8197 :
8198 : /* Make sure we're crossing no more than one alignment boundary.
8199 :
8200 : ??? We don't have logic to recombine loads of two adjacent
8201 : fields that each crosses a different alignment boundary, so
8202 : as to load the middle word only once, if other words can't be
8203 : otherwise recombined. */
8204 49785 : if (boundary - first_bit > align)
8205 : return -1;
8206 :
8207 19167 : HOST_WIDE_INT l_start_word = l_bitpos & amask;
8208 19167 : HOST_WIDE_INT l_end_word = (l_bitpos + l_bitsize - 1) & amask;
8209 :
8210 19167 : HOST_WIDE_INT r_start_word = r_bitpos & amask;
8211 19167 : HOST_WIDE_INT r_end_word = (r_bitpos + r_bitsize - 1) & amask;
8212 :
8213 : /* If neither field straddles across an alignment boundary, it's no
8214 : use to even try to merge them. */
8215 19167 : if (l_start_word == l_end_word && r_start_word == r_end_word)
8216 18860 : return -1;
8217 :
8218 : return boundary;
8219 : }
8220 :
8221 : /* Make a bit_field_ref. If POINT is NULL, return the BIT_FIELD_REF.
8222 : Otherwise, build and insert a load stmt before POINT, and return
8223 : the SSA_NAME. ??? Rewrite LOAD in terms of the bitfield? */
8224 :
8225 : static tree
8226 4723 : make_bit_field_load (location_t loc, tree inner, tree orig_inner, tree type,
8227 : HOST_WIDE_INT bitsize, poly_int64 bitpos,
8228 : bool unsignedp, bool reversep, gimple *point)
8229 : {
8230 4723 : if (point && loc == UNKNOWN_LOCATION)
8231 22 : loc = gimple_location (point);
8232 :
8233 4723 : tree ref = make_bit_field_ref (loc, unshare_expr (inner),
8234 : unshare_expr (orig_inner),
8235 : type, bitsize, bitpos,
8236 : unsignedp, reversep);
8237 4723 : if (!point)
8238 : return ref;
8239 :
8240 : /* If we're remaking the same load, reuse the SSA NAME it is already loaded
8241 : into. */
8242 4574 : if (gimple_assign_load_p (point)
8243 4574 : && operand_equal_p (ref, gimple_assign_rhs1 (point)))
8244 : {
8245 1676 : gcc_checking_assert (TREE_CODE (gimple_assign_lhs (point)) == SSA_NAME);
8246 : return gimple_assign_lhs (point);
8247 : }
8248 :
8249 2898 : gimple_seq stmts = NULL;
8250 2898 : tree ret = force_gimple_operand (ref, &stmts, true, NULL_TREE);
8251 :
8252 : /* We know the vuse is supposed to end up being the same as that at the
8253 : original load at the insertion point, but if we don't set it, it will be a
8254 : generic placeholder that only the global SSA update at the end of the pass
8255 : would make equal, too late for us to use in further combinations. So go
8256 : ahead and copy the vuse. */
8257 :
8258 2898 : tree reaching_vuse = gimple_vuse (point);
8259 2898 : for (gimple_stmt_iterator i = gsi_start (stmts);
8260 6394 : !gsi_end_p (i); gsi_next (&i))
8261 : {
8262 3496 : gimple *new_stmt = gsi_stmt (i);
8263 6992 : if (gimple_has_mem_ops (new_stmt))
8264 3496 : gimple_set_vuse (new_stmt, reaching_vuse);
8265 : }
8266 :
8267 2898 : gimple_stmt_iterator gsi = gsi_for_stmt (point);
8268 2898 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
8269 2898 : return ret;
8270 : }
8271 :
8272 : /* Initialize ln_arg[0] and ln_arg[1] to a pair of newly-created (at
8273 : LOC) loads from INNER (from ORIG_INNER), of modes MODE and MODE2,
8274 : respectively, starting at BIT_POS, using reversed endianness if
8275 : REVERSEP. Also initialize BITPOS (the starting position of each
8276 : part into INNER), BITSIZ (the bit count starting at BITPOS),
8277 : TOSHIFT[1] (the amount by which the part and its mask are to be
8278 : shifted right to bring its least-significant bit to bit zero) and
8279 : SHIFTED (the amount by which the part, by separate loading, has
8280 : already been shifted right, but that the mask needs shifting to
8281 : match). */
8282 :
8283 : static inline void
8284 307 : build_split_load (tree /* out */ ln_arg[2],
8285 : HOST_WIDE_INT /* out */ bitpos[2],
8286 : HOST_WIDE_INT /* out */ bitsiz[2],
8287 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8288 : HOST_WIDE_INT /* out */ shifted[2],
8289 : location_t loc, tree inner, tree orig_inner,
8290 : scalar_int_mode mode, scalar_int_mode mode2,
8291 : HOST_WIDE_INT bit_pos, bool reversep,
8292 : gimple *point[2])
8293 : {
8294 307 : scalar_int_mode modes[2] = { mode, mode2 };
8295 307 : bitsiz[0] = GET_MODE_BITSIZE (mode);
8296 307 : bitsiz[1] = GET_MODE_BITSIZE (mode2);
8297 :
8298 921 : for (int i = 0; i < 2; i++)
8299 : {
8300 614 : tree type = lang_hooks.types.type_for_mode (modes[i], 1);
8301 614 : if (!type)
8302 : {
8303 0 : type = build_nonstandard_integer_type (bitsiz[0], 1);
8304 0 : gcc_assert (type);
8305 : }
8306 614 : bitpos[i] = bit_pos;
8307 1228 : ln_arg[i] = make_bit_field_load (loc, inner, orig_inner,
8308 614 : type, bitsiz[i],
8309 614 : bit_pos, 1, reversep, point[i]);
8310 614 : bit_pos += bitsiz[i];
8311 : }
8312 :
8313 307 : toshift[1] = toshift[0];
8314 307 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8315 : {
8316 3 : shifted[0] = bitsiz[1];
8317 3 : shifted[1] = 0;
8318 3 : toshift[0] = 0;
8319 : }
8320 : else
8321 : {
8322 304 : shifted[1] = bitsiz[0];
8323 304 : shifted[0] = 0;
8324 304 : toshift[1] = 0;
8325 : }
8326 307 : }
8327 :
8328 : /* Make arrangements to split at bit BOUNDARY a single loaded word
8329 : (with REVERSEP bit order) LN_ARG[0], to be shifted right by
8330 : TOSHIFT[0] to bring the field of interest to the least-significant
8331 : bit. The expectation is that the same loaded word will be
8332 : propagated from part 0 to part 1, with just different shifting and
8333 : masking to extract both parts. MASK is not expected to do more
8334 : than masking out the bits that belong to the other part. See
8335 : build_split_load for more information on the other fields. */
8336 :
8337 : static inline void
8338 51 : reuse_split_load (tree /* in[0] out[1] */ ln_arg[2],
8339 : HOST_WIDE_INT /* in[0] out[1] */ bitpos[2],
8340 : HOST_WIDE_INT /* in[0] out[1] */ bitsiz[2],
8341 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8342 : HOST_WIDE_INT /* out */ shifted[2],
8343 : wide_int /* out */ mask[2],
8344 : HOST_WIDE_INT boundary, bool reversep)
8345 : {
8346 51 : unsigned prec = TYPE_PRECISION (TREE_TYPE (ln_arg[0]));
8347 :
8348 51 : ln_arg[1] = ln_arg[0];
8349 51 : bitpos[1] = bitpos[0];
8350 51 : bitsiz[1] = bitsiz[0];
8351 51 : shifted[1] = shifted[0] = 0;
8352 :
8353 51 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8354 : {
8355 3 : toshift[1] = toshift[0];
8356 3 : toshift[0] = bitpos[0] + bitsiz[0] - boundary;
8357 3 : mask[0] = wi::mask (toshift[0], true, prec);
8358 3 : mask[1] = wi::mask (toshift[0], false, prec);
8359 : }
8360 : else
8361 : {
8362 48 : toshift[1] = boundary - bitpos[1];
8363 48 : mask[1] = wi::mask (toshift[1], true, prec);
8364 48 : mask[0] = wi::mask (toshift[1], false, prec);
8365 : }
8366 51 : }
8367 :
8368 : /* Find ways of folding logical expressions of LHS and RHS:
8369 :
8370 : Try to merge two comparisons to nearby fields.
8371 :
8372 : For example, if we have p->a == 2 && p->b == 4 and we can load both A and B
8373 : at once, we can do this with a comparison against the object ANDed with the
8374 : a mask.
8375 :
8376 : If we have p->a == q->a && p->b == q->b, we may be able to use bit masking
8377 : operations to do this with one comparison, loading both fields from P at
8378 : once, and likewise from Q.
8379 :
8380 : Herein, loading at once means loading from within the same alignment
8381 : boundary for the enclosing object. If (packed) fields cross such alignment
8382 : boundaries, we may still recombine the compares, so that loads do not cross
8383 : the boundaries.
8384 :
8385 : CODE is the logical operation being done. It can be TRUTH_ANDIF_EXPR,
8386 : TRUTH_AND_EXPR, TRUTH_ORIF_EXPR, or TRUTH_OR_EXPR.
8387 :
8388 : TRUTH_TYPE is the type of the logical operand.
8389 :
8390 : LHS is denoted as LL_ARG LCODE LR_ARG.
8391 :
8392 : RHS is denoted as RL_ARG RCODE RR_ARG.
8393 :
8394 : LHS is assumed to dominate RHS.
8395 :
8396 : Combined loads are inserted next to preexisting loads, once we determine
8397 : that the combination is viable, and the combined condition references new
8398 : SSA_NAMEs that hold the loaded values. Since the original loads are
8399 : verified to have the same gimple_vuse, the insertion point doesn't matter
8400 : for correctness. ??? The loads may be a lot earlier than the compares, and
8401 : it's conceivable that one or two loads for RHS appear before those for LHS.
8402 : It could be advantageous to try to place the loads optimally, taking
8403 : advantage of knowing whether RHS is accessed before LHS, or that both are
8404 : accessed before both compares, but we don't do that (yet?).
8405 :
8406 : SEPARATEP should be NULL if the combined condition must be returned as a
8407 : single expression, even if it is a compound condition. This must only be
8408 : done if LHS and RHS are adjacent, without intervening conditions, and the
8409 : combined condition is to replace RHS, while LHS is dropped altogether.
8410 :
8411 : Otherwise, SEPARATEP must be a non-NULL pointer to a NULL_TREE, that may be
8412 : replaced by a part of the compound condition that could replace RHS, while
8413 : the returned expression replaces LHS. This works whether or not LHS and RHS
8414 : are adjacent, as long as there aren't VDEFs or other side effects between
8415 : them.
8416 :
8417 : If the "words" accessed by RHS are already accessed by LHS, this won't
8418 : matter, but if RHS accesses "words" that LHS doesn't, then *SEPARATEP will
8419 : be set to the compares that should take RHS's place. By "words" we mean
8420 : contiguous bits that do not cross a an TYPE_ALIGN boundary of the accessed
8421 : object's type.
8422 :
8423 : We return the simplified tree or 0 if no optimization is possible. */
8424 :
8425 : tree
8426 439829 : fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type,
8427 : location_t lloc, enum tree_code lcode,
8428 : tree ll_arg, tree lr_arg,
8429 : location_t rloc, enum tree_code rcode,
8430 : tree rl_arg, tree rr_arg,
8431 : tree *separatep)
8432 : {
8433 : /* If this is the "or" of two comparisons, we can do something if
8434 : the comparisons are NE_EXPR. If this is the "and", we can do something
8435 : if the comparisons are EQ_EXPR. I.e.,
8436 : (a->b == 2 && a->c == 4) can become (a->new == NEW).
8437 :
8438 : WANTED_CODE is this operation code. For single bit fields, we can
8439 : convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
8440 : comparison for one-bit fields. */
8441 :
8442 439829 : enum tree_code orig_code = code;
8443 439829 : enum tree_code wanted_code;
8444 439829 : tree ll_inner, lr_inner, rl_inner, rr_inner;
8445 439829 : gimple *ll_load, *lr_load, *rl_load, *rr_load;
8446 439829 : HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
8447 439829 : HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
8448 439829 : HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
8449 439829 : HOST_WIDE_INT lnbitsize, lnbitpos, lnprec;
8450 439829 : HOST_WIDE_INT rnbitsize, rnbitpos, rnprec;
8451 439829 : bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
8452 439829 : bool ll_reversep, lr_reversep, rl_reversep, rr_reversep;
8453 439829 : int ll_signbit, lr_signbit, rl_signbit, rr_signbit;
8454 439829 : scalar_int_mode lnmode, lnmode2, rnmode;
8455 439829 : wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
8456 439829 : wide_int l_const, r_const;
8457 439829 : tree lntype, rntype, result;
8458 439829 : HOST_WIDE_INT first_bit, end_bit;
8459 439829 : bool volatilep;
8460 439829 : bool l_split_load;
8461 :
8462 : /* These are indexed by: conv, mask, shft, load. */
8463 439829 : location_t ll_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8464 439829 : location_t lr_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8465 439829 : location_t rl_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8466 439829 : location_t rr_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8467 :
8468 439829 : gcc_checking_assert (!separatep || !*separatep);
8469 :
8470 : /* Start by getting the comparison codes. Fail if anything is volatile.
8471 : If one operand is a BIT_AND_EXPR with the constant one, treat it as if
8472 : it were surrounded with a NE_EXPR. */
8473 :
8474 439829 : if (TREE_CODE_CLASS (lcode) != tcc_comparison
8475 439829 : || TREE_CODE_CLASS (rcode) != tcc_comparison)
8476 : return 0;
8477 :
8478 : /* We don't normally find TRUTH_*IF_EXPR in gimple, but these codes may be
8479 : given by our caller to denote conditions from different blocks. */
8480 439829 : switch (code)
8481 : {
8482 : case TRUTH_AND_EXPR:
8483 : case TRUTH_ANDIF_EXPR:
8484 : code = TRUTH_AND_EXPR;
8485 : break;
8486 :
8487 0 : case TRUTH_OR_EXPR:
8488 0 : case TRUTH_ORIF_EXPR:
8489 0 : code = TRUTH_OR_EXPR;
8490 0 : break;
8491 :
8492 : default:
8493 : return 0;
8494 : }
8495 :
8496 : /* Prepare to turn compares of signed quantities with zero into sign-bit
8497 : tests. We need not worry about *_reversep here for these compare
8498 : rewrites: loads will have already been reversed before compares. Save the
8499 : precision, because [lr]l_arg may change and we won't be able to tell how
8500 : wide it was originally. */
8501 439829 : unsigned lsignbit = 0, rsignbit = 0;
8502 439829 : if ((lcode == LT_EXPR || lcode == GE_EXPR)
8503 15228 : && integer_zerop (lr_arg)
8504 3746 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8505 443575 : && !TYPE_UNSIGNED (TREE_TYPE (ll_arg)))
8506 : {
8507 3746 : lsignbit = TYPE_PRECISION (TREE_TYPE (ll_arg));
8508 3746 : lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8509 : }
8510 : /* Turn compares of unsigned quantities with powers of two into
8511 : equality tests of masks. */
8512 436083 : else if ((lcode == LT_EXPR || lcode == GE_EXPR)
8513 11482 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8514 10737 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8515 8441 : && TREE_CODE (lr_arg) == INTEGER_CST
8516 436083 : && wi::popcount (wi::to_wide (lr_arg)) == 1)
8517 : {
8518 0 : ll_and_mask = ~(wi::to_wide (lr_arg) - 1);
8519 0 : lcode = (lcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8520 0 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8521 : }
8522 : /* Turn compares of unsigned quantities with powers of two minus one
8523 : into equality tests of masks. */
8524 872166 : else if ((lcode == LE_EXPR || lcode == GT_EXPR)
8525 35576 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8526 35353 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8527 28863 : && TREE_CODE (lr_arg) == INTEGER_CST
8528 497352 : && wi::popcount (wi::to_wide (lr_arg) + 1) == 1)
8529 : {
8530 4192 : ll_and_mask = ~wi::to_wide (lr_arg);
8531 4192 : lcode = (lcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8532 4192 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8533 : }
8534 : /* Likewise for the second compare. */
8535 439829 : if ((rcode == LT_EXPR || rcode == GE_EXPR)
8536 16717 : && integer_zerop (rr_arg)
8537 2732 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8538 442561 : && !TYPE_UNSIGNED (TREE_TYPE (rl_arg)))
8539 : {
8540 2732 : rsignbit = TYPE_PRECISION (TREE_TYPE (rl_arg));
8541 2732 : rcode = (rcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8542 : }
8543 437097 : else if ((rcode == LT_EXPR || rcode == GE_EXPR)
8544 13985 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8545 12869 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8546 4800 : && TREE_CODE (rr_arg) == INTEGER_CST
8547 437097 : && wi::popcount (wi::to_wide (rr_arg)) == 1)
8548 : {
8549 0 : rl_and_mask = ~(wi::to_wide (rr_arg) - 1);
8550 0 : rcode = (rcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8551 0 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8552 : }
8553 874194 : else if ((rcode == LE_EXPR || rcode == GT_EXPR)
8554 43123 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8555 42876 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8556 33517 : && TREE_CODE (rr_arg) == INTEGER_CST
8557 503768 : && wi::popcount (wi::to_wide (rr_arg) + 1) == 1)
8558 : {
8559 3233 : rl_and_mask = ~wi::to_wide (rr_arg);
8560 3233 : rcode = (rcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8561 3233 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8562 : }
8563 :
8564 : /* See if the comparisons can be merged. Then get all the parameters for
8565 : each side. */
8566 :
8567 439829 : if ((lcode != EQ_EXPR && lcode != NE_EXPR)
8568 395863 : || (rcode != EQ_EXPR && rcode != NE_EXPR))
8569 : return 0;
8570 :
8571 375450 : ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
8572 375450 : volatilep = 0;
8573 375450 : bool l_xor = false, r_xor = false;
8574 375450 : ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos,
8575 : &ll_unsignedp, &ll_reversep, &volatilep,
8576 : &ll_and_mask, &ll_signbit,
8577 : &l_xor, &lr_arg, &lr_and_mask,
8578 : &ll_load, ll_loc);
8579 375450 : if (!ll_inner)
8580 : return 0;
8581 282263 : lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos,
8582 : &lr_unsignedp, &lr_reversep, &volatilep,
8583 : &lr_and_mask, &lr_signbit, &l_xor, 0, 0,
8584 : &lr_load, lr_loc);
8585 282263 : if (!lr_inner)
8586 : return 0;
8587 277003 : rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos,
8588 : &rl_unsignedp, &rl_reversep, &volatilep,
8589 : &rl_and_mask, &rl_signbit,
8590 : &r_xor, &rr_arg, &rr_and_mask,
8591 : &rl_load, rl_loc);
8592 277003 : if (!rl_inner)
8593 : return 0;
8594 257039 : rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos,
8595 : &rr_unsignedp, &rr_reversep, &volatilep,
8596 : &rr_and_mask, &rr_signbit, &r_xor, 0, 0,
8597 : &rr_load, rr_loc);
8598 257039 : if (!rr_inner)
8599 : return 0;
8600 :
8601 : /* It must be true that the inner operation on the lhs of each
8602 : comparison must be the same if we are to be able to do anything.
8603 : Then see if we have constants. If not, the same must be true for
8604 : the rhs's. If one is a load and the other isn't, we have to be
8605 : conservative and avoid the optimization, otherwise we could get
8606 : SRAed fields wrong. */
8607 254488 : if (volatilep)
8608 : return 0;
8609 :
8610 254479 : if (ll_reversep != rl_reversep
8611 254479 : || ! operand_equal_p (ll_inner, rl_inner, 0))
8612 : {
8613 : /* Try swapping the operands. */
8614 195003 : if (ll_reversep != rr_reversep || rsignbit
8615 389242 : || !operand_equal_p (ll_inner, rr_inner, 0))
8616 : return 0;
8617 :
8618 1638 : rcode = swap_tree_comparison (rcode);
8619 1638 : std::swap (rl_arg, rr_arg);
8620 1638 : std::swap (rl_inner, rr_inner);
8621 1638 : std::swap (rl_bitsize, rr_bitsize);
8622 1638 : std::swap (rl_bitpos, rr_bitpos);
8623 1638 : std::swap (rl_unsignedp, rr_unsignedp);
8624 1638 : std::swap (rl_reversep, rr_reversep);
8625 1638 : std::swap (rl_and_mask, rr_and_mask);
8626 1638 : std::swap (rl_signbit, rr_signbit);
8627 1638 : std::swap (rl_load, rr_load);
8628 1638 : std::swap (rl_loc, rr_loc);
8629 : }
8630 :
8631 119795 : if ((ll_load && rl_load)
8632 237359 : ? gimple_vuse (ll_load) != gimple_vuse (rl_load)
8633 2231 : : (!ll_load != !rl_load))
8634 : return 0;
8635 :
8636 : /* ??? Can we do anything with these? */
8637 60037 : if (lr_signbit > 0 || rr_signbit > 0)
8638 : return 0;
8639 :
8640 : /* If the mask encompassed extensions of the sign bit before
8641 : clipping, try to include the sign bit in the test. If we're not
8642 : comparing with zero, don't even try to deal with it (for now?).
8643 : If we've already committed to a sign test, the extended (before
8644 : clipping) mask could already be messing with it. */
8645 60037 : if (ll_signbit > 0)
8646 : {
8647 4 : if (!integer_zerop (lr_arg) || lsignbit)
8648 0 : return 0;
8649 4 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8650 4 : if (!ll_and_mask.get_precision ())
8651 0 : ll_and_mask = sign;
8652 : else
8653 4 : ll_and_mask |= sign;
8654 4 : }
8655 :
8656 60037 : if (rl_signbit > 0)
8657 : {
8658 4 : if (!integer_zerop (rr_arg) || rsignbit)
8659 1 : return 0;
8660 3 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8661 3 : if (!rl_and_mask.get_precision ())
8662 0 : rl_and_mask = sign;
8663 : else
8664 3 : rl_and_mask |= sign;
8665 3 : }
8666 :
8667 60036 : if (TREE_CODE (lr_arg) == INTEGER_CST
8668 46934 : && TREE_CODE (rr_arg) == INTEGER_CST)
8669 : {
8670 46309 : l_const = wi::to_wide (lr_arg);
8671 : /* We don't expect masks on constants, but if there are any, apply
8672 : them now. */
8673 46309 : if (lr_and_mask.get_precision ())
8674 4 : l_const &= wide_int::from (lr_and_mask,
8675 2 : l_const.get_precision (), UNSIGNED);
8676 46309 : r_const = wi::to_wide (rr_arg);
8677 46309 : if (rr_and_mask.get_precision ())
8678 0 : r_const &= wide_int::from (rr_and_mask,
8679 0 : r_const.get_precision (), UNSIGNED);
8680 46309 : lr_reversep = ll_reversep;
8681 : }
8682 13727 : else if (lr_reversep != rr_reversep
8683 13719 : || ! operand_equal_p (lr_inner, rr_inner, 0)
8684 23948 : || ((lr_load && rr_load)
8685 30483 : ? gimple_vuse (lr_load) != gimple_vuse (rr_load)
8686 60 : : (!lr_load != !rr_load)))
8687 : return 0;
8688 :
8689 : /* If we found sign tests, finish turning them into bit tests. */
8690 :
8691 56227 : if (lsignbit)
8692 : {
8693 66 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8694 : /* If ll_arg is zero-extended and we're testing the sign bit, we know
8695 : what the result should be. Shifting the sign bit out of sign will get
8696 : us to mask the entire field out, yielding zero, i.e., the sign bit of
8697 : the zero-extended value. We know the masked value is being compared
8698 : with zero, so the compare will get us the result we're looking
8699 : for: TRUE if EQ_EXPR, FALSE if NE_EXPR. */
8700 66 : if (lsignbit > ll_bitsize && ll_unsignedp)
8701 1 : sign <<= 1;
8702 66 : if (!ll_and_mask.get_precision ())
8703 65 : ll_and_mask = sign;
8704 : else
8705 1 : ll_and_mask &= sign;
8706 66 : if (l_xor)
8707 : {
8708 3 : if (ll_bitsize != lr_bitsize)
8709 1 : return 0;
8710 2 : if (!lr_and_mask.get_precision ())
8711 2 : lr_and_mask = sign;
8712 : else
8713 0 : lr_and_mask &= sign;
8714 2 : if (l_const.get_precision ())
8715 0 : l_const &= wide_int::from (lr_and_mask,
8716 0 : l_const.get_precision (), UNSIGNED);
8717 : }
8718 66 : }
8719 :
8720 56226 : if (rsignbit)
8721 : {
8722 182 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8723 182 : if (rsignbit > rl_bitsize && rl_unsignedp)
8724 0 : sign <<= 1;
8725 182 : if (!rl_and_mask.get_precision ())
8726 182 : rl_and_mask = sign;
8727 : else
8728 0 : rl_and_mask &= sign;
8729 182 : if (r_xor)
8730 : {
8731 17 : if (rl_bitsize != rr_bitsize)
8732 0 : return 0;
8733 17 : if (!rr_and_mask.get_precision ())
8734 17 : rr_and_mask = sign;
8735 : else
8736 0 : rr_and_mask &= sign;
8737 17 : if (r_const.get_precision ())
8738 24 : r_const &= wide_int::from (rr_and_mask,
8739 12 : r_const.get_precision (), UNSIGNED);
8740 : }
8741 182 : }
8742 :
8743 : /* If either comparison code is not correct for our logical operation,
8744 : fail. However, we can convert a one-bit comparison against zero into
8745 : the opposite comparison against that bit being set in the field. */
8746 :
8747 56226 : wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
8748 56226 : if (lcode != wanted_code)
8749 : {
8750 5042 : if (l_const.get_precision ()
8751 4864 : && l_const == 0
8752 1661 : && ll_and_mask.get_precision ()
8753 5430 : && wi::popcount (ll_and_mask) == 1)
8754 : {
8755 : /* Make the left operand unsigned, since we are only interested
8756 : in the value of one bit. Otherwise we are doing the wrong
8757 : thing below. */
8758 228 : ll_unsignedp = 1;
8759 228 : l_const = ll_and_mask;
8760 : }
8761 : else
8762 4814 : return 0;
8763 : }
8764 :
8765 : /* This is analogous to the code for l_const above. */
8766 51412 : if (rcode != wanted_code)
8767 : {
8768 996 : if (r_const.get_precision ()
8769 996 : && r_const == 0
8770 949 : && rl_and_mask.get_precision ()
8771 1875 : && wi::popcount (rl_and_mask) == 1)
8772 : {
8773 534 : rl_unsignedp = 1;
8774 534 : r_const = rl_and_mask;
8775 : }
8776 : else
8777 462 : return 0;
8778 : }
8779 :
8780 : /* This will be bumped to 2 if any of the field pairs crosses an
8781 : alignment boundary, so the merged compare has to be done in two
8782 : parts. */
8783 50950 : int parts = 1;
8784 : /* Set to true if the second combined compare should come first,
8785 : e.g., because the second original compare accesses a word that
8786 : the first one doesn't, and the combined compares access those in
8787 : cmp[0]. */
8788 50950 : bool first1 = false;
8789 : /* Set to true if the first original compare is not the one being
8790 : split. */
8791 50950 : bool maybe_separate = false;
8792 :
8793 : /* The following 2-dimensional arrays use the first index to
8794 : identify left(0)- vs right(1)-hand compare operands, and the
8795 : second one to identify merged compare parts. */
8796 : /* The memory loads or constants to be compared. */
8797 50950 : tree ld_arg[2][2];
8798 : /* The first bit of the corresponding inner object that the
8799 : corresponding LD_ARG covers. */
8800 50950 : HOST_WIDE_INT bitpos[2][2];
8801 : /* The bit count starting at BITPOS that the corresponding LD_ARG
8802 : covers. */
8803 50950 : HOST_WIDE_INT bitsiz[2][2];
8804 : /* The number of bits by which LD_ARG has already been shifted
8805 : right, WRT mask. */
8806 50950 : HOST_WIDE_INT shifted[2][2];
8807 : /* The number of bits by which both LD_ARG and MASK need shifting to
8808 : bring its least-significant bit to bit zero. */
8809 50950 : HOST_WIDE_INT toshift[2][2];
8810 : /* An additional mask to be applied to LD_ARG, to remove any bits
8811 : that may have been loaded for use in another compare, but that
8812 : don't belong in the corresponding compare. */
8813 611400 : wide_int xmask[2][2] = {};
8814 :
8815 : /* The combined compare or compares. */
8816 50950 : tree cmp[2];
8817 :
8818 : /* Consider we're comparing two non-contiguous fields of packed
8819 : structs, both aligned at 32-bit boundaries:
8820 :
8821 : ll_arg: an 8-bit field at offset 0
8822 : lr_arg: a 16-bit field at offset 2
8823 :
8824 : rl_arg: an 8-bit field at offset 1
8825 : rr_arg: a 16-bit field at offset 3
8826 :
8827 : We'll have r_split_load, because rr_arg straddles across an
8828 : alignment boundary.
8829 :
8830 : We'll want to have:
8831 :
8832 : bitpos = { { 0, 0 }, { 0, 32 } }
8833 : bitsiz = { { 32, 32 }, { 32, 8 } }
8834 :
8835 : And, for little-endian:
8836 :
8837 : shifted = { { 0, 0 }, { 0, 32 } }
8838 : toshift = { { 0, 24 }, { 0, 0 } }
8839 :
8840 : Or, for big-endian:
8841 :
8842 : shifted = { { 0, 0 }, { 8, 0 } }
8843 : toshift = { { 8, 0 }, { 0, 0 } }
8844 : */
8845 :
8846 : /* See if we can find a mode that contains both fields being compared on
8847 : the left. If we can't, fail. Otherwise, update all constants and masks
8848 : to be relative to a field of that size. */
8849 50950 : first_bit = MIN (ll_bitpos, rl_bitpos);
8850 50950 : end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
8851 50950 : HOST_WIDE_INT ll_align = TYPE_ALIGN (TREE_TYPE (ll_inner));
8852 50950 : poly_uint64 ll_end_region = 0;
8853 50950 : if (TYPE_SIZE (TREE_TYPE (ll_inner))
8854 50950 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (ll_inner))))
8855 50950 : ll_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (ll_inner)));
8856 50950 : if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region,
8857 50950 : ll_align, BITS_PER_WORD, volatilep, &lnmode))
8858 : l_split_load = false;
8859 : /* ??? If ll and rl share the same load, reuse that?
8860 : See PR 118206 -> gcc.dg/field-merge-18.c */
8861 : else
8862 : {
8863 : /* Consider the possibility of recombining loads if any of the
8864 : fields straddles across an alignment boundary, so that either
8865 : part can be loaded along with the other field. Since we
8866 : limit access modes to BITS_PER_WORD, don't exceed that,
8867 : otherwise on a 32-bit host and a 64-bit-aligned data
8868 : structure, we'll fail the above for a field that straddles
8869 : across two words, and would fail here for not even trying to
8870 : split it at between 32-bit words. */
8871 47651 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
8872 50873 : (MIN (ll_align, BITS_PER_WORD),
8873 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8874 :
8875 47651 : if (boundary < 0
8876 219 : || !get_best_mode (boundary - first_bit, first_bit, 0, ll_end_region,
8877 : ll_align, BITS_PER_WORD, volatilep, &lnmode)
8878 47828 : || !get_best_mode (end_bit - boundary, boundary, 0, ll_end_region,
8879 177 : ll_align, BITS_PER_WORD, volatilep, &lnmode2))
8880 : {
8881 50654 : if (ll_align <= BITS_PER_WORD)
8882 : return 0;
8883 :
8884 : /* As a last resort, try double-word access modes. This
8885 : enables us to deal with misaligned double-word fields
8886 : that straddle across 3 separate words. */
8887 1996 : boundary = compute_split_boundary_from_align
8888 2098 : (MIN (ll_align, 2 * BITS_PER_WORD),
8889 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8890 1996 : if (boundary < 0
8891 0 : || !get_best_mode (boundary - first_bit, first_bit,
8892 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8893 : volatilep, &lnmode)
8894 1996 : || !get_best_mode (end_bit - boundary, boundary,
8895 0 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8896 : volatilep, &lnmode2))
8897 : return 0;
8898 : }
8899 :
8900 : /* If we can't have a single load, but can with two, figure out whether
8901 : the two compares can be separated, i.e., whether the entirety of the
8902 : first original compare is encompassed by the entirety of the first
8903 : combined compare. If the first original compare is past the alignment
8904 : boundary, arrange to compare that range first, by setting first1
8905 : (meaning make cmp[1] first, instead of cmp[0]). */
8906 177 : l_split_load = true;
8907 177 : parts = 2;
8908 177 : if (ll_bitpos >= boundary)
8909 : maybe_separate = first1 = true;
8910 132 : else if (ll_bitpos + ll_bitsize <= boundary)
8911 32 : maybe_separate = true;
8912 : }
8913 :
8914 3476 : lnbitsize = GET_MODE_BITSIZE (lnmode);
8915 3476 : lnbitpos = first_bit & ~ (lnbitsize - 1);
8916 : /* Avoid situations that the code below can't handle. */
8917 3476 : if (lnbitpos < 0)
8918 : return 0;
8919 :
8920 : /* Choose the type for the combined compare. Even if we're splitting loads,
8921 : make it wide enough to hold both. */
8922 3476 : if (l_split_load)
8923 354 : lnbitsize += GET_MODE_BITSIZE (lnmode2);
8924 3476 : lntype = build_nonstandard_integer_type (lnbitsize, 1);
8925 3476 : if (!lntype)
8926 : return NULL_TREE;
8927 3476 : lnprec = TYPE_PRECISION (lntype);
8928 3476 : xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
8929 :
8930 : /* Adjust bit ranges for reverse endianness. */
8931 3476 : if (ll_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8932 : {
8933 6 : xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
8934 6 : xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
8935 : }
8936 :
8937 : /* Adjust masks to match the positions in the combined lntype. */
8938 6952 : wide_int ll_mask, rl_mask, r_mask;
8939 3476 : if (ll_and_mask.get_precision ())
8940 4300 : ll_mask = wi::lshift (wide_int::from (ll_and_mask, lnprec, UNSIGNED),
8941 2150 : xll_bitpos);
8942 : else
8943 1326 : ll_mask = wi::shifted_mask (xll_bitpos, ll_bitsize, false, lnprec);
8944 3476 : if (rl_and_mask.get_precision ())
8945 3958 : rl_mask = wi::lshift (wide_int::from (rl_and_mask, lnprec, UNSIGNED),
8946 1979 : xrl_bitpos);
8947 : else
8948 1497 : rl_mask = wi::shifted_mask (xrl_bitpos, rl_bitsize, false, lnprec);
8949 :
8950 : /* When we set l_const, we also set r_const. */
8951 3476 : gcc_checking_assert (!l_const.get_precision () == !r_const.get_precision ());
8952 :
8953 : /* Adjust right-hand constants in both original comparisons to match width
8954 : and bit position. */
8955 3476 : if (l_const.get_precision ())
8956 : {
8957 : /* Before clipping upper bits of the right-hand operand of the compare,
8958 : check that they're sign or zero extensions, depending on how the
8959 : left-hand operand would be extended. If it is unsigned, or if there's
8960 : a mask that zeroes out extension bits, whether because we've checked
8961 : for upper bits in the mask and found them all clear (ll_signbit < 0),
8962 : or because the sign bit itself is masked out, check that the
8963 : right-hand operand is zero-extended. */
8964 2054 : bool l_non_ext_bits = false;
8965 2054 : if (ll_bitsize < lr_bitsize)
8966 : {
8967 44 : wide_int zext = wi::zext (l_const, ll_bitsize);
8968 88 : if ((ll_unsignedp
8969 32 : || ll_signbit < 0
8970 32 : || (ll_and_mask.get_precision ()
8971 52 : && ((ll_and_mask & wi::mask (ll_bitsize - 1, true, ll_bitsize))
8972 8 : == 0))
8973 164 : ? zext : wi::sext (l_const, ll_bitsize)) == l_const)
8974 44 : l_const = zext;
8975 : else
8976 : l_non_ext_bits = true;
8977 44 : }
8978 : /* We're doing bitwise equality tests, so don't bother with sign
8979 : extensions. */
8980 2054 : l_const = wide_int::from (l_const, lnprec, UNSIGNED);
8981 2054 : if (ll_and_mask.get_precision ())
8982 1152 : l_const &= wide_int::from (ll_and_mask, lnprec, UNSIGNED);
8983 2054 : l_const <<= xll_bitpos;
8984 6162 : if (l_non_ext_bits || (l_const & ~ll_mask) != 0)
8985 : {
8986 0 : warning_at (lloc, OPT_Wtautological_compare,
8987 : "comparison is always %d", wanted_code == NE_EXPR);
8988 :
8989 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
8990 : }
8991 :
8992 : /* Before clipping upper bits of the right-hand operand of the compare,
8993 : check that they're sign or zero extensions, depending on how the
8994 : left-hand operand would be extended. */
8995 2054 : bool r_non_ext_bits = false;
8996 2054 : if (rl_bitsize < rr_bitsize)
8997 : {
8998 10 : wide_int zext = wi::zext (r_const, rl_bitsize);
8999 20 : if ((rl_unsignedp
9000 6 : || rl_signbit < 0
9001 5 : || (rl_and_mask.get_precision ()
9002 18 : && ((rl_and_mask & wi::mask (rl_bitsize - 1, true, rl_bitsize))
9003 8 : == 0))
9004 36 : ? zext : wi::sext (r_const, rl_bitsize)) == r_const)
9005 10 : r_const = zext;
9006 : else
9007 : r_non_ext_bits = true;
9008 10 : }
9009 2054 : r_const = wide_int::from (r_const, lnprec, UNSIGNED);
9010 2054 : if (rl_and_mask.get_precision ())
9011 1031 : r_const &= wide_int::from (rl_and_mask, lnprec, UNSIGNED);
9012 2054 : r_const <<= xrl_bitpos;
9013 6162 : if (r_non_ext_bits || (r_const & ~rl_mask) != 0)
9014 : {
9015 0 : warning_at (rloc, OPT_Wtautological_compare,
9016 : "comparison is always %d", wanted_code == NE_EXPR);
9017 :
9018 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
9019 : }
9020 :
9021 : /* If there is something in common between the masks, those bits of the
9022 : constants must be the same. If not, the combined condition cannot be
9023 : met, and the result is known. Test for this to avoid generating
9024 : incorrect code below. */
9025 2054 : wide_int mask = ll_mask & rl_mask;
9026 2054 : if (mask != 0
9027 2093 : && (l_const & mask) != (r_const & mask))
9028 : {
9029 0 : if (wanted_code == NE_EXPR)
9030 0 : return constant_boolean_node (true, truth_type);
9031 : else
9032 0 : return constant_boolean_node (false, truth_type);
9033 : }
9034 :
9035 : /* The constants are combined so as to line up with the loaded field, so
9036 : tentatively use the same parameters for the second combined
9037 : compare. */
9038 2054 : ld_arg[1][0] = wide_int_to_tree (lntype, l_const | r_const);
9039 2054 : toshift[1][0] = MIN (xll_bitpos, xrl_bitpos);
9040 2054 : shifted[1][0] = 0;
9041 2054 : bitpos[1][0] = lnbitpos;
9042 2054 : bitsiz[1][0] = lnbitsize;
9043 :
9044 2054 : if (parts > 1)
9045 49 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9046 : shifted[1], xmask[1],
9047 49 : lnbitpos + GET_MODE_BITSIZE (lnmode),
9048 : lr_reversep);
9049 :
9050 : /* No masking needed, we know the full constants. */
9051 2054 : r_mask = wi::mask (0, true, lnprec);
9052 :
9053 : /* If the compiler thinks this is used uninitialized below, it's
9054 : because it can't realize that parts can only be 2 when
9055 : comparing with constants if l_split_load is also true. This
9056 : just silences the warning. */
9057 2054 : rnbitpos = 0;
9058 2054 : }
9059 :
9060 : /* Likewise, if the right sides are not constant, align them for the combined
9061 : compare. Also, disallow this optimization if a size, signedness or
9062 : storage order mismatch occurs between the left and right sides. */
9063 : else
9064 : {
9065 1422 : if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
9066 1336 : || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
9067 1336 : || ll_reversep != lr_reversep
9068 : /* Make sure the two fields on the right
9069 : correspond to the left without being swapped. */
9070 1336 : || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
9071 241 : return 0;
9072 :
9073 : /* Each compare tests, for every bit in its masks, either that the bits
9074 : on both sides are equal (bit in both masks), or that the bit on one
9075 : side is zero (bit in one mask only). The combined compare can only
9076 : express one such test per bit, so reject combinations in which both
9077 : compares test the same bit in different ways. Check this in the
9078 : left-hand frame, since the right-hand fields are laid out alike. */
9079 1194 : wide_int lr_m, rr_m;
9080 1194 : if (lr_and_mask.get_precision ())
9081 2000 : lr_m = wi::lshift (wide_int::from (lr_and_mask, lnprec, UNSIGNED),
9082 1000 : xll_bitpos);
9083 : else
9084 194 : lr_m = wi::shifted_mask (xll_bitpos, lr_bitsize, false, lnprec);
9085 1194 : if (rr_and_mask.get_precision ())
9086 1888 : rr_m = wi::lshift (wide_int::from (rr_and_mask, lnprec, UNSIGNED),
9087 944 : xrl_bitpos);
9088 : else
9089 250 : rr_m = wi::shifted_mask (xrl_bitpos, rr_bitsize, false, lnprec);
9090 2388 : if (((ll_mask | lr_m) & (rl_mask | rr_m)
9091 3582 : & ((ll_mask ^ rl_mask) | (lr_m ^ rr_m))) != 0)
9092 : return 0;
9093 :
9094 1189 : bool r_split_load;
9095 1189 : scalar_int_mode rnmode2;
9096 :
9097 : /* Figure out how to load the bits for the right-hand size of the
9098 : combined compare. As in the left-hand size, we may have to split it,
9099 : and then we use two separate compares. */
9100 1189 : first_bit = MIN (lr_bitpos, rr_bitpos);
9101 1189 : end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
9102 1189 : HOST_WIDE_INT lr_align = TYPE_ALIGN (TREE_TYPE (lr_inner));
9103 1189 : poly_uint64 lr_end_region = 0;
9104 1189 : if (TYPE_SIZE (TREE_TYPE (lr_inner))
9105 1189 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (lr_inner))))
9106 1189 : lr_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (lr_inner)));
9107 1189 : if (!get_best_mode (end_bit - first_bit, first_bit, 0, lr_end_region,
9108 1189 : lr_align, BITS_PER_WORD, volatilep, &rnmode))
9109 : {
9110 : /* Consider the possibility of recombining loads if any of the
9111 : fields straddles across an alignment boundary, so that either
9112 : part can be loaded along with the other field. */
9113 138 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
9114 138 : (lr_align, lr_bitpos, lr_bitsize, rr_bitpos, rr_bitsize);
9115 :
9116 138 : if (boundary < 0
9117 : /* If we're to split both, make sure the split point is
9118 : the same. */
9119 130 : || (l_split_load
9120 128 : && (boundary - lr_bitpos
9121 128 : != (lnbitpos + GET_MODE_BITSIZE (lnmode)) - ll_bitpos))
9122 130 : || !get_best_mode (boundary - first_bit, first_bit,
9123 : 0, lr_end_region,
9124 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode)
9125 268 : || !get_best_mode (end_bit - boundary, boundary, 0, lr_end_region,
9126 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode2))
9127 : return 0;
9128 :
9129 130 : r_split_load = true;
9130 130 : parts = 2;
9131 130 : if (lr_bitpos >= boundary)
9132 : maybe_separate = first1 = true;
9133 88 : else if (lr_bitpos + lr_bitsize <= boundary)
9134 29 : maybe_separate = true;
9135 : }
9136 : else
9137 : r_split_load = false;
9138 :
9139 : /* Find a type that can hold the entire right-hand operand. */
9140 1181 : rnbitsize = GET_MODE_BITSIZE (rnmode);
9141 1181 : rnbitpos = first_bit & ~ (rnbitsize - 1);
9142 1181 : if (r_split_load)
9143 260 : rnbitsize += GET_MODE_BITSIZE (rnmode2);
9144 1181 : rntype = build_nonstandard_integer_type (rnbitsize, 1);
9145 1181 : if (!rntype)
9146 : return 0;
9147 1181 : rnprec = TYPE_PRECISION (rntype);
9148 1181 : xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
9149 :
9150 : /* Adjust for reversed endianness. */
9151 1181 : if (lr_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
9152 : {
9153 0 : xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
9154 0 : xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
9155 : }
9156 :
9157 : /* Adjust the masks to match the combined type, and combine them. */
9158 1181 : wide_int lr_mask, rr_mask;
9159 1181 : if (lr_and_mask.get_precision ())
9160 1992 : lr_mask = wi::lshift (wide_int::from (lr_and_mask, rnprec, UNSIGNED),
9161 996 : xlr_bitpos);
9162 : else
9163 185 : lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec);
9164 1181 : if (rr_and_mask.get_precision ())
9165 1886 : rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED),
9166 943 : xrr_bitpos);
9167 : else
9168 238 : rr_mask = wi::shifted_mask (xrr_bitpos, rr_bitsize, false, rnprec);
9169 1181 : r_mask = lr_mask | rr_mask;
9170 :
9171 : /* Load the right-hand operand of the combined compare. */
9172 1181 : toshift[1][0] = MIN (xlr_bitpos, xrr_bitpos);
9173 1181 : shifted[1][0] = 0;
9174 :
9175 1181 : if (!r_split_load)
9176 : {
9177 1051 : bitpos[1][0] = rnbitpos;
9178 1051 : bitsiz[1][0] = rnbitsize;
9179 2102 : ld_arg[1][0] = make_bit_field_load (ll_loc[3], lr_inner, lr_arg,
9180 1051 : rntype, rnbitsize, rnbitpos,
9181 : lr_unsignedp || rr_unsignedp,
9182 : lr_reversep, lr_load);
9183 : }
9184 :
9185 : /* ... and the second part of the right-hand operand if needed. */
9186 1181 : if (parts > 1)
9187 : {
9188 130 : if (r_split_load)
9189 : {
9190 130 : gimple *point[2];
9191 130 : point[0] = lr_load;
9192 130 : point[1] = rr_load;
9193 130 : build_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9194 : shifted[1], rl_loc[3], lr_inner, lr_arg,
9195 : rnmode, rnmode2, rnbitpos, lr_reversep, point);
9196 : }
9197 : else
9198 0 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9199 : shifted[1], xmask[1],
9200 0 : lnbitpos + GET_MODE_BITSIZE (lnmode)
9201 0 : - ll_bitpos + lr_bitpos, lr_reversep);
9202 : }
9203 1194 : }
9204 :
9205 : /* Now issue the loads for the left-hand combined operand/s. */
9206 6470 : wide_int l_mask = ll_mask | rl_mask;
9207 3235 : toshift[0][0] = MIN (xll_bitpos, xrl_bitpos);
9208 3235 : shifted[0][0] = 0;
9209 :
9210 3235 : if (!l_split_load)
9211 : {
9212 3058 : bitpos[0][0] = lnbitpos;
9213 3058 : bitsiz[0][0] = lnbitsize;
9214 6116 : ld_arg[0][0] = make_bit_field_load (ll_loc[3], ll_inner, ll_arg,
9215 3058 : lntype, lnbitsize, lnbitpos,
9216 : ll_unsignedp || rl_unsignedp,
9217 : ll_reversep, ll_load);
9218 : }
9219 :
9220 3235 : if (parts > 1)
9221 : {
9222 179 : if (l_split_load)
9223 : {
9224 177 : gimple *point[2];
9225 177 : point[0] = ll_load;
9226 177 : point[1] = rl_load;
9227 177 : build_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9228 : shifted[0], rl_loc[3], ll_inner, ll_arg,
9229 : lnmode, lnmode2, lnbitpos, ll_reversep, point);
9230 : }
9231 : else
9232 2 : reuse_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9233 : shifted[0], xmask[0],
9234 2 : rnbitpos + GET_MODE_BITSIZE (rnmode)
9235 2 : - lr_bitpos + ll_bitpos, ll_reversep);
9236 : }
9237 :
9238 : /* Compute the compares. */
9239 6649 : for (int i = 0; i < parts; i++)
9240 : {
9241 3414 : tree op[2] = { ld_arg[0][i], ld_arg[1][i] };
9242 10242 : wide_int mask[2] = { l_mask, r_mask };
9243 3414 : location_t *locs[2] = { i ? rl_loc : ll_loc, i ? rr_loc : lr_loc };
9244 :
9245 : /* Figure out the masks, and unshare the original operands. */
9246 10242 : for (int j = 0; j < 2; j++)
9247 : {
9248 6828 : unsigned prec = TYPE_PRECISION (TREE_TYPE (op[j]));
9249 6828 : op[j] = unshare_expr (op[j]);
9250 :
9251 : /* Mask out the bits belonging to the other part. */
9252 6828 : if (xmask[j][i].get_precision ())
9253 102 : mask[j] &= xmask[j][i];
9254 :
9255 6828 : if (shifted[j][i])
9256 : {
9257 307 : wide_int shift = wide_int::from (shifted[j][i], prec, UNSIGNED);
9258 307 : mask[j] = wi::lrshift (mask[j], shift);
9259 307 : }
9260 6828 : mask[j] = wide_int::from (mask[j], prec, UNSIGNED);
9261 : }
9262 :
9263 : /* Line up the operands for a compare. */
9264 3414 : HOST_WIDE_INT shift = (toshift[0][i] - toshift[1][i]);
9265 :
9266 3414 : if (shift)
9267 : {
9268 54 : int j;
9269 54 : if (shift > 0)
9270 : j = 0;
9271 : else
9272 : {
9273 52 : j = 1;
9274 52 : shift = -shift;
9275 : }
9276 :
9277 54 : tree shiftsz = bitsize_int (shift);
9278 54 : op[j] = fold_build2_loc (locs[j][1], RSHIFT_EXPR, TREE_TYPE (op[j]),
9279 : op[j], shiftsz);
9280 54 : mask[j] = wi::lrshift (mask[j], shift);
9281 : }
9282 :
9283 : /* Convert to the smaller type before masking out unwanted
9284 : bits. */
9285 3414 : tree type = TREE_TYPE (op[0]);
9286 3414 : if (type != TREE_TYPE (op[1]))
9287 : {
9288 190 : int j = (TYPE_PRECISION (type)
9289 190 : < TYPE_PRECISION (TREE_TYPE (op[1])));
9290 190 : if (!j)
9291 91 : type = TREE_TYPE (op[1]);
9292 190 : op[j] = fold_convert_loc (locs[j][0], type, op[j]);
9293 190 : mask[j] = wide_int::from (mask[j], TYPE_PRECISION (type), UNSIGNED);
9294 : }
9295 :
9296 : /* Apply masks. */
9297 10242 : for (int j = 0; j < 2; j++)
9298 6828 : if (mask[j] != wi::mask (0, true, mask[j].get_precision ()))
9299 2686 : op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type,
9300 5372 : op[j], wide_int_to_tree (type, mask[j]));
9301 :
9302 6649 : cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type,
9303 : op[0], op[1]);
9304 10242 : }
9305 :
9306 : /* Reorder the compares if needed. */
9307 3235 : if (first1)
9308 45 : std::swap (cmp[0], cmp[1]);
9309 :
9310 : /* Prepare to return the resulting compares. Combine two parts if
9311 : needed. */
9312 3235 : if (parts == 1)
9313 3056 : result = cmp[0];
9314 179 : else if (!separatep || !maybe_separate)
9315 : {
9316 : /* Only fold if any of the cmp is known, otherwise we may lose the
9317 : sequence point, and that may prevent further optimizations. */
9318 173 : if (TREE_CODE (cmp[0]) == INTEGER_CST
9319 137 : || TREE_CODE (cmp[1]) == INTEGER_CST)
9320 37 : result = fold_build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9321 : else
9322 136 : result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9323 : }
9324 : else
9325 : {
9326 6 : result = cmp[0];
9327 6 : *separatep = cmp[1];
9328 : }
9329 :
9330 3235 : return result;
9331 439829 : }
9332 :
9333 : /* Try to simplify the AND of two comparisons, specified by
9334 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9335 : If this can be simplified to a single expression (without requiring
9336 : introducing more SSA variables to hold intermediate values),
9337 : return the resulting tree. Otherwise return NULL_TREE.
9338 : If the result expression is non-null, it has boolean type. */
9339 :
9340 : tree
9341 608119 : maybe_fold_and_comparisons (tree type,
9342 : enum tree_code code1, tree op1a, tree op1b,
9343 : enum tree_code code2, tree op2a, tree op2b,
9344 : basic_block outer_cond_bb)
9345 : {
9346 608119 : if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9347 : outer_cond_bb))
9348 : return t;
9349 :
9350 606344 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1,
9351 : op1a, op1b, code2, op2a,
9352 : op2b, outer_cond_bb))
9353 : return t;
9354 :
9355 : return NULL_TREE;
9356 : }
9357 :
9358 : /* Helper function for or_comparisons_1: try to simplify the OR of the
9359 : ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
9360 : If INVERT is true, invert the value of VAR before doing the OR.
9361 : Return NULL_EXPR if we can't simplify this to a single expression. */
9362 :
9363 : static tree
9364 47108 : or_var_with_comparison (tree type, tree var, bool invert,
9365 : enum tree_code code2, tree op2a, tree op2b,
9366 : basic_block outer_cond_bb)
9367 : {
9368 47108 : tree t;
9369 47108 : gimple *stmt = SSA_NAME_DEF_STMT (var);
9370 :
9371 : /* We can only deal with variables whose definitions are assignments. */
9372 47108 : if (!is_gimple_assign (stmt))
9373 : return NULL_TREE;
9374 :
9375 : /* If we have an inverted comparison, apply DeMorgan's law and rewrite
9376 : !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
9377 : Then we only have to consider the simpler non-inverted cases. */
9378 47039 : if (invert)
9379 22917 : t = and_var_with_comparison_1 (type, stmt,
9380 : invert_tree_comparison (code2, false),
9381 : op2a, op2b, outer_cond_bb);
9382 : else
9383 24122 : t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
9384 : outer_cond_bb);
9385 47039 : return canonicalize_bool (t, invert);
9386 : }
9387 :
9388 : /* Try to simplify the OR of the ssa variable defined by the assignment
9389 : STMT with the comparison specified by (OP2A CODE2 OP2B).
9390 : Return NULL_EXPR if we can't simplify this to a single expression. */
9391 :
9392 : static tree
9393 88420 : or_var_with_comparison_1 (tree type, gimple *stmt,
9394 : enum tree_code code2, tree op2a, tree op2b,
9395 : basic_block outer_cond_bb)
9396 : {
9397 88420 : tree var = gimple_assign_lhs (stmt);
9398 88420 : tree true_test_var = NULL_TREE;
9399 88420 : tree false_test_var = NULL_TREE;
9400 88420 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
9401 :
9402 : /* Check for identities like (var OR (var != 0)) => true . */
9403 88420 : if (TREE_CODE (op2a) == SSA_NAME
9404 88420 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
9405 : {
9406 17886 : if ((code2 == NE_EXPR && integer_zerop (op2b))
9407 48405 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
9408 : {
9409 14798 : true_test_var = op2a;
9410 14798 : if (var == true_test_var)
9411 : return var;
9412 : }
9413 3028 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
9414 27566 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
9415 : {
9416 6963 : false_test_var = op2a;
9417 6963 : if (var == false_test_var)
9418 0 : return boolean_true_node;
9419 : }
9420 : }
9421 :
9422 : /* If the definition is a comparison, recurse on it. */
9423 88420 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
9424 : {
9425 471 : tree t = or_comparisons_1 (type, innercode,
9426 : gimple_assign_rhs1 (stmt),
9427 : gimple_assign_rhs2 (stmt),
9428 : code2, op2a, op2b, outer_cond_bb);
9429 471 : if (t)
9430 : return t;
9431 : }
9432 :
9433 : /* If the definition is an AND or OR expression, we may be able to
9434 : simplify by reassociating. */
9435 88420 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
9436 88420 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
9437 : {
9438 37524 : tree inner1 = gimple_assign_rhs1 (stmt);
9439 37524 : tree inner2 = gimple_assign_rhs2 (stmt);
9440 37524 : gimple *s;
9441 37524 : tree t;
9442 37524 : tree partial = NULL_TREE;
9443 37524 : bool is_or = (innercode == BIT_IOR_EXPR);
9444 :
9445 : /* Check for boolean identities that don't require recursive examination
9446 : of inner1/inner2:
9447 : inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
9448 : inner1 OR (inner1 AND inner2) => inner1
9449 : !inner1 OR (inner1 OR inner2) => true
9450 : !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
9451 : */
9452 37524 : if (inner1 == true_test_var)
9453 0 : return (is_or ? var : inner1);
9454 37524 : else if (inner2 == true_test_var)
9455 0 : return (is_or ? var : inner2);
9456 37524 : else if (inner1 == false_test_var)
9457 0 : return (is_or
9458 0 : ? boolean_true_node
9459 0 : : or_var_with_comparison (type, inner2, false, code2, op2a,
9460 0 : op2b, outer_cond_bb));
9461 37524 : else if (inner2 == false_test_var)
9462 0 : return (is_or
9463 0 : ? boolean_true_node
9464 0 : : or_var_with_comparison (type, inner1, false, code2, op2a,
9465 0 : op2b, outer_cond_bb));
9466 :
9467 : /* Next, redistribute/reassociate the OR across the inner tests.
9468 : Compute the first partial result, (inner1 OR (op2a code op2b)) */
9469 37524 : if (TREE_CODE (inner1) == SSA_NAME
9470 37524 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
9471 36904 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9472 65805 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9473 : gimple_assign_rhs1 (s),
9474 : gimple_assign_rhs2 (s),
9475 : code2, op2a, op2b,
9476 : outer_cond_bb)))
9477 : {
9478 : /* Handle the OR case, where we are reassociating:
9479 : (inner1 OR inner2) OR (op2a code2 op2b)
9480 : => (t OR inner2)
9481 : If the partial result t is a constant, we win. Otherwise
9482 : continue on to try reassociating with the other inner test. */
9483 2615 : if (is_or)
9484 : {
9485 21 : if (integer_onep (t))
9486 0 : return boolean_true_node;
9487 21 : else if (integer_zerop (t))
9488 : return inner2;
9489 : }
9490 :
9491 : /* Handle the AND case, where we are redistributing:
9492 : (inner1 AND inner2) OR (op2a code2 op2b)
9493 : => (t AND (inner2 OR (op2a code op2b))) */
9494 2594 : else if (integer_zerop (t))
9495 0 : return boolean_false_node;
9496 :
9497 : /* Save partial result for later. */
9498 : partial = t;
9499 : }
9500 :
9501 : /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
9502 37524 : if (TREE_CODE (inner2) == SSA_NAME
9503 37524 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
9504 37090 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9505 72381 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9506 : gimple_assign_rhs1 (s),
9507 : gimple_assign_rhs2 (s),
9508 : code2, op2a, op2b,
9509 : outer_cond_bb)))
9510 : {
9511 : /* Handle the OR case, where we are reassociating:
9512 : (inner1 OR inner2) OR (op2a code2 op2b)
9513 : => (inner1 OR t)
9514 : => (t OR partial) */
9515 2652 : if (is_or)
9516 : {
9517 31 : if (integer_zerop (t))
9518 : return inner1;
9519 31 : else if (integer_onep (t))
9520 1 : return boolean_true_node;
9521 : /* If both are the same, we can apply the identity
9522 : (x OR x) == x. */
9523 30 : else if (partial && same_bool_result_p (t, partial))
9524 3 : return t;
9525 : }
9526 :
9527 : /* Handle the AND case, where we are redistributing:
9528 : (inner1 AND inner2) OR (op2a code2 op2b)
9529 : => (t AND (inner1 OR (op2a code2 op2b)))
9530 : => (t AND partial) */
9531 : else
9532 : {
9533 2621 : if (integer_zerop (t))
9534 0 : return boolean_false_node;
9535 2621 : else if (partial)
9536 : {
9537 : /* We already got a simplification for the other
9538 : operand to the redistributed AND expression. The
9539 : interesting case is when at least one is true.
9540 : Or, if both are the same, we can apply the identity
9541 : (x AND x) == x. */
9542 15 : if (integer_onep (partial))
9543 : return t;
9544 14 : else if (integer_onep (t))
9545 : return partial;
9546 1 : else if (same_bool_result_p (t, partial))
9547 0 : return t;
9548 : }
9549 : }
9550 : }
9551 : }
9552 : return NULL_TREE;
9553 : }
9554 :
9555 : /* Try to simplify the OR of two comparisons defined by
9556 : (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
9557 : If this can be done without constructing an intermediate value,
9558 : return the resulting tree; otherwise NULL_TREE is returned.
9559 : This function is deliberately asymmetric as it recurses on SSA_DEFs
9560 : in the first comparison but not the second. */
9561 :
9562 : static tree
9563 518066 : or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
9564 : enum tree_code code2, tree op2a, tree op2b,
9565 : basic_block outer_cond_bb)
9566 : {
9567 518066 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
9568 :
9569 : /* First check for ((x CODE1 y) OR (x CODE2 y)). */
9570 518066 : if (operand_equal_p (op1a, op2a, 0)
9571 518066 : && operand_equal_p (op1b, op2b, 0))
9572 : {
9573 : /* Result will be either NULL_TREE, or a combined comparison. */
9574 7337 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9575 : TRUTH_ORIF_EXPR, code1, code2,
9576 : truth_type, op1a, op1b);
9577 7337 : if (t)
9578 : return t;
9579 : }
9580 :
9581 : /* Likewise the swapped case of the above. */
9582 510761 : if (operand_equal_p (op1a, op2b, 0)
9583 510761 : && operand_equal_p (op1b, op2a, 0))
9584 : {
9585 : /* Result will be either NULL_TREE, or a combined comparison. */
9586 0 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9587 : TRUTH_ORIF_EXPR, code1,
9588 : swap_tree_comparison (code2),
9589 : truth_type, op1a, op1b);
9590 0 : if (t)
9591 : return t;
9592 : }
9593 :
9594 : /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
9595 : NAME's definition is a truth value. See if there are any simplifications
9596 : that can be done against the NAME's definition. */
9597 510761 : if (TREE_CODE (op1a) == SSA_NAME
9598 510608 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
9599 863532 : && (integer_zerop (op1b) || integer_onep (op1b)))
9600 : {
9601 40645 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
9602 82681 : || (code1 == NE_EXPR && integer_onep (op1b)));
9603 78389 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
9604 78389 : switch (gimple_code (stmt))
9605 : {
9606 47039 : case GIMPLE_ASSIGN:
9607 : /* Try to simplify by copy-propagating the definition. */
9608 47039 : return or_var_with_comparison (type, op1a, invert, code2, op2a,
9609 47039 : op2b, outer_cond_bb);
9610 :
9611 14549 : case GIMPLE_PHI:
9612 : /* If every argument to the PHI produces the same result when
9613 : ORed with the second comparison, we win.
9614 : Do not do this unless the type is bool since we need a bool
9615 : result here anyway. */
9616 14549 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
9617 : {
9618 : tree result = NULL_TREE;
9619 : unsigned i;
9620 756 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
9621 : {
9622 756 : tree arg = gimple_phi_arg_def (stmt, i);
9623 :
9624 : /* If this PHI has itself as an argument, ignore it.
9625 : If all the other args produce the same result,
9626 : we're still OK. */
9627 756 : if (arg == gimple_phi_result (stmt))
9628 0 : continue;
9629 756 : else if (TREE_CODE (arg) == INTEGER_CST)
9630 : {
9631 674 : if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
9632 : {
9633 335 : if (!result)
9634 211 : result = boolean_true_node;
9635 124 : else if (!integer_onep (result))
9636 : return NULL_TREE;
9637 : }
9638 339 : else if (!result)
9639 133 : result = fold_build2 (code2, boolean_type_node,
9640 : op2a, op2b);
9641 206 : else if (!same_bool_comparison_p (result,
9642 : code2, op2a, op2b))
9643 : return NULL_TREE;
9644 : }
9645 82 : else if (TREE_CODE (arg) == SSA_NAME
9646 82 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
9647 : {
9648 82 : tree temp;
9649 82 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
9650 : /* In simple cases we can look through PHI nodes,
9651 : but we have to be careful with loops.
9652 : See PR49073. */
9653 82 : if (! dom_info_available_p (CDI_DOMINATORS)
9654 82 : || gimple_bb (def_stmt) == gimple_bb (stmt)
9655 164 : || dominated_by_p (CDI_DOMINATORS,
9656 82 : gimple_bb (def_stmt),
9657 82 : gimple_bb (stmt)))
9658 : return NULL_TREE;
9659 69 : temp = or_var_with_comparison (type, arg, invert, code2,
9660 : op2a, op2b, outer_cond_bb);
9661 69 : if (!temp)
9662 : return NULL_TREE;
9663 0 : else if (!result)
9664 : result = temp;
9665 0 : else if (!same_bool_result_p (result, temp))
9666 : return NULL_TREE;
9667 : }
9668 : else
9669 : return NULL_TREE;
9670 : }
9671 : return result;
9672 : }
9673 :
9674 : default:
9675 : break;
9676 : }
9677 : }
9678 : return NULL_TREE;
9679 : }
9680 :
9681 : /* Try to simplify the OR of two comparisons, specified by
9682 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9683 : If this can be simplified to a single expression (without requiring
9684 : introducing more SSA variables to hold intermediate values),
9685 : return the resulting tree. Otherwise return NULL_TREE.
9686 : If the result expression is non-null, it has boolean type. */
9687 :
9688 : tree
9689 262450 : maybe_fold_or_comparisons (tree type,
9690 : enum tree_code code1, tree op1a, tree op1b,
9691 : enum tree_code code2, tree op2a, tree op2b,
9692 : basic_block outer_cond_bb)
9693 : {
9694 262450 : if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9695 : outer_cond_bb))
9696 : return t;
9697 :
9698 255145 : if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b,
9699 : outer_cond_bb))
9700 : return t;
9701 :
9702 255141 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1,
9703 : op1a, op1b, code2, op2a,
9704 : op2b, outer_cond_bb))
9705 : return t;
9706 :
9707 : return NULL_TREE;
9708 : }
9709 :
9710 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
9711 :
9712 : Either NULL_TREE, a simplified but non-constant or a constant
9713 : is returned.
9714 :
9715 : ??? This should go into a gimple-fold-inline.h file to be eventually
9716 : privatized with the single valueize function used in the various TUs
9717 : to avoid the indirect function call overhead. */
9718 :
9719 : tree
9720 435115498 : gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
9721 : tree (*gvalueize) (tree))
9722 : {
9723 435115498 : gimple_match_op res_op;
9724 : /* ??? The SSA propagators do not correctly deal with following SSA use-def
9725 : edges if there are intermediate VARYING defs. For this reason
9726 : do not follow SSA edges here even though SCCVN can technically
9727 : just deal fine with that. */
9728 435115498 : if (gimple_simplify (stmt, &res_op, NULL, gvalueize, valueize))
9729 : {
9730 57196231 : tree res = NULL_TREE;
9731 57196231 : if (gimple_simplified_result_is_gimple_val (&res_op))
9732 34924950 : res = res_op.ops[0];
9733 22271281 : else if (mprts_hook)
9734 7775856 : res = mprts_hook (&res_op);
9735 42700806 : if (res)
9736 : {
9737 36831644 : if (dump_file && dump_flags & TDF_DETAILS)
9738 : {
9739 9496 : fprintf (dump_file, "Match-and-simplified ");
9740 9496 : print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
9741 9496 : fprintf (dump_file, " to ");
9742 9496 : print_generic_expr (dump_file, res);
9743 9496 : fprintf (dump_file, "\n");
9744 : }
9745 : return res;
9746 : }
9747 : }
9748 :
9749 398283854 : location_t loc = gimple_location (stmt);
9750 398283854 : switch (gimple_code (stmt))
9751 : {
9752 345190014 : case GIMPLE_ASSIGN:
9753 345190014 : {
9754 345190014 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
9755 :
9756 345190014 : switch (get_gimple_rhs_class (subcode))
9757 : {
9758 119035151 : case GIMPLE_SINGLE_RHS:
9759 119035151 : {
9760 119035151 : tree rhs = gimple_assign_rhs1 (stmt);
9761 119035151 : enum tree_code_class kind = TREE_CODE_CLASS (subcode);
9762 :
9763 119035151 : if (TREE_CODE (rhs) == SSA_NAME)
9764 : {
9765 : /* If the RHS is an SSA_NAME, return its known constant value,
9766 : if any. */
9767 11918216 : return (*valueize) (rhs);
9768 : }
9769 : /* Handle propagating invariant addresses into address
9770 : operations. */
9771 107116935 : else if (TREE_CODE (rhs) == ADDR_EXPR
9772 107116935 : && !is_gimple_min_invariant (rhs))
9773 : {
9774 6493612 : poly_int64 offset = 0;
9775 6493612 : tree base;
9776 6493612 : base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (rhs, 0),
9777 : &offset,
9778 : valueize);
9779 6493612 : if (base
9780 6493612 : && (CONSTANT_CLASS_P (base)
9781 5830545 : || decl_address_invariant_p (base)))
9782 201022 : return build_invariant_address (TREE_TYPE (rhs),
9783 201022 : base, offset);
9784 : }
9785 100623323 : else if (TREE_CODE (rhs) == CONSTRUCTOR
9786 1133494 : && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
9787 102217206 : && known_eq (CONSTRUCTOR_NELTS (rhs),
9788 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
9789 : {
9790 437520 : unsigned i, nelts;
9791 437520 : tree val;
9792 :
9793 437520 : nelts = CONSTRUCTOR_NELTS (rhs);
9794 437520 : tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
9795 980872 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
9796 : {
9797 531306 : val = (*valueize) (val);
9798 531306 : if (TREE_CODE (val) == INTEGER_CST
9799 447308 : || TREE_CODE (val) == REAL_CST
9800 425474 : || TREE_CODE (val) == FIXED_CST)
9801 105832 : vec.quick_push (val);
9802 : else
9803 : return NULL_TREE;
9804 : }
9805 :
9806 12046 : return vec.build ();
9807 437520 : }
9808 106478393 : if (subcode == OBJ_TYPE_REF)
9809 : {
9810 418290 : tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
9811 : /* If callee is constant, we can fold away the wrapper. */
9812 418290 : if (is_gimple_min_invariant (val))
9813 : return val;
9814 : }
9815 :
9816 106478109 : if (kind == tcc_reference)
9817 : {
9818 70718425 : if ((TREE_CODE (rhs) == VIEW_CONVERT_EXPR
9819 68439129 : || TREE_CODE (rhs) == REALPART_EXPR
9820 67421098 : || TREE_CODE (rhs) == IMAGPART_EXPR)
9821 72912848 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9822 : {
9823 3542802 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9824 3542802 : return fold_unary_loc (EXPR_LOCATION (rhs),
9825 3542802 : TREE_CODE (rhs),
9826 7085604 : TREE_TYPE (rhs), val);
9827 : }
9828 67175623 : else if (TREE_CODE (rhs) == BIT_FIELD_REF
9829 67175623 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9830 : {
9831 658290 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9832 658290 : return fold_ternary_loc (EXPR_LOCATION (rhs),
9833 658290 : TREE_CODE (rhs),
9834 658290 : TREE_TYPE (rhs), val,
9835 658290 : TREE_OPERAND (rhs, 1),
9836 1316580 : TREE_OPERAND (rhs, 2));
9837 : }
9838 66517333 : else if (TREE_CODE (rhs) == MEM_REF
9839 66517333 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9840 : {
9841 13713074 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9842 13713074 : if (TREE_CODE (val) == ADDR_EXPR
9843 13713074 : && is_gimple_min_invariant (val))
9844 : {
9845 979233 : tree tem = fold_build2 (MEM_REF, TREE_TYPE (rhs),
9846 : unshare_expr (val),
9847 : TREE_OPERAND (rhs, 1));
9848 979233 : if (tem)
9849 66517333 : rhs = tem;
9850 : }
9851 : }
9852 66517333 : return fold_const_aggregate_ref_1 (rhs, valueize);
9853 : }
9854 35759684 : else if (kind == tcc_declaration)
9855 7897090 : return get_symbol_constant_value (rhs);
9856 : return rhs;
9857 : }
9858 :
9859 : case GIMPLE_UNARY_RHS:
9860 : return NULL_TREE;
9861 :
9862 169701796 : case GIMPLE_BINARY_RHS:
9863 : /* Translate &x + CST into an invariant form suitable for
9864 : further propagation. */
9865 169701796 : if (subcode == POINTER_PLUS_EXPR)
9866 : {
9867 25797700 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9868 25797700 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9869 25797700 : if (TREE_CODE (op0) == ADDR_EXPR
9870 5872794 : && TREE_CODE (op1) == INTEGER_CST)
9871 : {
9872 589252 : tree off = fold_convert (ptr_type_node, op1);
9873 589252 : return build1_loc
9874 1178504 : (loc, ADDR_EXPR, TREE_TYPE (op0),
9875 589252 : fold_build2 (MEM_REF,
9876 : TREE_TYPE (TREE_TYPE (op0)),
9877 589252 : unshare_expr (op0), off));
9878 : }
9879 : }
9880 : /* Canonicalize bool != 0 and bool == 0 appearing after
9881 : valueization. While gimple_simplify handles this
9882 : it can get confused by the ~X == 1 -> X == 0 transform
9883 : which we cant reduce to a SSA name or a constant
9884 : (and we have no way to tell gimple_simplify to not
9885 : consider those transforms in the first place). */
9886 143904096 : else if (subcode == EQ_EXPR
9887 143904096 : || subcode == NE_EXPR)
9888 : {
9889 3438475 : tree lhs = gimple_assign_lhs (stmt);
9890 3438475 : tree op0 = gimple_assign_rhs1 (stmt);
9891 3438475 : if (useless_type_conversion_p (TREE_TYPE (lhs),
9892 3438475 : TREE_TYPE (op0)))
9893 : {
9894 24470 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9895 24470 : op0 = (*valueize) (op0);
9896 24470 : if (TREE_CODE (op0) == INTEGER_CST)
9897 518 : std::swap (op0, op1);
9898 24470 : if (TREE_CODE (op1) == INTEGER_CST
9899 24470 : && ((subcode == NE_EXPR && integer_zerop (op1))
9900 2080 : || (subcode == EQ_EXPR && integer_onep (op1))))
9901 276 : return op0;
9902 : }
9903 : }
9904 : return NULL_TREE;
9905 :
9906 767127 : case GIMPLE_TERNARY_RHS:
9907 767127 : {
9908 : /* Handle ternary operators that can appear in GIMPLE form. */
9909 767127 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9910 767127 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9911 767127 : tree op2 = (*valueize) (gimple_assign_rhs3 (stmt));
9912 767127 : return fold_ternary_loc (loc, subcode,
9913 767127 : TREE_TYPE (gimple_assign_lhs (stmt)),
9914 767127 : op0, op1, op2);
9915 : }
9916 :
9917 0 : default:
9918 0 : gcc_unreachable ();
9919 : }
9920 : }
9921 :
9922 15010292 : case GIMPLE_CALL:
9923 15010292 : {
9924 15010292 : tree fn;
9925 15010292 : gcall *call_stmt = as_a <gcall *> (stmt);
9926 :
9927 15010292 : if (gimple_call_internal_p (stmt))
9928 : {
9929 1343461 : enum tree_code subcode = ERROR_MARK;
9930 1343461 : switch (gimple_call_internal_fn (stmt))
9931 : {
9932 : case IFN_UBSAN_CHECK_ADD:
9933 : subcode = PLUS_EXPR;
9934 : break;
9935 8233 : case IFN_UBSAN_CHECK_SUB:
9936 8233 : subcode = MINUS_EXPR;
9937 8233 : break;
9938 6847 : case IFN_UBSAN_CHECK_MUL:
9939 6847 : subcode = MULT_EXPR;
9940 6847 : break;
9941 145599 : case IFN_BUILTIN_EXPECT:
9942 145599 : {
9943 145599 : tree arg0 = gimple_call_arg (stmt, 0);
9944 145599 : tree op0 = (*valueize) (arg0);
9945 145599 : if (TREE_CODE (op0) == INTEGER_CST)
9946 : return op0;
9947 114003 : return NULL_TREE;
9948 : }
9949 : default:
9950 : return NULL_TREE;
9951 : }
9952 23263 : tree arg0 = gimple_call_arg (stmt, 0);
9953 23263 : tree arg1 = gimple_call_arg (stmt, 1);
9954 23263 : tree op0 = (*valueize) (arg0);
9955 23263 : tree op1 = (*valueize) (arg1);
9956 :
9957 23263 : if (TREE_CODE (op0) != INTEGER_CST
9958 2561 : || TREE_CODE (op1) != INTEGER_CST)
9959 : {
9960 22741 : switch (subcode)
9961 : {
9962 6747 : case MULT_EXPR:
9963 : /* x * 0 = 0 * x = 0 without overflow. */
9964 6747 : if (integer_zerop (op0) || integer_zerop (op1))
9965 20 : return build_zero_cst (TREE_TYPE (arg0));
9966 : break;
9967 7891 : case MINUS_EXPR:
9968 : /* y - y = 0 without overflow. */
9969 7891 : if (operand_equal_p (op0, op1, 0))
9970 0 : return build_zero_cst (TREE_TYPE (arg0));
9971 : break;
9972 : default:
9973 : break;
9974 : }
9975 : }
9976 23243 : tree res
9977 23243 : = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1);
9978 23243 : if (res
9979 3078 : && TREE_CODE (res) == INTEGER_CST
9980 23765 : && !TREE_OVERFLOW (res))
9981 0 : return res;
9982 : return NULL_TREE;
9983 : }
9984 :
9985 13666831 : fn = (*valueize) (gimple_call_fn (stmt));
9986 13666831 : if (TREE_CODE (fn) == ADDR_EXPR
9987 13011423 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
9988 13011359 : && fndecl_built_in_p (TREE_OPERAND (fn, 0))
9989 19928357 : && gimple_builtin_call_types_compatible_p (stmt,
9990 6261526 : TREE_OPERAND (fn, 0)))
9991 : {
9992 6159441 : tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
9993 6159441 : tree retval;
9994 6159441 : unsigned i;
9995 19066353 : for (i = 0; i < gimple_call_num_args (stmt); ++i)
9996 12906912 : args[i] = (*valueize) (gimple_call_arg (stmt, i));
9997 6159441 : retval = fold_builtin_call_array (loc,
9998 : gimple_call_return_type (call_stmt),
9999 : fn, gimple_call_num_args (stmt), args);
10000 6159441 : if (retval)
10001 : {
10002 : /* fold_call_expr wraps the result inside a NOP_EXPR. */
10003 61977 : STRIP_NOPS (retval);
10004 61977 : retval = fold_convert (gimple_call_return_type (call_stmt),
10005 : retval);
10006 : }
10007 : return retval;
10008 : }
10009 : return NULL_TREE;
10010 : }
10011 :
10012 : default:
10013 : return NULL_TREE;
10014 : }
10015 : }
10016 :
10017 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
10018 : Returns NULL_TREE if folding to a constant is not possible, otherwise
10019 : returns a constant according to is_gimple_min_invariant. */
10020 :
10021 : tree
10022 4380 : gimple_fold_stmt_to_constant (gimple *stmt, tree (*valueize) (tree))
10023 : {
10024 4380 : tree res = gimple_fold_stmt_to_constant_1 (stmt, valueize);
10025 4380 : if (res && is_gimple_min_invariant (res))
10026 2369 : return res;
10027 : return NULL_TREE;
10028 : }
10029 :
10030 :
10031 : /* The following set of functions are supposed to fold references using
10032 : their constant initializers. */
10033 :
10034 : /* See if we can find constructor defining value of BASE.
10035 : When we know the constructor with constant offset (such as
10036 : base is array[40] and we do know constructor of array), then
10037 : BIT_OFFSET is adjusted accordingly.
10038 :
10039 : As a special case, return error_mark_node when constructor
10040 : is not explicitly available, but it is known to be zero
10041 : such as 'static const int a;'. */
10042 : static tree
10043 126776224 : get_base_constructor (tree base, poly_int64 *bit_offset,
10044 : tree (*valueize)(tree))
10045 : {
10046 126875731 : poly_int64 bit_offset2, size, max_size;
10047 126875731 : bool reverse;
10048 :
10049 126875731 : if (TREE_CODE (base) == MEM_REF)
10050 : {
10051 135411510 : poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
10052 67705755 : if (!boff.to_shwi (bit_offset))
10053 67329013 : return NULL_TREE;
10054 :
10055 67705403 : if (valueize
10056 67705403 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
10057 35457173 : base = valueize (TREE_OPERAND (base, 0));
10058 67705403 : if (!base || TREE_CODE (base) != ADDR_EXPR)
10059 : return NULL_TREE;
10060 376742 : base = TREE_OPERAND (base, 0);
10061 : }
10062 59169976 : else if (valueize
10063 30710244 : && TREE_CODE (base) == SSA_NAME)
10064 0 : base = valueize (base);
10065 :
10066 : /* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its
10067 : DECL_INITIAL. If BASE is a nested reference into another
10068 : ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
10069 : the inner reference. */
10070 59546718 : switch (TREE_CODE (base))
10071 : {
10072 51883373 : case VAR_DECL:
10073 51883373 : case CONST_DECL:
10074 51883373 : {
10075 51883373 : tree init = ctor_for_folding (base);
10076 :
10077 : /* Our semantic is exact opposite of ctor_for_folding;
10078 : NULL means unknown, while error_mark_node is 0. */
10079 51883373 : if (init == error_mark_node)
10080 : return NULL_TREE;
10081 1288760 : if (!init)
10082 1174 : return error_mark_node;
10083 : return init;
10084 : }
10085 :
10086 99507 : case VIEW_CONVERT_EXPR:
10087 99507 : return get_base_constructor (TREE_OPERAND (base, 0),
10088 99507 : bit_offset, valueize);
10089 :
10090 367566 : case ARRAY_REF:
10091 367566 : case COMPONENT_REF:
10092 367566 : base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
10093 : &reverse);
10094 367566 : if (!known_size_p (max_size) || maybe_ne (size, max_size))
10095 : return NULL_TREE;
10096 307113 : *bit_offset += bit_offset2;
10097 307113 : return get_base_constructor (base, bit_offset, valueize);
10098 :
10099 : case CONSTRUCTOR:
10100 : return base;
10101 :
10102 7196272 : default:
10103 7196272 : if (CONSTANT_CLASS_P (base))
10104 97204 : return base;
10105 :
10106 : return NULL_TREE;
10107 : }
10108 : }
10109 :
10110 : /* CTOR is a CONSTRUCTOR of an array or vector type. Fold a reference of SIZE
10111 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10112 : the reference; otherwise the type of the referenced element is used instead.
10113 : When SIZE is zero, attempt to fold a reference to the entire element OFFSET
10114 : refers to. Increment *SUBOFF by the bit offset of the accessed element. */
10115 :
10116 : static tree
10117 700376 : fold_array_ctor_reference (tree type, tree ctor,
10118 : unsigned HOST_WIDE_INT offset,
10119 : unsigned HOST_WIDE_INT size,
10120 : tree from_decl,
10121 : unsigned HOST_WIDE_INT *suboff)
10122 : {
10123 700376 : offset_int low_bound;
10124 700376 : offset_int elt_size;
10125 700376 : offset_int access_index;
10126 700376 : tree domain_type = NULL_TREE;
10127 700376 : HOST_WIDE_INT inner_offset;
10128 :
10129 : /* Compute low bound and elt size. */
10130 700376 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
10131 700376 : domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
10132 700376 : if (domain_type && TYPE_MIN_VALUE (domain_type))
10133 : {
10134 : /* Static constructors for variably sized objects make no sense. */
10135 700376 : if (TREE_CODE (TYPE_MIN_VALUE (domain_type)) != INTEGER_CST)
10136 : return NULL_TREE;
10137 700376 : low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
10138 : }
10139 : else
10140 0 : low_bound = 0;
10141 : /* Static constructors for variably sized objects make no sense. */
10142 700376 : if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))) != INTEGER_CST)
10143 : return NULL_TREE;
10144 700376 : elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
10145 :
10146 : /* When TYPE is non-null, verify that it specifies a constant-sized
10147 : access of a multiple of the array element size. Avoid division
10148 : by zero below when ELT_SIZE is zero, such as with the result of
10149 : an initializer for a zero-length array or an empty struct. */
10150 700412 : if (elt_size == 0
10151 700376 : || (type
10152 700340 : && (!TYPE_SIZE_UNIT (type)
10153 700340 : || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
10154 : return NULL_TREE;
10155 :
10156 : /* Compute the array index we look for. */
10157 700340 : access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
10158 : elt_size);
10159 700340 : access_index += low_bound;
10160 :
10161 : /* And offset within the access. */
10162 700340 : inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
10163 :
10164 700340 : unsigned HOST_WIDE_INT elt_sz = elt_size.to_uhwi ();
10165 700340 : if (size > elt_sz * BITS_PER_UNIT)
10166 : {
10167 : /* native_encode_expr constraints. */
10168 21537 : if (size > MAX_BITSIZE_MODE_ANY_MODE
10169 17564 : || size % BITS_PER_UNIT != 0
10170 17564 : || inner_offset % BITS_PER_UNIT != 0
10171 17564 : || elt_sz > MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT)
10172 : return NULL_TREE;
10173 :
10174 17564 : unsigned ctor_idx;
10175 17564 : tree val = get_array_ctor_element_at_index (ctor, access_index,
10176 : &ctor_idx);
10177 17588 : if (!val && ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10178 23 : return build_zero_cst (type);
10179 :
10180 : /* native-encode adjacent ctor elements. */
10181 17541 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10182 17541 : unsigned bufoff = 0;
10183 17541 : offset_int index = 0;
10184 17541 : offset_int max_index = access_index;
10185 17541 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10186 17541 : if (!val)
10187 1 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10188 17540 : else if (!CONSTANT_CLASS_P (val))
10189 : return NULL_TREE;
10190 17385 : if (!elt->index)
10191 : ;
10192 17250 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10193 : {
10194 10 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10195 10 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10196 : }
10197 : else
10198 17240 : index = max_index = wi::to_offset (elt->index);
10199 17385 : index = wi::umax (index, access_index);
10200 113068 : do
10201 : {
10202 113068 : if (bufoff + elt_sz > sizeof (buf))
10203 0 : elt_sz = sizeof (buf) - bufoff;
10204 113068 : int len;
10205 113068 : if (TREE_CODE (val) == RAW_DATA_CST)
10206 : {
10207 20 : gcc_assert (inner_offset == 0);
10208 20 : if (!elt->index || TREE_CODE (elt->index) != INTEGER_CST)
10209 : return NULL_TREE;
10210 40 : inner_offset = (access_index
10211 20 : - wi::to_offset (elt->index)).to_uhwi ();
10212 20 : len = MIN (sizeof (buf) - bufoff,
10213 : (unsigned) (RAW_DATA_LENGTH (val) - inner_offset));
10214 20 : memcpy (buf + bufoff, RAW_DATA_POINTER (val) + inner_offset,
10215 : len);
10216 20 : access_index += len - 1;
10217 : }
10218 : else
10219 : {
10220 226096 : len = native_encode_expr (val, buf + bufoff, elt_sz,
10221 113048 : inner_offset / BITS_PER_UNIT);
10222 113048 : if (len != (int) elt_sz - inner_offset / BITS_PER_UNIT)
10223 : return NULL_TREE;
10224 : }
10225 113068 : inner_offset = 0;
10226 113068 : bufoff += len;
10227 :
10228 113068 : access_index += 1;
10229 113068 : if (wi::cmpu (access_index, index) == 0)
10230 2 : val = elt->value;
10231 113066 : else if (wi::cmpu (access_index, max_index) > 0)
10232 : {
10233 112916 : ctor_idx++;
10234 112916 : if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10235 : {
10236 15453 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10237 15453 : ++max_index;
10238 : }
10239 : else
10240 : {
10241 97463 : elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10242 97463 : index = 0;
10243 97463 : max_index = access_index;
10244 97463 : if (!elt->index)
10245 : ;
10246 96655 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10247 : {
10248 0 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10249 0 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10250 : }
10251 : else
10252 96655 : index = max_index = wi::to_offset (elt->index);
10253 97463 : index = wi::umax (index, access_index);
10254 97463 : if (wi::cmpu (access_index, index) == 0)
10255 97458 : val = elt->value;
10256 : else
10257 5 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10258 : }
10259 : }
10260 : }
10261 113068 : while (bufoff < size / BITS_PER_UNIT);
10262 17385 : *suboff += size;
10263 17385 : return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
10264 : }
10265 :
10266 678803 : unsigned ctor_idx;
10267 678803 : if (tree val = get_array_ctor_element_at_index (ctor, access_index,
10268 : &ctor_idx))
10269 : {
10270 677649 : if (TREE_CODE (val) == RAW_DATA_CST)
10271 : {
10272 2590 : if (size != BITS_PER_UNIT || elt_sz != 1 || inner_offset != 0)
10273 : return NULL_TREE;
10274 2582 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10275 2582 : if (elt->index == NULL_TREE || TREE_CODE (elt->index) != INTEGER_CST)
10276 : return NULL_TREE;
10277 2582 : unsigned o = (access_index - wi::to_offset (elt->index)).to_uhwi ();
10278 2582 : val = build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
10279 : }
10280 677641 : if (!size && TREE_CODE (val) != CONSTRUCTOR)
10281 : {
10282 : /* For the final reference to the entire accessed element
10283 : (SIZE is zero), reset INNER_OFFSET, disegard TYPE (which
10284 : may be null) in favor of the type of the element, and set
10285 : SIZE to the size of the accessed element. */
10286 23751 : inner_offset = 0;
10287 23751 : type = TREE_TYPE (val);
10288 23751 : size = elt_sz * BITS_PER_UNIT;
10289 : }
10290 1742933 : else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
10291 476025 : && TREE_CODE (val) == CONSTRUCTOR
10292 15653 : && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
10293 : /* If this isn't the last element in the CTOR and a CTOR itself
10294 : and it does not cover the whole object we are requesting give up
10295 : since we're not set up for combining from multiple CTORs. */
10296 26 : return NULL_TREE;
10297 :
10298 677615 : *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
10299 677615 : return fold_ctor_reference (type, val, inner_offset, size, from_decl,
10300 : suboff);
10301 : }
10302 :
10303 : /* Memory not explicitly mentioned in constructor is 0 (or
10304 : the reference is out of range). */
10305 1154 : return type ? build_zero_cst (type) : NULL_TREE;
10306 : }
10307 :
10308 : /* CTOR is a CONSTRUCTOR of a record or union type. Fold a reference of SIZE
10309 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10310 : the reference; otherwise the type of the referenced member is used instead.
10311 : When SIZE is zero, attempt to fold a reference to the entire member OFFSET
10312 : refers to. Increment *SUBOFF by the bit offset of the accessed member. */
10313 :
10314 : static tree
10315 83256 : fold_nonarray_ctor_reference (tree type, tree ctor,
10316 : unsigned HOST_WIDE_INT offset,
10317 : unsigned HOST_WIDE_INT size,
10318 : tree from_decl,
10319 : unsigned HOST_WIDE_INT *suboff)
10320 : {
10321 83256 : unsigned HOST_WIDE_INT cnt;
10322 83256 : tree cfield, cval;
10323 :
10324 126363 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
10325 : {
10326 117406 : tree byte_offset = DECL_FIELD_OFFSET (cfield);
10327 117406 : tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
10328 117406 : tree field_size = DECL_SIZE (cfield);
10329 :
10330 117406 : if (!field_size)
10331 : {
10332 : /* Determine the size of the flexible array member from
10333 : the size of the initializer provided for it. */
10334 847 : field_size = TYPE_SIZE (TREE_TYPE (cval));
10335 : }
10336 :
10337 : /* Variable sized objects in static constructors makes no sense,
10338 : but field_size can be NULL for flexible array members. */
10339 117406 : gcc_assert (TREE_CODE (field_offset) == INTEGER_CST
10340 : && TREE_CODE (byte_offset) == INTEGER_CST
10341 : && (field_size != NULL_TREE
10342 : ? TREE_CODE (field_size) == INTEGER_CST
10343 : : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
10344 :
10345 : /* Compute bit offset of the field. */
10346 117406 : offset_int bitoffset
10347 117406 : = (wi::to_offset (field_offset)
10348 117406 : + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
10349 : /* Compute bit offset where the field ends. */
10350 117406 : offset_int bitoffset_end;
10351 117406 : if (field_size != NULL_TREE)
10352 117406 : bitoffset_end = bitoffset + wi::to_offset (field_size);
10353 : else
10354 0 : bitoffset_end = 0;
10355 :
10356 : /* Compute the bit offset of the end of the desired access.
10357 : As a special case, if the size of the desired access is
10358 : zero, assume the access is to the entire field (and let
10359 : the caller make any necessary adjustments by storing
10360 : the actual bounds of the field in FIELDBOUNDS). */
10361 117406 : offset_int access_end = offset_int (offset);
10362 117406 : if (size)
10363 70781 : access_end += size;
10364 : else
10365 46625 : access_end = bitoffset_end;
10366 :
10367 : /* Is there any overlap between the desired access at
10368 : [OFFSET, OFFSET+SIZE) and the offset of the field within
10369 : the object at [BITOFFSET, BITOFFSET_END)? */
10370 117406 : if (wi::cmps (access_end, bitoffset) > 0
10371 117406 : && (field_size == NULL_TREE
10372 114701 : || wi::lts_p (offset, bitoffset_end)))
10373 : {
10374 74299 : *suboff += bitoffset.to_uhwi ();
10375 :
10376 74299 : if (!size && TREE_CODE (cval) != CONSTRUCTOR)
10377 : {
10378 : /* For the final reference to the entire accessed member
10379 : (SIZE is zero), reset OFFSET, disegard TYPE (which may
10380 : be null) in favor of the type of the member, and set
10381 : SIZE to the size of the accessed member. */
10382 21470 : offset = bitoffset.to_uhwi ();
10383 21470 : type = TREE_TYPE (cval);
10384 21470 : size = (bitoffset_end - bitoffset).to_uhwi ();
10385 : }
10386 :
10387 : /* We do have overlap. Now see if the field is large enough
10388 : to cover the access. Give up for accesses that extend
10389 : beyond the end of the object or that span multiple fields. */
10390 74299 : if (wi::cmps (access_end, bitoffset_end) > 0)
10391 : return NULL_TREE;
10392 73672 : if (offset < bitoffset)
10393 : return NULL_TREE;
10394 :
10395 73672 : offset_int inner_offset = offset_int (offset) - bitoffset;
10396 :
10397 : /* Integral bit-fields are left-justified on big-endian targets, so
10398 : we must arrange for native_encode_int to start at their MSB. */
10399 73672 : if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
10400 : {
10401 73672 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
10402 : return NULL_TREE;
10403 73672 : if (BYTES_BIG_ENDIAN)
10404 : {
10405 : tree ctype = TREE_TYPE (cfield);
10406 : unsigned int encoding_size;
10407 : if (TYPE_MODE (ctype) != BLKmode)
10408 : encoding_size
10409 : = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (ctype));
10410 : else
10411 : encoding_size = TREE_INT_CST_LOW (TYPE_SIZE (ctype));
10412 : inner_offset += encoding_size - wi::to_offset (field_size);
10413 : }
10414 : }
10415 :
10416 73672 : return fold_ctor_reference (type, cval,
10417 73672 : inner_offset.to_uhwi (), size,
10418 : from_decl, suboff);
10419 : }
10420 : }
10421 :
10422 8957 : if (!type)
10423 : return NULL_TREE;
10424 :
10425 8957 : return build_zero_cst (type);
10426 : }
10427 :
10428 : /* CTOR is a value initializing memory. Fold a reference of TYPE and
10429 : bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE
10430 : is zero, attempt to fold a reference to the entire subobject
10431 : which OFFSET refers to. This is used when folding accesses to
10432 : string members of aggregates. When non-null, set *SUBOFF to
10433 : the bit offset of the accessed subobject. */
10434 :
10435 : tree
10436 1626245 : fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
10437 : const poly_uint64 &poly_size, tree from_decl,
10438 : unsigned HOST_WIDE_INT *suboff /* = NULL */)
10439 : {
10440 1626245 : tree ret;
10441 :
10442 : /* We found the field with exact match. */
10443 1626245 : if (type
10444 1626245 : && useless_type_conversion_p (type, TREE_TYPE (ctor))
10445 2326869 : && known_eq (poly_offset, 0U))
10446 699358 : return canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10447 :
10448 : /* The remaining optimizations need a constant size and offset. */
10449 926887 : unsigned HOST_WIDE_INT size, offset;
10450 926887 : if (!poly_size.is_constant (&size) || !poly_offset.is_constant (&offset))
10451 : return NULL_TREE;
10452 :
10453 : /* We are at the end of walk, see if we can view convert the
10454 : result. */
10455 926887 : if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset
10456 : /* VIEW_CONVERT_EXPR is defined only for matching sizes. */
10457 23270 : && known_eq (wi::to_poly_widest (TYPE_SIZE (type)), size)
10458 23163 : && known_eq (wi::to_poly_widest (TYPE_SIZE (TREE_TYPE (ctor))), size))
10459 : {
10460 14462 : ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10461 14462 : if (ret)
10462 : {
10463 14462 : ret = fold_unary (VIEW_CONVERT_EXPR, type, ret);
10464 14462 : if (ret)
10465 14442 : STRIP_USELESS_TYPE_CONVERSION (ret);
10466 : }
10467 : return ret;
10468 : }
10469 :
10470 : /* For constants and byte-aligned/sized reads, try to go through
10471 : native_encode/interpret. */
10472 912425 : if (CONSTANT_CLASS_P (ctor)
10473 : && BITS_PER_UNIT == 8
10474 120525 : && offset % BITS_PER_UNIT == 0
10475 120521 : && offset / BITS_PER_UNIT <= INT_MAX
10476 120489 : && size % BITS_PER_UNIT == 0
10477 120480 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10478 1032607 : && can_native_interpret_type_p (type))
10479 : {
10480 104925 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10481 209850 : int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
10482 104925 : offset / BITS_PER_UNIT);
10483 104925 : if (len > 0)
10484 104209 : return native_interpret_expr (type, buf, len);
10485 : }
10486 :
10487 : /* For constructors, try first a recursive local processing, but in any case
10488 : this requires the native storage order. */
10489 808216 : if (TREE_CODE (ctor) == CONSTRUCTOR
10490 808216 : && !(AGGREGATE_TYPE_P (TREE_TYPE (ctor))
10491 783862 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (ctor))))
10492 : {
10493 783632 : unsigned HOST_WIDE_INT dummy = 0;
10494 783632 : if (!suboff)
10495 648667 : suboff = &dummy;
10496 :
10497 783632 : tree ret;
10498 783632 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE
10499 783632 : || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE)
10500 700376 : ret = fold_array_ctor_reference (type, ctor, offset, size,
10501 : from_decl, suboff);
10502 : else
10503 83256 : ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
10504 : from_decl, suboff);
10505 :
10506 : /* Otherwise fall back to native_encode_initializer. This may be done
10507 : only from the outermost fold_ctor_reference call (because it itself
10508 : recurses into CONSTRUCTORs and doesn't update suboff). */
10509 783632 : if (ret == NULL_TREE
10510 221046 : && suboff == &dummy
10511 : && BITS_PER_UNIT == 8
10512 212687 : && offset % BITS_PER_UNIT == 0
10513 212685 : && offset / BITS_PER_UNIT <= INT_MAX
10514 212685 : && size % BITS_PER_UNIT == 0
10515 212676 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10516 992335 : && can_native_interpret_type_p (type))
10517 : {
10518 195066 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10519 390132 : int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT,
10520 195066 : offset / BITS_PER_UNIT);
10521 195066 : if (len > 0)
10522 1302 : return native_interpret_expr (type, buf, len);
10523 : }
10524 :
10525 : return ret;
10526 : }
10527 :
10528 : return NULL_TREE;
10529 : }
10530 :
10531 : /* Return the tree representing the element referenced by T if T is an
10532 : ARRAY_REF or COMPONENT_REF into constant aggregates valuezing SSA
10533 : names using VALUEIZE. Return NULL_TREE otherwise. */
10534 :
10535 : tree
10536 132028628 : fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
10537 : {
10538 132028628 : tree ctor, idx, base;
10539 132028628 : poly_int64 offset, size, max_size;
10540 132028628 : tree tem;
10541 132028628 : bool reverse;
10542 :
10543 132028628 : if (TREE_THIS_VOLATILE (t))
10544 : return NULL_TREE;
10545 :
10546 131711664 : if (DECL_P (t))
10547 301656 : return get_symbol_constant_value (t);
10548 :
10549 131410008 : tem = fold_read_from_constant_string (t);
10550 131410008 : if (tem)
10551 : return tem;
10552 :
10553 131408166 : switch (TREE_CODE (t))
10554 : {
10555 10712573 : case ARRAY_REF:
10556 10712573 : case ARRAY_RANGE_REF:
10557 : /* Constant indexes are handled well by get_base_constructor.
10558 : Only special case variable offsets.
10559 : FIXME: This code can't handle nested references with variable indexes
10560 : (they will be handled only by iteration of ccp). Perhaps we can bring
10561 : get_ref_base_and_extent here and make it use a valueize callback. */
10562 10712573 : if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
10563 6239945 : && valueize
10564 4170097 : && (idx = (*valueize) (TREE_OPERAND (t, 1)))
10565 14882670 : && poly_int_tree_p (idx))
10566 : {
10567 1690476 : tree low_bound, unit_size;
10568 :
10569 : /* If the resulting bit-offset is constant, track it. */
10570 1690476 : if ((low_bound = array_ref_low_bound (t),
10571 1690476 : poly_int_tree_p (low_bound))
10572 1690476 : && (unit_size = array_ref_element_size (t),
10573 1690476 : tree_fits_uhwi_p (unit_size)))
10574 : {
10575 1690476 : poly_offset_int woffset
10576 1690476 : = wi::sext (wi::to_poly_offset (idx)
10577 3380952 : - wi::to_poly_offset (low_bound),
10578 1690476 : TYPE_PRECISION (sizetype));
10579 1690476 : woffset *= tree_to_uhwi (unit_size);
10580 1690476 : woffset *= BITS_PER_UNIT;
10581 1690476 : if (woffset.to_shwi (&offset))
10582 : {
10583 1690357 : base = TREE_OPERAND (t, 0);
10584 1690357 : ctor = get_base_constructor (base, &offset, valueize);
10585 : /* Empty constructor. Always fold to 0. */
10586 1690357 : if (ctor == error_mark_node)
10587 1690357 : return build_zero_cst (TREE_TYPE (t));
10588 : /* Out of bound array access. Value is undefined,
10589 : but don't fold. */
10590 1690280 : if (maybe_lt (offset, 0))
10591 : return NULL_TREE;
10592 : /* We cannot determine ctor. */
10593 1689861 : if (!ctor)
10594 : return NULL_TREE;
10595 176065 : return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
10596 176065 : tree_to_uhwi (unit_size)
10597 352130 : * BITS_PER_UNIT,
10598 : base);
10599 : }
10600 : }
10601 : }
10602 : /* Fallthru. */
10603 :
10604 124778754 : case COMPONENT_REF:
10605 124778754 : case BIT_FIELD_REF:
10606 124778754 : case TARGET_MEM_REF:
10607 124778754 : case MEM_REF:
10608 124778754 : base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
10609 124778754 : ctor = get_base_constructor (base, &offset, valueize);
10610 :
10611 : /* We cannot determine ctor. */
10612 124778754 : if (!ctor)
10613 : return NULL_TREE;
10614 : /* Empty constructor. Always fold to 0. */
10615 1209802 : if (ctor == error_mark_node)
10616 1097 : return build_zero_cst (TREE_TYPE (t));
10617 : /* We do not know precise access. */
10618 1208705 : if (!known_size_p (max_size) || maybe_ne (max_size, size))
10619 : return NULL_TREE;
10620 : /* Out of bound array access. Value is undefined, but don't fold. */
10621 509107 : if (maybe_lt (offset, 0))
10622 : return NULL_TREE;
10623 : /* Access with reverse storage order. */
10624 508726 : if (reverse)
10625 : return NULL_TREE;
10626 :
10627 508726 : tem = fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, base);
10628 508726 : if (tem)
10629 : return tem;
10630 :
10631 : /* For bit field reads try to read the representative and
10632 : adjust. */
10633 182197 : if (TREE_CODE (t) == COMPONENT_REF
10634 5149 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1))
10635 182281 : && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)))
10636 : {
10637 84 : HOST_WIDE_INT csize, coffset;
10638 84 : tree field = TREE_OPERAND (t, 1);
10639 84 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
10640 168 : if (INTEGRAL_TYPE_P (TREE_TYPE (repr))
10641 83 : && size.is_constant (&csize)
10642 83 : && offset.is_constant (&coffset)
10643 83 : && (coffset % BITS_PER_UNIT != 0
10644 81 : || csize % BITS_PER_UNIT != 0)
10645 84 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
10646 : {
10647 10 : poly_int64 bitoffset;
10648 10 : poly_uint64 field_offset, repr_offset;
10649 10 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
10650 20 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
10651 10 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
10652 : else
10653 : bitoffset = 0;
10654 10 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
10655 10 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
10656 10 : HOST_WIDE_INT bitoff;
10657 10 : int diff = (TYPE_PRECISION (TREE_TYPE (repr))
10658 10 : - TYPE_PRECISION (TREE_TYPE (field)));
10659 10 : if (bitoffset.is_constant (&bitoff)
10660 10 : && bitoff >= 0
10661 10 : && bitoff <= diff)
10662 : {
10663 10 : offset -= bitoff;
10664 10 : size = tree_to_uhwi (DECL_SIZE (repr));
10665 :
10666 20 : tem = fold_ctor_reference (TREE_TYPE (repr), ctor, offset,
10667 10 : size, base);
10668 10 : if (tem && TREE_CODE (tem) == INTEGER_CST)
10669 : {
10670 10 : if (!BYTES_BIG_ENDIAN)
10671 10 : tem = wide_int_to_tree (TREE_TYPE (field),
10672 10 : wi::lrshift (wi::to_wide (tem),
10673 : bitoff));
10674 : else
10675 : tem = wide_int_to_tree (TREE_TYPE (field),
10676 : wi::lrshift (wi::to_wide (tem),
10677 : diff - bitoff));
10678 10 : return tem;
10679 : }
10680 : }
10681 : }
10682 : }
10683 : break;
10684 :
10685 1816549 : case REALPART_EXPR:
10686 1816549 : case IMAGPART_EXPR:
10687 1816549 : {
10688 1816549 : tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize);
10689 1816549 : if (c && TREE_CODE (c) == COMPLEX_CST)
10690 2786 : return fold_build1_loc (EXPR_LOCATION (t),
10691 5572 : TREE_CODE (t), TREE_TYPE (t), c);
10692 : break;
10693 : }
10694 :
10695 : default:
10696 : break;
10697 : }
10698 :
10699 : return NULL_TREE;
10700 : }
10701 :
10702 : tree
10703 63694746 : fold_const_aggregate_ref (tree t)
10704 : {
10705 63694746 : return fold_const_aggregate_ref_1 (t, NULL);
10706 : }
10707 :
10708 : /* Lookup virtual method with index TOKEN in a virtual table V
10709 : at OFFSET.
10710 : Set CAN_REFER if non-NULL to false if method
10711 : is not referable or if the virtual table is ill-formed (such as rewritten
10712 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10713 :
10714 : tree
10715 285688 : gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
10716 : tree v,
10717 : unsigned HOST_WIDE_INT offset,
10718 : bool *can_refer)
10719 : {
10720 285688 : tree vtable = v, init, fn;
10721 285688 : unsigned HOST_WIDE_INT size;
10722 285688 : unsigned HOST_WIDE_INT elt_size, access_index;
10723 285688 : tree domain_type;
10724 :
10725 285688 : if (can_refer)
10726 285688 : *can_refer = true;
10727 :
10728 : /* First of all double check we have virtual table. */
10729 285688 : if (!VAR_P (v) || !DECL_VIRTUAL_P (v))
10730 : {
10731 : /* Pass down that we lost track of the target. */
10732 0 : if (can_refer)
10733 0 : *can_refer = false;
10734 : return NULL_TREE;
10735 : }
10736 :
10737 285688 : init = ctor_for_folding (v);
10738 :
10739 : /* The virtual tables should always be born with constructors
10740 : and we always should assume that they are available for
10741 : folding. At the moment we do not stream them in all cases,
10742 : but it should never happen that ctor seem unreachable. */
10743 285688 : gcc_assert (init);
10744 285688 : if (init == error_mark_node)
10745 : {
10746 : /* Pass down that we lost track of the target. */
10747 213 : if (can_refer)
10748 213 : *can_refer = false;
10749 : return NULL_TREE;
10750 : }
10751 285475 : gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
10752 285475 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))));
10753 285475 : offset *= BITS_PER_UNIT;
10754 285475 : offset += token * size;
10755 :
10756 : /* Lookup the value in the constructor that is assumed to be array.
10757 : This is equivalent to
10758 : fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
10759 : offset, size, NULL);
10760 : but in a constant time. We expect that frontend produced a simple
10761 : array without indexed initializers. */
10762 :
10763 285475 : gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
10764 285475 : domain_type = TYPE_DOMAIN (TREE_TYPE (init));
10765 285475 : gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
10766 285475 : elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
10767 :
10768 285475 : access_index = offset / BITS_PER_UNIT / elt_size;
10769 285475 : gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);
10770 :
10771 : /* This code makes an assumption that there are no
10772 : indexed fields produced by C++ FE, so we can directly index the array. */
10773 285475 : if (access_index < CONSTRUCTOR_NELTS (init))
10774 : {
10775 285474 : fn = CONSTRUCTOR_ELT (init, access_index)->value;
10776 285474 : gcc_checking_assert (!CONSTRUCTOR_ELT (init, access_index)->index);
10777 285474 : STRIP_NOPS (fn);
10778 : }
10779 : else
10780 : fn = NULL;
10781 :
10782 : /* For type inconsistent program we may end up looking up virtual method
10783 : in virtual table that does not contain TOKEN entries. We may overrun
10784 : the virtual table and pick up a constant or RTTI info pointer.
10785 : In any case the call is undefined. */
10786 285474 : if (!fn
10787 285474 : || (TREE_CODE (fn) != ADDR_EXPR && TREE_CODE (fn) != FDESC_EXPR)
10788 565151 : || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
10789 5798 : fn = builtin_decl_unreachable ();
10790 : else
10791 : {
10792 279677 : fn = TREE_OPERAND (fn, 0);
10793 :
10794 : /* When cgraph node is missing and function is not public, we cannot
10795 : devirtualize. This can happen in WHOPR when the actual method
10796 : ends up in other partition, because we found devirtualization
10797 : possibility too late. */
10798 279677 : if (!can_refer_decl_in_current_unit_p (fn, vtable))
10799 : {
10800 36954 : if (can_refer)
10801 : {
10802 36954 : *can_refer = false;
10803 36954 : return fn;
10804 : }
10805 : return NULL_TREE;
10806 : }
10807 : }
10808 :
10809 : /* Make sure we create a cgraph node for functions we'll reference.
10810 : They can be non-existent if the reference comes from an entry
10811 : of an external vtable for example. */
10812 248521 : cgraph_node::get_create (fn);
10813 :
10814 248521 : return fn;
10815 : }
10816 :
10817 : /* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
10818 : is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
10819 : KNOWN_BINFO carries the binfo describing the true type of
10820 : OBJ_TYPE_REF_OBJECT(REF).
10821 : Set CAN_REFER if non-NULL to false if method
10822 : is not referable or if the virtual table is ill-formed (such as rewritten
10823 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10824 :
10825 : tree
10826 276744 : gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
10827 : bool *can_refer)
10828 : {
10829 276744 : unsigned HOST_WIDE_INT offset;
10830 276744 : tree v;
10831 :
10832 276744 : v = BINFO_VTABLE (known_binfo);
10833 : /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone. */
10834 276744 : if (!v)
10835 : return NULL_TREE;
10836 :
10837 276744 : if (!vtable_pointer_value_to_vtable (v, &v, &offset))
10838 : {
10839 0 : if (can_refer)
10840 0 : *can_refer = false;
10841 : return NULL_TREE;
10842 : }
10843 276744 : return gimple_get_virt_method_for_vtable (token, v, offset, can_refer);
10844 : }
10845 :
10846 : /* Given a pointer value T, return a simplified version of an
10847 : indirection through T, or NULL_TREE if no simplification is
10848 : possible. Note that the resulting type may be different from
10849 : the type pointed to in the sense that it is still compatible
10850 : from the langhooks point of view. */
10851 :
10852 : tree
10853 2550320 : gimple_fold_indirect_ref (tree t)
10854 : {
10855 2550320 : tree ptype = TREE_TYPE (t), type = TREE_TYPE (ptype);
10856 2550320 : tree sub = t;
10857 2550320 : tree subtype;
10858 :
10859 2550320 : STRIP_NOPS (sub);
10860 2550320 : subtype = TREE_TYPE (sub);
10861 2550320 : if (!POINTER_TYPE_P (subtype)
10862 2550320 : || TYPE_REF_CAN_ALIAS_ALL (ptype))
10863 : return NULL_TREE;
10864 :
10865 2548611 : if (TREE_CODE (sub) == ADDR_EXPR)
10866 : {
10867 97635 : tree op = TREE_OPERAND (sub, 0);
10868 97635 : tree optype = TREE_TYPE (op);
10869 : /* *&p => p */
10870 97635 : if (useless_type_conversion_p (type, optype))
10871 : return op;
10872 :
10873 : /* *(foo *)&fooarray => fooarray[0] */
10874 1021 : if (TREE_CODE (optype) == ARRAY_TYPE
10875 335 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
10876 1356 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10877 : {
10878 54 : tree type_domain = TYPE_DOMAIN (optype);
10879 54 : tree min_val = size_zero_node;
10880 54 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10881 54 : min_val = TYPE_MIN_VALUE (type_domain);
10882 54 : if (TREE_CODE (min_val) == INTEGER_CST)
10883 54 : return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
10884 : }
10885 : /* *(foo *)&complexfoo => __real__ complexfoo */
10886 967 : else if (TREE_CODE (optype) == COMPLEX_TYPE
10887 967 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10888 4 : return fold_build1 (REALPART_EXPR, type, op);
10889 : /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
10890 963 : else if (TREE_CODE (optype) == VECTOR_TYPE
10891 963 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10892 : {
10893 26 : tree part_width = TYPE_SIZE (type);
10894 26 : tree index = bitsize_int (0);
10895 26 : return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
10896 : }
10897 : }
10898 :
10899 : /* *(p + CST) -> ... */
10900 2451913 : if (TREE_CODE (sub) == POINTER_PLUS_EXPR
10901 2451913 : && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
10902 : {
10903 34249 : tree addr = TREE_OPERAND (sub, 0);
10904 34249 : tree off = TREE_OPERAND (sub, 1);
10905 34249 : tree addrtype;
10906 :
10907 34249 : STRIP_NOPS (addr);
10908 34249 : addrtype = TREE_TYPE (addr);
10909 :
10910 : /* ((foo*)&vectorfoo)[1] -> BIT_FIELD_REF<vectorfoo,...> */
10911 34249 : if (TREE_CODE (addr) == ADDR_EXPR
10912 92 : && TREE_CODE (TREE_TYPE (addrtype)) == VECTOR_TYPE
10913 39 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype)))
10914 34277 : && tree_fits_uhwi_p (off))
10915 : {
10916 28 : unsigned HOST_WIDE_INT offset = tree_to_uhwi (off);
10917 28 : tree part_width = TYPE_SIZE (type);
10918 28 : unsigned HOST_WIDE_INT part_widthi
10919 28 : = tree_to_shwi (part_width) / BITS_PER_UNIT;
10920 28 : unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
10921 28 : tree index = bitsize_int (indexi);
10922 28 : if (known_lt (offset / part_widthi,
10923 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
10924 28 : return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
10925 : part_width, index);
10926 : }
10927 :
10928 : /* ((foo*)&complexfoo)[1] -> __imag__ complexfoo */
10929 34221 : if (TREE_CODE (addr) == ADDR_EXPR
10930 64 : && TREE_CODE (TREE_TYPE (addrtype)) == COMPLEX_TYPE
10931 34222 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype))))
10932 : {
10933 1 : tree size = TYPE_SIZE_UNIT (type);
10934 1 : if (tree_int_cst_equal (size, off))
10935 1 : return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (addr, 0));
10936 : }
10937 :
10938 : /* *(p + CST) -> MEM_REF <p, CST>. */
10939 34220 : if (TREE_CODE (addr) != ADDR_EXPR
10940 34220 : || DECL_P (TREE_OPERAND (addr, 0)))
10941 34202 : return fold_build2 (MEM_REF, type,
10942 : addr,
10943 : wide_int_to_tree (ptype, wi::to_wide (off)));
10944 : }
10945 :
10946 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
10947 2417682 : if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
10948 2535 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
10949 2420187 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
10950 : {
10951 1 : tree type_domain;
10952 1 : tree min_val = size_zero_node;
10953 1 : tree osub = sub;
10954 1 : sub = gimple_fold_indirect_ref (sub);
10955 1 : if (! sub)
10956 1 : sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
10957 1 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
10958 1 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10959 1 : min_val = TYPE_MIN_VALUE (type_domain);
10960 1 : if (TREE_CODE (min_val) == INTEGER_CST)
10961 1 : return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
10962 : }
10963 :
10964 : return NULL_TREE;
10965 : }
10966 :
10967 : /* Return true if CODE is an operation that when operating on signed
10968 : integer types involves undefined behavior on overflow and the
10969 : operation can be expressed with unsigned arithmetic. */
10970 :
10971 : bool
10972 620884 : arith_code_with_undefined_signed_overflow (tree_code code)
10973 : {
10974 620884 : switch (code)
10975 : {
10976 : case ABS_EXPR:
10977 : case PLUS_EXPR:
10978 : case MINUS_EXPR:
10979 : case MULT_EXPR:
10980 : case NEGATE_EXPR:
10981 : case POINTER_PLUS_EXPR:
10982 : return true;
10983 277100 : default:
10984 277100 : return false;
10985 : }
10986 : }
10987 :
10988 : /* Return true if STMT has an operation that operates on a signed
10989 : integer types involves undefined behavior on overflow and the
10990 : operation can be expressed with unsigned arithmetic.
10991 : Also returns true if STMT is a VCE that needs to be rewritten
10992 : if moved to be executed unconditionally.
10993 : SHIFT_COUNT additionally asks for a shift or rotate whose count may be
10994 : out of range; rewrite_to_defined_unconditional reduces such a count. */
10995 :
10996 : bool
10997 1625611 : gimple_needing_rewrite_undefined (gimple *stmt, bool shift_count)
10998 : {
10999 1625611 : if (!is_gimple_assign (stmt))
11000 : return false;
11001 1382745 : tree lhs = gimple_assign_lhs (stmt);
11002 1382745 : if (!lhs)
11003 : return false;
11004 1382745 : tree lhs_type = TREE_TYPE (lhs);
11005 1382745 : if (!INTEGRAL_TYPE_P (lhs_type)
11006 158982 : && !POINTER_TYPE_P (lhs_type))
11007 : return false;
11008 1335256 : tree rhs = gimple_assign_rhs1 (stmt);
11009 : /* Boolean loads need special handling as they are treated as a full MODE load
11010 : and don't mask off the bits for the precision. */
11011 1335256 : if (gimple_assign_load_p (stmt)
11012 : /* Booleans are the integral type which has this non-masking issue. */
11013 168251 : && TREE_CODE (lhs_type) == BOOLEAN_TYPE
11014 : /* Only non mode precision booleans are need the masking. */
11015 587 : && !type_has_mode_precision_p (lhs_type)
11016 : /* BFR should be the correct thing and just grab the precision. */
11017 587 : && TREE_CODE (rhs) != BIT_FIELD_REF
11018 : /* Bit-fields loads don't need a rewrite as the masking
11019 : happens for them. */
11020 1335843 : && (TREE_CODE (rhs) != COMPONENT_REF
11021 199 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1))))
11022 : return true;
11023 : /* VCE from integral types to a integral types but with
11024 : a smaller precision need to be changed into casts
11025 : to be well defined. */
11026 1334669 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
11027 202 : && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
11028 173 : && is_gimple_val (TREE_OPERAND (rhs, 0))
11029 1334842 : && TYPE_PRECISION (lhs_type)
11030 173 : < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
11031 : return true;
11032 : /* A shift or rotate by a count that may be out of range; the count can
11033 : be reduced into range. */
11034 1334502 : enum tree_code code = gimple_assign_rhs_code (stmt);
11035 1334502 : if (shift_count
11036 798845 : && (code == LSHIFT_EXPR
11037 : || code == RSHIFT_EXPR
11038 : || code == LROTATE_EXPR
11039 798845 : || code == RROTATE_EXPR)
11040 59574 : && INTEGRAL_TYPE_P (lhs_type)
11041 1394076 : && (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
11042 59574 : || wi::geu_p (wi::to_wide (gimple_assign_rhs2 (stmt)),
11043 16470 : TYPE_PRECISION (lhs_type))))
11044 : return true;
11045 1291394 : if (!TYPE_OVERFLOW_UNDEFINED (lhs_type))
11046 : return false;
11047 494480 : if (!arith_code_with_undefined_signed_overflow (code))
11048 : return false;
11049 : return true;
11050 : }
11051 :
11052 : /* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
11053 : operation that can be transformed to unsigned arithmetic by converting
11054 : its operand, carrying out the operation in the corresponding unsigned
11055 : type and converting the result back to the original type.
11056 :
11057 : If IN_PLACE is true, *GSI points to STMT, adjust the stmt in place and
11058 : return NULL.
11059 : Otherwise returns a sequence of statements that replace STMT and also
11060 : contain a modified form of STMT itself. */
11061 :
11062 : static gimple_seq
11063 69030 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi, gimple *stmt,
11064 : bool in_place)
11065 : {
11066 69030 : gcc_assert (gimple_needing_rewrite_undefined (stmt, true));
11067 69030 : if (dump_file && (dump_flags & TDF_DETAILS))
11068 : {
11069 59 : fprintf (dump_file, "rewriting stmt for being unconditional defined");
11070 59 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
11071 : }
11072 69030 : gimple_seq stmts = NULL;
11073 69030 : tree lhs = gimple_assign_lhs (stmt);
11074 :
11075 : /* Boolean loads need to be rewritten to be a load from the same mode
11076 : and then a cast to the other type so the other bits are masked off
11077 : correctly since the load was done conditionally. It is similar to the VCE
11078 : case below. */
11079 69030 : if (gimple_assign_load_p (stmt)
11080 69030 : && TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
11081 : {
11082 135 : tree rhs = gimple_assign_rhs1 (stmt);
11083 :
11084 : /* Double check that gimple_needing_rewrite_undefined was called. */
11085 : /* Bit-fields loads will do the masking so don't need the rewriting. */
11086 135 : gcc_assert (TREE_CODE (rhs) != COMPONENT_REF
11087 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1)));
11088 : /* BFR is like a bit field load and will do the correct thing. */
11089 135 : gcc_assert (TREE_CODE (lhs) != BIT_FIELD_REF);
11090 : /* Complex boolean types are not valid so REAL/IMAG part will
11091 : never show up. */
11092 135 : gcc_assert (TREE_CODE (rhs) != REALPART_EXPR
11093 : && TREE_CODE (lhs) != IMAGPART_EXPR);
11094 :
11095 135 : auto bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (rhs)));
11096 135 : tree new_type = build_nonstandard_integer_type (bits, true);
11097 135 : location_t loc = gimple_location (stmt);
11098 135 : tree mem_ref = fold_build1_loc (loc, VIEW_CONVERT_EXPR, new_type, rhs);
11099 : /* Replace the original load with a new load and a new lhs. */
11100 135 : tree new_lhs = make_ssa_name (new_type);
11101 135 : gimple_assign_set_rhs1 (stmt, mem_ref);
11102 135 : gimple_assign_set_lhs (stmt, new_lhs);
11103 :
11104 135 : if (in_place)
11105 49 : update_stmt (stmt);
11106 : else
11107 : {
11108 86 : gimple_set_modified (stmt, true);
11109 86 : gimple_seq_add_stmt (&stmts, stmt);
11110 : }
11111 :
11112 : /* Build the conversion statement. */
11113 135 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
11114 135 : if (in_place)
11115 : {
11116 49 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11117 49 : update_stmt (stmt);
11118 : }
11119 : else
11120 86 : gimple_seq_add_stmt (&stmts, cvt);
11121 135 : return stmts;
11122 : }
11123 :
11124 : /* VCE from integral types to another integral types but with
11125 : smaller precisions need to be changed into casts
11126 : to be well defined. */
11127 68895 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
11128 : {
11129 60 : tree rhs = gimple_assign_rhs1 (stmt);
11130 60 : tree new_rhs = TREE_OPERAND (rhs, 0);
11131 60 : gcc_assert (TYPE_PRECISION (TREE_TYPE (rhs))
11132 : < TYPE_PRECISION (TREE_TYPE (new_rhs)));
11133 60 : gcc_assert (is_gimple_val (new_rhs));
11134 60 : gimple_assign_set_rhs_code (stmt, NOP_EXPR);
11135 60 : gimple_assign_set_rhs1 (stmt, new_rhs);
11136 60 : if (in_place)
11137 51 : update_stmt (stmt);
11138 : else
11139 : {
11140 9 : gimple_set_modified (stmt, true);
11141 9 : gimple_seq_add_stmt (&stmts, stmt);
11142 : }
11143 60 : return stmts;
11144 : }
11145 : /* Reduce a shift or rotate count into range. The mask keeps the count's
11146 : own type where that holds PREC - 1, so that a SHIFT_COUNT_TRUNCATED
11147 : target folds it away; MIN needs an unsigned count so a negative one
11148 : clamps. */
11149 68835 : enum tree_code code = gimple_assign_rhs_code (stmt);
11150 68835 : if (code == LSHIFT_EXPR
11151 : || code == RSHIFT_EXPR
11152 : || code == LROTATE_EXPR
11153 68835 : || code == RROTATE_EXPR)
11154 : {
11155 141 : unsigned prec = TYPE_PRECISION (TREE_TYPE (lhs));
11156 141 : bool pow2 = pow2p_hwi (prec);
11157 141 : tree count = gimple_assign_rhs2 (stmt);
11158 141 : tree type = TREE_TYPE (count);
11159 281 : if (!pow2 || wi::ltu_p (wi::max_value (type), prec - 1))
11160 1 : type = unsigned_type_node;
11161 141 : count = gimple_convert (&stmts, type, count);
11162 142 : count = gimple_build (&stmts, pow2 ? BIT_AND_EXPR : MIN_EXPR, type,
11163 141 : count, build_int_cst (type, prec - 1));
11164 141 : gimple_assign_set_rhs2 (stmt, count);
11165 141 : gimple_set_modified (stmt, true);
11166 141 : if (in_place)
11167 : {
11168 0 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
11169 0 : update_stmt (stmt);
11170 0 : return NULL;
11171 : }
11172 141 : gimple_seq_add_stmt (&stmts, stmt);
11173 141 : return stmts;
11174 : }
11175 68694 : tree type = unsigned_type_for (TREE_TYPE (lhs));
11176 68694 : if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
11177 21 : gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
11178 : else
11179 205489 : for (unsigned i = 1; i < gimple_num_ops (stmt); ++i)
11180 : {
11181 136816 : tree op = gimple_op (stmt, i);
11182 136816 : op = gimple_convert (&stmts, type, op);
11183 136816 : gimple_set_op (stmt, i, op);
11184 : }
11185 68694 : gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
11186 68694 : if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
11187 9421 : gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
11188 68694 : gimple_set_modified (stmt, true);
11189 68694 : if (in_place)
11190 : {
11191 48444 : if (stmts)
11192 48182 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
11193 48444 : stmts = NULL;
11194 : }
11195 : else
11196 20250 : gimple_seq_add_stmt (&stmts, stmt);
11197 68694 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
11198 68694 : if (in_place)
11199 : {
11200 48444 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11201 48444 : update_stmt (stmt);
11202 : }
11203 : else
11204 20250 : gimple_seq_add_stmt (&stmts, cvt);
11205 :
11206 68694 : return stmts;
11207 : }
11208 :
11209 : void
11210 48544 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi)
11211 : {
11212 48544 : rewrite_to_defined_unconditional (gsi, gsi_stmt (*gsi), true);
11213 48544 : }
11214 :
11215 : gimple_seq
11216 20486 : rewrite_to_defined_unconditional (gimple *stmt)
11217 : {
11218 20486 : return rewrite_to_defined_unconditional (nullptr, stmt, false);
11219 : }
11220 :
11221 : /* The valueization hook we use for the gimple_build API simplification.
11222 : This makes us match fold_buildN behavior by only combining with
11223 : statements in the sequence(s) we are currently building. */
11224 :
11225 : static tree
11226 22372743 : gimple_build_valueize (tree op)
11227 : {
11228 22372743 : if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL)
11229 4991253 : return op;
11230 : return NULL_TREE;
11231 : }
11232 :
11233 : /* Helper for gimple_build to perform the final insertion of stmts on SEQ. */
11234 :
11235 : static inline void
11236 1404762 : gimple_build_insert_seq (gimple_stmt_iterator *gsi,
11237 : bool before, gsi_iterator_update update,
11238 : gimple_seq seq)
11239 : {
11240 1404762 : if (before)
11241 : {
11242 96465 : if (gsi->bb)
11243 96465 : gsi_insert_seq_before (gsi, seq, update);
11244 : else
11245 0 : gsi_insert_seq_before_without_update (gsi, seq, update);
11246 : }
11247 : else
11248 : {
11249 1308297 : if (gsi->bb)
11250 187 : gsi_insert_seq_after (gsi, seq, update);
11251 : else
11252 1308110 : gsi_insert_seq_after_without_update (gsi, seq, update);
11253 : }
11254 1404762 : }
11255 :
11256 : /* Build the expression CODE OP0 of type TYPE with location LOC,
11257 : simplifying it first if possible. Returns the built
11258 : expression value and inserts statements possibly defining it
11259 : before GSI if BEFORE is true or after GSI if false and advance
11260 : the iterator accordingly.
11261 : If gsi refers to a basic block simplifying is allowed to look
11262 : at all SSA defs while when it does not it is restricted to
11263 : SSA defs that are not associated with a basic block yet,
11264 : indicating they belong to the currently building sequence. */
11265 :
11266 : tree
11267 363193 : gimple_build (gimple_stmt_iterator *gsi,
11268 : bool before, gsi_iterator_update update,
11269 : location_t loc, enum tree_code code, tree type, tree op0)
11270 : {
11271 363193 : gimple_seq seq = NULL;
11272 363193 : tree res
11273 363193 : = gimple_simplify (code, type, op0, &seq,
11274 363193 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11275 363193 : if (!res)
11276 : {
11277 311517 : res = make_ssa_name (type);
11278 311517 : gimple *stmt;
11279 311517 : if (code == REALPART_EXPR
11280 : || code == IMAGPART_EXPR
11281 311517 : || code == VIEW_CONVERT_EXPR)
11282 11665 : stmt = gimple_build_assign (res, code, build1 (code, type, op0));
11283 : else
11284 299852 : stmt = gimple_build_assign (res, code, op0);
11285 311517 : gimple_set_location (stmt, loc);
11286 311517 : gimple_seq_add_stmt_without_update (&seq, stmt);
11287 : }
11288 363193 : gimple_build_insert_seq (gsi, before, update, seq);
11289 363193 : return res;
11290 : }
11291 :
11292 : /* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
11293 : simplifying it first if possible. Returns the built
11294 : expression value inserting any new statements at GSI honoring BEFORE
11295 : and UPDATE. */
11296 :
11297 : tree
11298 827768 : gimple_build (gimple_stmt_iterator *gsi,
11299 : bool before, gsi_iterator_update update,
11300 : location_t loc, enum tree_code code, tree type,
11301 : tree op0, tree op1)
11302 : {
11303 827768 : gimple_seq seq = NULL;
11304 827768 : tree res
11305 827768 : = gimple_simplify (code, type, op0, op1, &seq,
11306 827768 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11307 827768 : if (!res)
11308 : {
11309 731562 : res = make_ssa_name (type);
11310 731562 : gimple *stmt = gimple_build_assign (res, code, op0, op1);
11311 731562 : gimple_set_location (stmt, loc);
11312 731562 : gimple_seq_add_stmt_without_update (&seq, stmt);
11313 : }
11314 827768 : gimple_build_insert_seq (gsi, before, update, seq);
11315 827768 : return res;
11316 : }
11317 :
11318 : /* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
11319 : simplifying it first if possible. Returns the built
11320 : expression value inserting any new statements at GSI honoring BEFORE
11321 : and UPDATE. */
11322 :
11323 : tree
11324 47913 : gimple_build (gimple_stmt_iterator *gsi,
11325 : bool before, gsi_iterator_update update,
11326 : location_t loc, enum tree_code code, tree type,
11327 : tree op0, tree op1, tree op2)
11328 : {
11329 :
11330 47913 : gimple_seq seq = NULL;
11331 47913 : tree res
11332 47913 : = gimple_simplify (code, type, op0, op1, op2, &seq,
11333 47913 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11334 47913 : if (!res)
11335 : {
11336 34142 : res = make_ssa_name (type);
11337 34142 : gimple *stmt;
11338 34142 : if (code == BIT_FIELD_REF)
11339 26655 : stmt = gimple_build_assign (res, code,
11340 : build3 (code, type, op0, op1, op2));
11341 : else
11342 7487 : stmt = gimple_build_assign (res, code, op0, op1, op2);
11343 34142 : gimple_set_location (stmt, loc);
11344 34142 : gimple_seq_add_stmt_without_update (&seq, stmt);
11345 : }
11346 47913 : gimple_build_insert_seq (gsi, before, update, seq);
11347 47913 : return res;
11348 : }
11349 :
11350 : /* Build the call FN () with a result of type TYPE (or no result if TYPE is
11351 : void) with a location LOC. Returns the built expression value (or NULL_TREE
11352 : if TYPE is void) inserting any new statements at GSI honoring BEFORE
11353 : and UPDATE. */
11354 :
11355 : tree
11356 0 : gimple_build (gimple_stmt_iterator *gsi,
11357 : bool before, gsi_iterator_update update,
11358 : location_t loc, combined_fn fn, tree type)
11359 : {
11360 0 : tree res = NULL_TREE;
11361 0 : gimple_seq seq = NULL;
11362 0 : gcall *stmt;
11363 0 : if (internal_fn_p (fn))
11364 0 : stmt = gimple_build_call_internal (as_internal_fn (fn), 0);
11365 : else
11366 : {
11367 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11368 0 : stmt = gimple_build_call (decl, 0);
11369 : }
11370 0 : if (!VOID_TYPE_P (type))
11371 : {
11372 0 : res = make_ssa_name (type);
11373 0 : gimple_call_set_lhs (stmt, res);
11374 : }
11375 0 : gimple_set_location (stmt, loc);
11376 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11377 0 : gimple_build_insert_seq (gsi, before, update, seq);
11378 0 : return res;
11379 : }
11380 :
11381 : /* Build the call FN (ARG0) 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 21705 : 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)
11392 : {
11393 21705 : gimple_seq seq = NULL;
11394 21705 : tree res = gimple_simplify (fn, type, arg0, &seq, gimple_build_valueize);
11395 21705 : if (!res)
11396 : {
11397 21705 : gcall *stmt;
11398 21705 : if (internal_fn_p (fn))
11399 21321 : stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
11400 : else
11401 : {
11402 384 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11403 384 : stmt = gimple_build_call (decl, 1, arg0);
11404 : }
11405 21705 : if (!VOID_TYPE_P (type))
11406 : {
11407 21321 : res = make_ssa_name (type);
11408 21321 : gimple_call_set_lhs (stmt, res);
11409 : }
11410 21705 : gimple_set_location (stmt, loc);
11411 21705 : gimple_seq_add_stmt_without_update (&seq, stmt);
11412 : }
11413 21705 : gimple_build_insert_seq (gsi, before, update, seq);
11414 21705 : return res;
11415 : }
11416 :
11417 : /* Build the call FN (ARG0, ARG1) with a result of type TYPE
11418 : (or no result if TYPE is void) with location LOC,
11419 : simplifying it first if possible. Returns the built
11420 : expression value (or NULL_TREE if TYPE is void) inserting any new
11421 : statements at GSI honoring BEFORE and UPDATE. */
11422 :
11423 : tree
11424 138 : gimple_build (gimple_stmt_iterator *gsi,
11425 : bool before, gsi_iterator_update update,
11426 : location_t loc, combined_fn fn,
11427 : tree type, tree arg0, tree arg1)
11428 : {
11429 138 : gimple_seq seq = NULL;
11430 138 : tree res = gimple_simplify (fn, type, arg0, arg1, &seq,
11431 : gimple_build_valueize);
11432 138 : if (!res)
11433 : {
11434 138 : gcall *stmt;
11435 138 : if (internal_fn_p (fn))
11436 138 : stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
11437 : else
11438 : {
11439 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11440 0 : stmt = gimple_build_call (decl, 2, arg0, arg1);
11441 : }
11442 138 : if (!VOID_TYPE_P (type))
11443 : {
11444 138 : res = make_ssa_name (type);
11445 138 : gimple_call_set_lhs (stmt, res);
11446 : }
11447 138 : gimple_set_location (stmt, loc);
11448 138 : gimple_seq_add_stmt_without_update (&seq, stmt);
11449 : }
11450 138 : gimple_build_insert_seq (gsi, before, update, seq);
11451 138 : return res;
11452 : }
11453 :
11454 : /* Build the call FN (ARG0, ARG1, ARG2) with a result of type TYPE
11455 : (or no result if TYPE is void) with location LOC,
11456 : simplifying it first if possible. Returns the built
11457 : expression value (or NULL_TREE if TYPE is void) inserting any new
11458 : statements at GSI honoring BEFORE and UPDATE. */
11459 :
11460 : tree
11461 0 : gimple_build (gimple_stmt_iterator *gsi,
11462 : bool before, gsi_iterator_update update,
11463 : location_t loc, combined_fn fn,
11464 : tree type, tree arg0, tree arg1, tree arg2)
11465 : {
11466 0 : gimple_seq seq = NULL;
11467 0 : tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
11468 : &seq, gimple_build_valueize);
11469 0 : if (!res)
11470 : {
11471 0 : gcall *stmt;
11472 0 : if (internal_fn_p (fn))
11473 0 : stmt = gimple_build_call_internal (as_internal_fn (fn),
11474 : 3, arg0, arg1, arg2);
11475 : else
11476 : {
11477 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11478 0 : stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
11479 : }
11480 0 : if (!VOID_TYPE_P (type))
11481 : {
11482 0 : res = make_ssa_name (type);
11483 0 : gimple_call_set_lhs (stmt, res);
11484 : }
11485 0 : gimple_set_location (stmt, loc);
11486 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11487 : }
11488 0 : gimple_build_insert_seq (gsi, before, update, seq);
11489 0 : return res;
11490 : }
11491 :
11492 : /* Build CODE (OP0) with a result of type TYPE (or no result if TYPE is
11493 : void) with location LOC, simplifying it first if possible. Returns the
11494 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11495 : statements at GSI honoring BEFORE and UPDATE. */
11496 :
11497 : tree
11498 21 : gimple_build (gimple_stmt_iterator *gsi,
11499 : bool before, gsi_iterator_update update,
11500 : location_t loc, code_helper code, tree type, tree op0)
11501 : {
11502 21 : if (code.is_tree_code ())
11503 0 : return gimple_build (gsi, before, update, loc, tree_code (code), type, op0);
11504 21 : return gimple_build (gsi, before, update, loc, combined_fn (code), type, op0);
11505 : }
11506 :
11507 : /* Build CODE (OP0, OP1) with a result of type TYPE (or no result if TYPE is
11508 : void) with location LOC, simplifying it first if possible. Returns the
11509 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11510 : statements at GSI honoring BEFORE and UPDATE. */
11511 :
11512 : tree
11513 23800 : gimple_build (gimple_stmt_iterator *gsi,
11514 : bool before, gsi_iterator_update update,
11515 : location_t loc, code_helper code, tree type, tree op0, tree op1)
11516 : {
11517 23800 : if (code.is_tree_code ())
11518 23662 : return gimple_build (gsi, before, update,
11519 23662 : loc, tree_code (code), type, op0, op1);
11520 138 : return gimple_build (gsi, before, update,
11521 138 : loc, combined_fn (code), type, op0, op1);
11522 : }
11523 :
11524 : /* Build CODE (OP0, OP1, OP2) with a result of type TYPE (or no result if TYPE
11525 : is void) with location LOC, simplifying it first if possible. Returns the
11526 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11527 : statements at GSI honoring BEFORE and UPDATE. */
11528 :
11529 : tree
11530 0 : gimple_build (gimple_stmt_iterator *gsi,
11531 : bool before, gsi_iterator_update update,
11532 : location_t loc, code_helper code,
11533 : tree type, tree op0, tree op1, tree op2)
11534 : {
11535 0 : if (code.is_tree_code ())
11536 0 : return gimple_build (gsi, before, update,
11537 0 : loc, tree_code (code), type, op0, op1, op2);
11538 0 : return gimple_build (gsi, before, update,
11539 0 : loc, combined_fn (code), type, op0, op1, op2);
11540 : }
11541 :
11542 : /* Build the conversion (TYPE) OP with a result of type TYPE
11543 : with location LOC if such conversion is necessary in GIMPLE,
11544 : simplifying it first.
11545 : Returns the built expression inserting any new statements
11546 : at GSI honoring BEFORE and UPDATE. */
11547 :
11548 : tree
11549 2077822 : gimple_convert (gimple_stmt_iterator *gsi,
11550 : bool before, gsi_iterator_update update,
11551 : location_t loc, tree type, tree op)
11552 : {
11553 2077822 : if (useless_type_conversion_p (type, TREE_TYPE (op)))
11554 : return op;
11555 184751 : return gimple_build (gsi, before, update, loc, NOP_EXPR, type, op);
11556 : }
11557 :
11558 : /* Build the conversion (ptrofftype) OP with a result of a type
11559 : compatible with ptrofftype with location LOC if such conversion
11560 : is necessary in GIMPLE, simplifying it first.
11561 : Returns the built expression value inserting any new statements
11562 : at GSI honoring BEFORE and UPDATE. */
11563 :
11564 : tree
11565 210 : gimple_convert_to_ptrofftype (gimple_stmt_iterator *gsi,
11566 : bool before, gsi_iterator_update update,
11567 : location_t loc, tree op)
11568 : {
11569 210 : if (ptrofftype_p (TREE_TYPE (op)))
11570 : return op;
11571 0 : return gimple_convert (gsi, before, update, loc, sizetype, op);
11572 : }
11573 :
11574 : /* Build a vector of type TYPE in which each element has the value OP.
11575 : Return a gimple value for the result, inserting any new statements
11576 : at GSI honoring BEFORE and UPDATE. */
11577 :
11578 : tree
11579 333185 : gimple_build_vector_from_val (gimple_stmt_iterator *gsi,
11580 : bool before, gsi_iterator_update update,
11581 : location_t loc, tree type, tree op)
11582 : {
11583 333185 : if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()
11584 : && !CONSTANT_CLASS_P (op))
11585 : return gimple_build (gsi, before, update,
11586 : loc, VEC_DUPLICATE_EXPR, type, op);
11587 :
11588 333185 : tree res, vec = build_vector_from_val (type, op);
11589 333185 : if (is_gimple_val (vec))
11590 : return vec;
11591 28135 : if (gimple_in_ssa_p (cfun))
11592 28135 : res = make_ssa_name (type);
11593 : else
11594 0 : res = create_tmp_reg (type);
11595 28135 : gimple_seq seq = NULL;
11596 28135 : gimple *stmt = gimple_build_assign (res, vec);
11597 28135 : gimple_set_location (stmt, loc);
11598 28135 : gimple_seq_add_stmt_without_update (&seq, stmt);
11599 28135 : gimple_build_insert_seq (gsi, before, update, seq);
11600 28135 : return res;
11601 : }
11602 :
11603 : /* Build a vector from BUILDER, handling the case in which some elements
11604 : are non-constant. Return a gimple value for the result, inserting
11605 : any new instructions to GSI honoring BEFORE and UPDATE.
11606 :
11607 : BUILDER must not have a stepped encoding on entry. This is because
11608 : the function is not geared up to handle the arithmetic that would
11609 : be needed in the variable case, and any code building a vector that
11610 : is known to be constant should use BUILDER->build () directly. */
11611 :
11612 : tree
11613 378653 : gimple_build_vector (gimple_stmt_iterator *gsi,
11614 : bool before, gsi_iterator_update update,
11615 : location_t loc, tree_vector_builder *builder)
11616 : {
11617 378653 : gcc_assert (builder->nelts_per_pattern () <= 2);
11618 378653 : unsigned int encoded_nelts = builder->encoded_nelts ();
11619 1333343 : for (unsigned int i = 0; i < encoded_nelts; ++i)
11620 1070600 : if (!CONSTANT_CLASS_P ((*builder)[i]))
11621 : {
11622 115910 : gimple_seq seq = NULL;
11623 115910 : tree type = builder->type ();
11624 115910 : unsigned int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
11625 115910 : vec<constructor_elt, va_gc> *v;
11626 115910 : vec_alloc (v, nelts);
11627 485694 : for (i = 0; i < nelts; ++i)
11628 253874 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));
11629 :
11630 115910 : tree res;
11631 115910 : if (gimple_in_ssa_p (cfun))
11632 115910 : res = make_ssa_name (type);
11633 : else
11634 0 : res = create_tmp_reg (type);
11635 115910 : gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
11636 115910 : gimple_set_location (stmt, loc);
11637 115910 : gimple_seq_add_stmt_without_update (&seq, stmt);
11638 115910 : gimple_build_insert_seq (gsi, before, update, seq);
11639 115910 : return res;
11640 : }
11641 262743 : return builder->build ();
11642 : }
11643 :
11644 : /* Emit gimple statements into &stmts that take a value given in OLD_SIZE
11645 : and generate a value guaranteed to be rounded upwards to ALIGN.
11646 :
11647 : Return the tree node representing this size, it is of TREE_TYPE TYPE. */
11648 :
11649 : tree
11650 0 : gimple_build_round_up (gimple_stmt_iterator *gsi,
11651 : bool before, gsi_iterator_update update,
11652 : location_t loc, tree type,
11653 : tree old_size, unsigned HOST_WIDE_INT align)
11654 : {
11655 0 : unsigned HOST_WIDE_INT tg_mask = align - 1;
11656 : /* tree new_size = (old_size + tg_mask) & ~tg_mask; */
11657 0 : gcc_assert (INTEGRAL_TYPE_P (type));
11658 0 : tree tree_mask = build_int_cst (type, tg_mask);
11659 0 : tree oversize = gimple_build (gsi, before, update,
11660 : loc, PLUS_EXPR, type, old_size, tree_mask);
11661 :
11662 0 : tree mask = build_int_cst (type, -align);
11663 0 : return gimple_build (gsi, before, update,
11664 0 : loc, BIT_AND_EXPR, type, oversize, mask);
11665 : }
11666 :
11667 : /* Return true if the result of assignment STMT is known to be non-negative.
11668 : DEPTH is the current nesting depth of the query. */
11669 :
11670 : static bool
11671 6138906 : gimple_assign_nonnegative_p (gimple *stmt, int depth)
11672 : {
11673 6138906 : enum tree_code code = gimple_assign_rhs_code (stmt);
11674 6138906 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
11675 6138906 : switch (get_gimple_rhs_class (code))
11676 : {
11677 468119 : case GIMPLE_UNARY_RHS:
11678 468119 : return tree_unary_nonnegative_p (gimple_assign_rhs_code (stmt),
11679 : type,
11680 : gimple_assign_rhs1 (stmt),
11681 468119 : depth);
11682 3429419 : case GIMPLE_BINARY_RHS:
11683 3429419 : return tree_binary_nonnegative_p (gimple_assign_rhs_code (stmt),
11684 : type,
11685 : gimple_assign_rhs1 (stmt),
11686 : gimple_assign_rhs2 (stmt),
11687 3429419 : depth);
11688 : case GIMPLE_TERNARY_RHS:
11689 : return false;
11690 2228186 : case GIMPLE_SINGLE_RHS:
11691 2228186 : return tree_single_nonnegative_p (gimple_assign_rhs1 (stmt),
11692 2228186 : depth);
11693 : case GIMPLE_INVALID_RHS:
11694 : break;
11695 : }
11696 0 : gcc_unreachable ();
11697 : }
11698 :
11699 : /* Return true if return value of call STMT is known to be non-negative.
11700 : DEPTH is the current nesting depth of the query. */
11701 :
11702 : static bool
11703 13866636 : gimple_call_nonnegative_p (gimple *stmt, int depth)
11704 : {
11705 13866636 : tree arg0
11706 13866636 : = gimple_call_num_args (stmt) > 0 ? gimple_call_arg (stmt, 0) : NULL_TREE;
11707 13866636 : tree arg1
11708 13866636 : = gimple_call_num_args (stmt) > 1 ? gimple_call_arg (stmt, 1) : NULL_TREE;
11709 13866636 : tree lhs = gimple_call_lhs (stmt);
11710 13866636 : return (lhs
11711 13866636 : && tree_call_nonnegative_p (TREE_TYPE (lhs),
11712 : gimple_call_combined_fn (stmt),
11713 13866636 : arg0, arg1, depth));
11714 : }
11715 :
11716 : /* Return true if return value of call STMT is known to be non-negative.
11717 : DEPTH is the current nesting depth of the query. */
11718 :
11719 : static bool
11720 968389 : gimple_phi_nonnegative_p (gimple *stmt, int depth)
11721 : {
11722 1325027 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11723 : {
11724 1320151 : tree arg = gimple_phi_arg_def (stmt, i);
11725 1320151 : if (!tree_single_nonnegative_p (arg, depth + 1))
11726 : return false;
11727 : }
11728 : return true;
11729 : }
11730 :
11731 : /* Return true if STMT is known to compute a non-negative value.
11732 : DEPTH is the current nesting depth of the query. */
11733 :
11734 : bool
11735 21654282 : gimple_stmt_nonnegative_p (gimple *stmt, int depth)
11736 : {
11737 21654282 : tree type = gimple_range_type (stmt);
11738 21654282 : if (type && frange::supports_p (type))
11739 : {
11740 1457701 : frange r;
11741 1457701 : bool sign;
11742 1457701 : if (get_global_range_query ()->range_of_stmt (r, stmt)
11743 1457701 : && r.signbit_p (sign))
11744 25595 : return !sign;
11745 1457701 : }
11746 21628687 : switch (gimple_code (stmt))
11747 : {
11748 6138906 : case GIMPLE_ASSIGN:
11749 6138906 : return gimple_assign_nonnegative_p (stmt, depth);
11750 13866636 : case GIMPLE_CALL:
11751 13866636 : return gimple_call_nonnegative_p (stmt, depth);
11752 968389 : case GIMPLE_PHI:
11753 968389 : return gimple_phi_nonnegative_p (stmt, depth);
11754 : default:
11755 : return false;
11756 : }
11757 : }
11758 :
11759 : /* Return true if the floating-point value computed by assignment STMT
11760 : is known to have an integer value. We also allow +Inf, -Inf and NaN
11761 : to be considered integer values. Return false for signaling NaN.
11762 :
11763 : DEPTH is the current nesting depth of the query. */
11764 :
11765 : static bool
11766 60483 : gimple_assign_integer_valued_real_p (gimple *stmt, int depth)
11767 : {
11768 60483 : enum tree_code code = gimple_assign_rhs_code (stmt);
11769 60483 : switch (get_gimple_rhs_class (code))
11770 : {
11771 15209 : case GIMPLE_UNARY_RHS:
11772 15209 : return integer_valued_real_unary_p (gimple_assign_rhs_code (stmt),
11773 15209 : gimple_assign_rhs1 (stmt), depth);
11774 13863 : case GIMPLE_BINARY_RHS:
11775 13863 : return integer_valued_real_binary_p (gimple_assign_rhs_code (stmt),
11776 : gimple_assign_rhs1 (stmt),
11777 13863 : gimple_assign_rhs2 (stmt), depth);
11778 : case GIMPLE_TERNARY_RHS:
11779 : return false;
11780 30227 : case GIMPLE_SINGLE_RHS:
11781 30227 : return integer_valued_real_single_p (gimple_assign_rhs1 (stmt), depth);
11782 : case GIMPLE_INVALID_RHS:
11783 : break;
11784 : }
11785 0 : gcc_unreachable ();
11786 : }
11787 :
11788 : /* Return true if the floating-point value computed by call STMT is known
11789 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11790 : considered integer values. Return false for signaling NaN.
11791 :
11792 : DEPTH is the current nesting depth of the query. */
11793 :
11794 : static bool
11795 1189 : gimple_call_integer_valued_real_p (gimple *stmt, int depth)
11796 : {
11797 1189 : tree arg0 = (gimple_call_num_args (stmt) > 0
11798 1189 : ? gimple_call_arg (stmt, 0)
11799 : : NULL_TREE);
11800 1189 : tree arg1 = (gimple_call_num_args (stmt) > 1
11801 1189 : ? gimple_call_arg (stmt, 1)
11802 : : NULL_TREE);
11803 1189 : return integer_valued_real_call_p (gimple_call_combined_fn (stmt),
11804 1189 : arg0, arg1, depth);
11805 : }
11806 :
11807 : /* Return true if the floating-point result of phi STMT is known to have
11808 : an integer value. We also allow +Inf, -Inf and NaN to be considered
11809 : integer values. Return false for signaling NaN.
11810 :
11811 : DEPTH is the current nesting depth of the query. */
11812 :
11813 : static bool
11814 1569 : gimple_phi_integer_valued_real_p (gimple *stmt, int depth)
11815 : {
11816 1736 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11817 : {
11818 1727 : tree arg = gimple_phi_arg_def (stmt, i);
11819 1727 : if (!integer_valued_real_single_p (arg, depth + 1))
11820 : return false;
11821 : }
11822 : return true;
11823 : }
11824 :
11825 : /* Return true if the floating-point value computed by STMT is known
11826 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11827 : considered integer values. Return false for signaling NaN.
11828 :
11829 : DEPTH is the current nesting depth of the query. */
11830 :
11831 : bool
11832 90655 : gimple_stmt_integer_valued_real_p (gimple *stmt, int depth)
11833 : {
11834 90655 : switch (gimple_code (stmt))
11835 : {
11836 60483 : case GIMPLE_ASSIGN:
11837 60483 : return gimple_assign_integer_valued_real_p (stmt, depth);
11838 1189 : case GIMPLE_CALL:
11839 1189 : return gimple_call_integer_valued_real_p (stmt, depth);
11840 1569 : case GIMPLE_PHI:
11841 1569 : return gimple_phi_integer_valued_real_p (stmt, depth);
11842 : default:
11843 : return false;
11844 : }
11845 : }
|