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 4423009 : can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
116 : {
117 4423009 : varpool_node *vnode;
118 4423009 : struct cgraph_node *node;
119 4423009 : symtab_node *snode;
120 :
121 4423009 : if (DECL_ABSTRACT_P (decl))
122 : return false;
123 :
124 : /* We are concerned only about static/external vars and functions. */
125 1500315 : if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
126 5518746 : || !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 4018431 : if (!TREE_PUBLIC (decl))
132 : {
133 1098547 : 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 1098502 : if (symtab->function_flags_ready)
138 : return true;
139 1062777 : snode = symtab_node::get (decl);
140 1062777 : if (!snode || !snode->definition)
141 : return false;
142 1062722 : node = dyn_cast <cgraph_node *> (snode);
143 1071399 : 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 2919884 : if (!from_decl
150 464499 : || !VAR_P (from_decl)
151 463370 : || (!DECL_EXTERNAL (from_decl)
152 202934 : && (vnode = varpool_node::get (from_decl)) != NULL
153 140015 : && vnode->definition)
154 3243245 : || (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 323358 : if (DECL_VISIBILITY_SPECIFIED (decl)
162 316637 : && DECL_EXTERNAL (decl)
163 252134 : && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT
164 492155 : && (!(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 154561 : 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 108947 : if (!symtab->function_flags_ready)
183 : return true;
184 :
185 96272 : snode = symtab_node::get (decl);
186 96272 : if (!snode
187 96272 : || ((!snode->definition || DECL_EXTERNAL (decl))
188 11931 : && (!snode->in_other_partition
189 0 : || (!snode->forced_by_abi && !snode->force_output))))
190 : return false;
191 59037 : node = dyn_cast <cgraph_node *> (snode);
192 59037 : 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 15529869 : canonicalize_constructor_val (tree cval, tree from_decl)
201 : {
202 15529869 : if (CONSTANT_CLASS_P (cval))
203 : return cval;
204 :
205 9403242 : tree orig_cval = cval;
206 9403242 : STRIP_NOPS (cval);
207 9403242 : if (TREE_CODE (cval) == POINTER_PLUS_EXPR
208 9403242 : && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
209 : {
210 71016 : tree ptr = TREE_OPERAND (cval, 0);
211 71016 : if (is_gimple_min_invariant (ptr))
212 212337 : cval = build1_loc (EXPR_LOCATION (cval),
213 70779 : ADDR_EXPR, TREE_TYPE (ptr),
214 141558 : fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),
215 : ptr,
216 : fold_convert (ptr_type_node,
217 : TREE_OPERAND (cval, 1))));
218 : }
219 9403242 : if (TREE_CODE (cval) == ADDR_EXPR)
220 : {
221 5148864 : tree base = NULL_TREE;
222 5148864 : 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 5148671 : base = get_base_address (TREE_OPERAND (cval, 0));
230 5148864 : if (!base)
231 0 : return NULL_TREE;
232 :
233 2292425 : if (VAR_OR_FUNCTION_DECL_P (base)
234 6445145 : && !can_refer_decl_in_current_unit_p (base, from_decl))
235 : return NULL_TREE;
236 4979285 : if (TREE_TYPE (base) == error_mark_node)
237 : return NULL_TREE;
238 4979285 : 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 2291540 : 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 1295396 : cgraph_node::get_create (base);
248 : }
249 : /* Fixup types in global initializers. */
250 4979285 : if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
251 38758 : cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
252 :
253 4979285 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
254 213336 : cval = fold_convert (TREE_TYPE (orig_cval), cval);
255 4979285 : return cval;
256 : }
257 : /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0. */
258 4254378 : if (TREE_CODE (cval) == INTEGER_CST)
259 : {
260 65114 : if (TREE_OVERFLOW_P (cval))
261 0 : cval = drop_tree_overflow (cval);
262 65114 : if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
263 61913 : cval = fold_convert (TREE_TYPE (orig_cval), cval);
264 65114 : 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 20370491 : get_symbol_constant_value (tree sym)
274 : {
275 20370491 : tree val = ctor_for_folding (sym);
276 20370491 : if (val != error_mark_node)
277 : {
278 39753 : if (val)
279 : {
280 37459 : val = canonicalize_constructor_val (unshare_expr (val), sym);
281 37459 : if (val
282 37459 : && is_gimple_min_invariant (val)
283 66052 : && useless_type_conversion_p (TREE_TYPE (sym), TREE_TYPE (val)))
284 : return val;
285 : else
286 8972 : return NULL_TREE;
287 : }
288 : /* Variables declared 'const' without an initializer
289 : have zero as the initializer if they may not be
290 : overridden at link or run time. */
291 2294 : if (!val
292 2294 : && is_gimple_reg_type (TREE_TYPE (sym)))
293 1957 : 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 65281289 : maybe_fold_reference (tree expr)
306 : {
307 65281289 : tree result = NULL_TREE;
308 :
309 : /* Avoid expensive fold_const_aggregate_ref early on aggregate loads
310 : and esp. replacing STRING_CSTs inline. */
311 65281289 : if (!is_gimple_reg_type (TREE_TYPE (expr)))
312 : return NULL_TREE;
313 :
314 62152706 : if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
315 60818455 : || TREE_CODE (expr) == REALPART_EXPR
316 60026403 : || TREE_CODE (expr) == IMAGPART_EXPR)
317 63873438 : && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
318 5795 : result = fold_unary_loc (EXPR_LOCATION (expr),
319 : TREE_CODE (expr),
320 5795 : TREE_TYPE (expr),
321 5795 : TREE_OPERAND (expr, 0));
322 62146911 : else if (TREE_CODE (expr) == BIT_FIELD_REF
323 62146911 : && 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 62146862 : result = fold_const_aggregate_ref (expr);
332 :
333 62152706 : if (result && is_gimple_min_invariant (result))
334 : 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 0 : 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 0 : 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 259995402 : fold_gimple_assign (gimple_stmt_iterator *si)
462 : {
463 259995402 : gimple *stmt = gsi_stmt (*si);
464 259995402 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
465 259995402 : location_t loc = gimple_location (stmt);
466 :
467 259995402 : tree result = NULL_TREE;
468 :
469 259995402 : switch (get_gimple_rhs_class (subcode))
470 : {
471 172301397 : case GIMPLE_SINGLE_RHS:
472 172301397 : {
473 172301397 : tree rhs = gimple_assign_rhs1 (stmt);
474 :
475 172301397 : if (TREE_CLOBBER_P (rhs))
476 : return NULL_TREE;
477 :
478 158351489 : if (REFERENCE_CLASS_P (rhs))
479 62589509 : return maybe_fold_reference (rhs);
480 :
481 95761980 : else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
482 : {
483 166970 : tree val = OBJ_TYPE_REF_EXPR (rhs);
484 166970 : if (is_gimple_min_invariant (val))
485 : return val;
486 166939 : else if (flag_devirtualize && virtual_method_call_p (rhs))
487 : {
488 166899 : bool final;
489 166899 : vec <cgraph_node *>targets
490 166899 : = possible_polymorphic_call_targets (rhs, stmt, &final);
491 167171 : 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 95595010 : else if (TREE_CODE (rhs) == ADDR_EXPR)
519 : {
520 15101610 : tree ref = TREE_OPERAND (rhs, 0);
521 15101610 : if (TREE_CODE (ref) == MEM_REF
522 15101610 : && integer_zerop (TREE_OPERAND (ref, 1)))
523 : {
524 2659 : result = TREE_OPERAND (ref, 0);
525 2659 : if (!useless_type_conversion_p (TREE_TYPE (rhs),
526 2659 : TREE_TYPE (result)))
527 0 : result = build1 (NOP_EXPR, TREE_TYPE (rhs), result);
528 2659 : return result;
529 : }
530 : }
531 :
532 80493400 : else if (TREE_CODE (rhs) == CONSTRUCTOR
533 80493400 : && 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 461874 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
540 457472 : if (! CONSTANT_CLASS_P (val))
541 : return NULL_TREE;
542 :
543 4402 : return build_vector_from_ctor (TREE_TYPE (rhs),
544 8804 : CONSTRUCTOR_ELTS (rhs));
545 : }
546 :
547 80123839 : else if (DECL_P (rhs)
548 80123839 : && is_gimple_reg_type (TREE_TYPE (rhs)))
549 12235133 : 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 562995 : case GIMPLE_TERNARY_RHS:
560 1125990 : result = fold_ternary_loc (loc, subcode,
561 562995 : TREE_TYPE (gimple_assign_lhs (stmt)),
562 : gimple_assign_rhs1 (stmt),
563 : gimple_assign_rhs2 (stmt),
564 : gimple_assign_rhs3 (stmt));
565 :
566 562995 : if (result)
567 : {
568 0 : STRIP_USELESS_TYPE_CONVERSION (result);
569 0 : if (valid_gimple_rhs_p (result))
570 : 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 130241 : gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
595 : {
596 130241 : gimple *stmt = gsi_stmt (*si_p);
597 :
598 130241 : if (gimple_has_location (stmt))
599 108132 : 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 130241 : gimple *laststore = NULL;
604 260482 : for (gimple_stmt_iterator i = gsi_last (stmts);
605 532399 : !gsi_end_p (i); gsi_prev (&i))
606 : {
607 201079 : gimple *new_stmt = gsi_stmt (i);
608 201079 : if ((gimple_assign_single_p (new_stmt)
609 126219 : && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
610 327028 : || (is_gimple_call (new_stmt)
611 15032 : && (gimple_call_flags (new_stmt)
612 15032 : & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0))
613 : {
614 2407 : tree vdef;
615 2407 : if (!laststore)
616 2401 : vdef = gimple_vdef (stmt);
617 : else
618 6 : vdef = make_ssa_name (gimple_vop (cfun), new_stmt);
619 2407 : gimple_set_vdef (new_stmt, vdef);
620 2407 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
621 1383 : 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 130241 : tree reaching_vuse = gimple_vuse (stmt);
629 130241 : for (gimple_stmt_iterator i = gsi_start (stmts);
630 331320 : !gsi_end_p (i); gsi_next (&i))
631 : {
632 201079 : 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 201079 : if (gimple_has_mem_ops (new_stmt))
636 201077 : gimple_set_vuse (new_stmt, reaching_vuse);
637 201079 : gimple_set_modified (new_stmt, true);
638 601846 : if (gimple_vdef (new_stmt))
639 201079 : 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 130241 : if (reaching_vuse
645 216101 : && reaching_vuse == gimple_vuse (stmt))
646 : {
647 84483 : tree vdef = gimple_vdef (stmt);
648 84483 : if (vdef
649 1469 : && TREE_CODE (vdef) == SSA_NAME)
650 : {
651 1413 : unlink_stmt_vdef (stmt);
652 1413 : release_ssa_name (vdef);
653 : }
654 : }
655 :
656 : /* Finally replace the original statement with the sequence. */
657 130241 : gsi_replace_with_seq (si_p, stmts, false);
658 130241 : }
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 2468 : finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
666 : gimple *stmt)
667 : {
668 2468 : tree lhs = gimple_call_lhs (stmt);
669 2468 : gimple_call_set_lhs (new_stmt, lhs);
670 2468 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
671 794 : SSA_NAME_DEF_STMT (lhs) = new_stmt;
672 2468 : gimple_move_vops (new_stmt, stmt);
673 2468 : gimple_set_location (new_stmt, gimple_location (stmt));
674 2468 : if (gimple_block (new_stmt) == NULL_TREE)
675 1 : gimple_set_block (new_stmt, gimple_block (stmt));
676 2468 : gsi_replace (si_p, new_stmt, false);
677 2468 : }
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 2465 : update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
685 : {
686 2465 : va_list ap;
687 2465 : gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));
688 :
689 2465 : gcc_assert (is_gimple_call (stmt));
690 2465 : va_start (ap, nargs);
691 2465 : new_stmt = gimple_build_call_valist (fn, nargs, ap);
692 2465 : finish_update_gimple_call (si_p, new_stmt, stmt);
693 2465 : va_end (ap);
694 2465 : 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 60164 : valid_gimple_call_p (tree expr)
703 : {
704 60164 : unsigned i, nargs;
705 :
706 60164 : 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 60164 : gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
738 : {
739 60164 : tree lhs;
740 60164 : gimple *stmt, *new_stmt;
741 60164 : gimple_stmt_iterator i;
742 60164 : gimple_seq stmts = NULL;
743 :
744 60164 : stmt = gsi_stmt (*si_p);
745 :
746 60164 : gcc_assert (is_gimple_call (stmt));
747 :
748 60164 : 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 60161 : lhs = gimple_call_lhs (stmt);
773 60161 : if (lhs == NULL_TREE)
774 : {
775 2464 : push_gimplify_context (gimple_in_ssa_p (cfun));
776 1232 : gimplify_and_add (expr, &stmts);
777 1232 : 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 1232 : if (gimple_seq_empty_p (stmts))
782 : {
783 1097 : if (gimple_in_ssa_p (cfun))
784 : {
785 1097 : unlink_stmt_vdef (stmt);
786 1097 : release_defs (stmt);
787 : }
788 1097 : gsi_replace (si_p, gimple_build_nop (), false);
789 1097 : return;
790 : }
791 : }
792 : else
793 : {
794 58929 : tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
795 58929 : new_stmt = gimple_build_assign (lhs, tmp);
796 58929 : i = gsi_last (stmts);
797 58929 : gsi_insert_after_without_update (&i, new_stmt,
798 : GSI_CONTINUE_LINKING);
799 : }
800 :
801 59064 : 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 40570 : dump_transformation (gcall *from, gcall *to)
808 : {
809 40570 : 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 40570 : }
813 :
814 : /* Replace the call at *GSI with the gimple value VAL. */
815 :
816 : void
817 90528 : replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
818 : {
819 90528 : gimple *stmt = gsi_stmt (*gsi);
820 90528 : tree lhs = gimple_call_lhs (stmt);
821 90528 : gimple *repl;
822 90528 : if (lhs)
823 : {
824 85520 : if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (val)))
825 2176 : val = fold_convert (TREE_TYPE (lhs), val);
826 85520 : repl = gimple_build_assign (lhs, val);
827 : }
828 : else
829 5008 : repl = gimple_build_nop ();
830 90528 : tree vdef = gimple_vdef (stmt);
831 90528 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
832 : {
833 5582 : unlink_stmt_vdef (stmt);
834 5582 : release_ssa_name (vdef);
835 : }
836 90528 : gsi_replace (gsi, repl, false);
837 90528 : }
838 :
839 : /* Replace the call at *GSI with the new call REPL and fold that
840 : again. */
841 :
842 : static void
843 40570 : replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
844 : {
845 40570 : gimple *stmt = gsi_stmt (*gsi);
846 40570 : dump_transformation (as_a <gcall *> (stmt), as_a <gcall *> (repl));
847 40570 : gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
848 40570 : gimple_set_location (repl, gimple_location (stmt));
849 40570 : gimple_move_vops (repl, stmt);
850 40570 : gsi_replace (gsi, repl, false);
851 40570 : fold_stmt (gsi);
852 40570 : }
853 :
854 : /* Return true if VAR is a VAR_DECL or a component thereof. */
855 :
856 : static bool
857 402218 : var_decl_component_p (tree var)
858 : {
859 402218 : tree inner = var;
860 571686 : while (handled_component_p (inner))
861 169468 : inner = TREE_OPERAND (inner, 0);
862 402218 : return (DECL_P (inner)
863 402218 : || (TREE_CODE (inner) == MEM_REF
864 43133 : && 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 1017472 : size_must_be_zero_p (tree size)
872 : {
873 1017472 : if (integer_zerop (size))
874 : return true;
875 :
876 1014879 : if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size)))
877 : return false;
878 :
879 615512 : tree type = TREE_TYPE (size);
880 615512 : 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 615512 : wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
885 615512 : wide_int zero = wi::zero (TYPE_PRECISION (type));
886 615512 : int_range_max valid_range (type, zero, ssize_max);
887 615512 : int_range_max vr;
888 1231024 : get_range_query (cfun)->range_of_expr (vr, size);
889 :
890 615512 : if (vr.undefined_p ())
891 87 : vr.set_varying (TREE_TYPE (size));
892 615512 : vr.intersect (valid_range);
893 615512 : return vr.zero_p ();
894 615512 : }
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 1017472 : gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
905 : tree dest, tree src, enum built_in_function code)
906 : {
907 1017472 : gimple *stmt = gsi_stmt (*gsi);
908 1017472 : tree lhs = gimple_call_lhs (stmt);
909 1017472 : tree len = gimple_call_arg (stmt, 2);
910 1017472 : 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 1017472 : if (size_must_be_zero_p (len))
915 : {
916 2638 : gimple *repl;
917 2638 : if (gimple_call_lhs (stmt))
918 60 : repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
919 : else
920 2578 : repl = gimple_build_nop ();
921 2638 : tree vdef = gimple_vdef (stmt);
922 2638 : if (vdef && TREE_CODE (vdef) == SSA_NAME)
923 : {
924 460 : unlink_stmt_vdef (stmt);
925 460 : release_ssa_name (vdef);
926 : }
927 2638 : gsi_replace (gsi, repl, false);
928 2638 : return true;
929 : }
930 :
931 : /* If SRC and DEST are the same (and not volatile), return
932 : DEST{,+LEN,+LEN-1}. */
933 1014834 : 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 83 : unlink_stmt_vdef (stmt);
939 166 : if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
940 43 : release_ssa_name (gimple_vdef (stmt));
941 83 : if (!lhs)
942 : {
943 62 : gsi_replace (gsi, gimple_build_nop (), false);
944 62 : return true;
945 : }
946 21 : goto done;
947 : }
948 2029502 : 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 1014751 : tree srctype
956 1028433 : = POINTER_TYPE_P (TREE_TYPE (src))
957 1028433 : ? TREE_TYPE (TREE_TYPE (src)) : NULL_TREE;
958 1014751 : tree desttype
959 1035119 : = POINTER_TYPE_P (TREE_TYPE (dest))
960 1035119 : ? TREE_TYPE (TREE_TYPE (dest)) : NULL_TREE;
961 1014751 : tree destvar, srcvar, srcoff;
962 1014751 : unsigned int src_align, dest_align;
963 1014751 : unsigned HOST_WIDE_INT tmp_len;
964 1014751 : const char *tmp_str;
965 :
966 : /* Build accesses at offset zero with a ref-all character type. */
967 1014751 : tree off0
968 1014751 : = 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 1014751 : src_align = get_pointer_alignment (src);
976 1014751 : dest_align = get_pointer_alignment (dest);
977 1014751 : if (tree_fits_uhwi_p (len)
978 389157 : && 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 290675 : && !c_strlen (src, 1)
986 192902 : && !((tmp_str = getbyterep (src, &tmp_len)) != NULL
987 80842 : && memchr (tmp_str, 0, tmp_len) == NULL)
988 125761 : && !(srctype
989 125761 : && AGGREGATE_TYPE_P (srctype)
990 60205 : && TYPE_REVERSE_STORAGE_ORDER (srctype))
991 1140379 : && !(desttype
992 125628 : && AGGREGATE_TYPE_P (desttype)
993 69581 : && TYPE_REVERSE_STORAGE_ORDER (desttype)))
994 : {
995 125595 : unsigned ilen = tree_to_uhwi (len);
996 125595 : 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 25207 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1004 : dest, src, len, len,
1005 25207 : false, false))
1006 981 : if (warning != OPT_Wrestrict)
1007 21846 : return false;
1008 :
1009 24285 : scalar_int_mode imode;
1010 24285 : machine_mode mode;
1011 24285 : if (int_mode_for_size (ilen * BITS_PER_UNIT, 0).exists (&imode)
1012 24285 : && bitwise_mode_for_size (ilen
1013 24285 : * BITS_PER_UNIT).exists (&mode)
1014 48570 : && 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 24285 : && (dest_align >= GET_MODE_ALIGNMENT (mode)
1018 13157 : || !targetm.slow_unaligned_access (mode, dest_align)
1019 0 : || (optab_handler (movmisalign_optab, mode)
1020 : != CODE_FOR_nothing)))
1021 : {
1022 24285 : tree type = bitwise_type_for_mode (mode);
1023 24285 : tree srctype = type;
1024 24285 : tree desttype = type;
1025 24285 : if (src_align < GET_MODE_ALIGNMENT (mode))
1026 12582 : srctype = build_aligned_type (type, src_align);
1027 24285 : tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
1028 24285 : tree tem = fold_const_aggregate_ref (srcmem);
1029 24285 : if (tem)
1030 : srcmem = tem;
1031 23223 : else if (src_align < GET_MODE_ALIGNMENT (mode)
1032 12324 : && targetm.slow_unaligned_access (mode, src_align)
1033 23223 : && (optab_handler (movmisalign_optab, mode)
1034 : == CODE_FOR_nothing))
1035 : srcmem = NULL_TREE;
1036 23223 : if (srcmem)
1037 : {
1038 24285 : gimple *new_stmt;
1039 24285 : if (is_gimple_reg_type (TREE_TYPE (srcmem)))
1040 : {
1041 24285 : new_stmt = gimple_build_assign (NULL_TREE, srcmem);
1042 24285 : srcmem
1043 24285 : = make_ssa_name (TREE_TYPE (srcmem), new_stmt);
1044 24285 : gimple_assign_set_lhs (new_stmt, srcmem);
1045 48570 : gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1046 24285 : gimple_set_location (new_stmt, loc);
1047 24285 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1048 : }
1049 24285 : if (dest_align < GET_MODE_ALIGNMENT (mode))
1050 13157 : desttype = build_aligned_type (type, dest_align);
1051 24285 : new_stmt
1052 24285 : = gimple_build_assign (fold_build2 (MEM_REF, desttype,
1053 : dest, off0),
1054 : srcmem);
1055 24285 : gimple_move_vops (new_stmt, stmt);
1056 24285 : if (!lhs)
1057 : {
1058 20924 : gsi_replace (gsi, new_stmt, false);
1059 20924 : return true;
1060 : }
1061 3361 : gimple_set_location (new_stmt, loc);
1062 3361 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1063 3361 : goto done;
1064 : }
1065 : }
1066 : }
1067 : }
1068 :
1069 989544 : 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 204799 : if (!dest_align || !src_align)
1077 : return false;
1078 204799 : if (readonly_data_expr (src)
1079 204799 : || (tree_fits_uhwi_p (len)
1080 32957 : && (MIN (src_align, dest_align) / BITS_PER_UNIT
1081 32957 : >= tree_to_uhwi (len))))
1082 : {
1083 955802 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1084 20545 : if (!fn)
1085 : return false;
1086 20545 : gimple_call_set_fndecl (stmt, fn);
1087 20545 : gimple_call_set_arg (stmt, 0, dest);
1088 20545 : gimple_call_set_arg (stmt, 1, src);
1089 20545 : fold_stmt (gsi);
1090 20545 : return true;
1091 : }
1092 :
1093 : /* If *src and *dest can't overlap, optimize into memcpy as well. */
1094 184254 : if (TREE_CODE (src) == ADDR_EXPR
1095 5507 : && TREE_CODE (dest) == ADDR_EXPR)
1096 : {
1097 1826 : tree src_base, dest_base, fn;
1098 1826 : poly_int64 src_offset = 0, dest_offset = 0;
1099 1826 : poly_uint64 maxsize;
1100 :
1101 1826 : srcvar = TREE_OPERAND (src, 0);
1102 1826 : src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
1103 1826 : if (src_base == NULL)
1104 0 : src_base = srcvar;
1105 1826 : destvar = TREE_OPERAND (dest, 0);
1106 1826 : dest_base = get_addr_base_and_unit_offset (destvar,
1107 : &dest_offset);
1108 1826 : if (dest_base == NULL)
1109 0 : dest_base = destvar;
1110 1826 : if (!poly_int_tree_p (len, &maxsize))
1111 229 : maxsize = -1;
1112 1826 : if (SSA_VAR_P (src_base)
1113 1816 : && SSA_VAR_P (dest_base))
1114 : {
1115 1816 : if (operand_equal_p (src_base, dest_base, 0)
1116 1816 : && ranges_maybe_overlap_p (src_offset, maxsize,
1117 : dest_offset, maxsize))
1118 : return false;
1119 : }
1120 10 : else if (TREE_CODE (src_base) == MEM_REF
1121 0 : && TREE_CODE (dest_base) == MEM_REF)
1122 : {
1123 0 : if (! operand_equal_p (TREE_OPERAND (src_base, 0),
1124 0 : TREE_OPERAND (dest_base, 0), 0))
1125 0 : return false;
1126 0 : poly_offset_int full_src_offset
1127 0 : = mem_ref_offset (src_base) + src_offset;
1128 0 : poly_offset_int full_dest_offset
1129 0 : = mem_ref_offset (dest_base) + dest_offset;
1130 0 : if (ranges_maybe_overlap_p (full_src_offset, maxsize,
1131 : full_dest_offset, maxsize))
1132 : return false;
1133 0 : }
1134 : else
1135 : return false;
1136 :
1137 1826 : 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 182428 : if ((is_gimple_min_invariant (dest)
1150 178743 : || TREE_CODE (dest) == SSA_NAME)
1151 342731 : && (is_gimple_min_invariant (src)
1152 160328 : || TREE_CODE (src) == SSA_NAME))
1153 : {
1154 163545 : ao_ref destr, srcr;
1155 163545 : ao_ref_init_from_ptr_and_size (&destr, dest, len);
1156 163545 : ao_ref_init_from_ptr_and_size (&srcr, src, len);
1157 163545 : if (!refs_may_alias_p_1 (&destr, &srcr, false))
1158 : {
1159 10306 : tree fn;
1160 10306 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1161 10306 : if (!fn)
1162 10306 : return false;
1163 10306 : gimple_call_set_fndecl (stmt, fn);
1164 10306 : gimple_call_set_arg (stmt, 0, dest);
1165 10306 : gimple_call_set_arg (stmt, 1, src);
1166 10306 : fold_stmt (gsi);
1167 10306 : return true;
1168 : }
1169 : }
1170 :
1171 172122 : return false;
1172 : }
1173 :
1174 784745 : if (!tree_fits_shwi_p (len))
1175 : return false;
1176 313893 : if (!srctype
1177 313893 : || (AGGREGATE_TYPE_P (srctype)
1178 193412 : && TYPE_REVERSE_STORAGE_ORDER (srctype)))
1179 : return false;
1180 313760 : if (!desttype
1181 313760 : || (AGGREGATE_TYPE_P (desttype)
1182 184858 : && 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 313727 : if (TREE_CODE (srctype) == ARRAY_TYPE
1191 313727 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
1192 118545 : srctype = TREE_TYPE (srctype);
1193 313727 : if (TREE_CODE (desttype) == ARRAY_TYPE
1194 313727 : && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
1195 97457 : desttype = TREE_TYPE (desttype);
1196 313727 : if (TREE_ADDRESSABLE (srctype)
1197 313680 : || 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 626629 : if (FLOAT_MODE_P (TYPE_MODE (desttype))
1203 312734 : || TREE_CODE (desttype) == BOOLEAN_TYPE
1204 626344 : || TREE_CODE (desttype) == ENUMERAL_TYPE)
1205 940 : desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
1206 626831 : if (FLOAT_MODE_P (TYPE_MODE (srctype))
1207 313087 : || TREE_CODE (srctype) == BOOLEAN_TYPE
1208 626701 : || TREE_CODE (srctype) == ENUMERAL_TYPE)
1209 583 : srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
1210 313632 : if (!srctype)
1211 120 : srctype = desttype;
1212 313632 : if (!desttype)
1213 0 : desttype = srctype;
1214 313632 : if (!srctype)
1215 : return false;
1216 :
1217 313632 : src_align = get_pointer_alignment (src);
1218 313632 : 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 313632 : destvar = NULL_TREE;
1227 313632 : srcvar = NULL_TREE;
1228 313632 : if (TREE_CODE (dest) == ADDR_EXPR
1229 108915 : && var_decl_component_p (TREE_OPERAND (dest, 0))
1230 108911 : && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)
1231 25001 : && dest_align >= TYPE_ALIGN (desttype)
1232 338633 : && (is_gimple_reg_type (desttype)
1233 24573 : || src_align >= TYPE_ALIGN (desttype)))
1234 19735 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1235 293897 : else if (TREE_CODE (src) == ADDR_EXPR
1236 229053 : && var_decl_component_p (TREE_OPERAND (src, 0))
1237 46845 : && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
1238 8944 : && src_align >= TYPE_ALIGN (srctype)
1239 302825 : && (is_gimple_reg_type (srctype)
1240 8765 : || dest_align >= TYPE_ALIGN (srctype)))
1241 3127 : 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 290770 : 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 290773 : && dest_align >= TYPE_ALIGN (TREE_TYPE (srcvar)))
1250 3 : srctype = TREE_TYPE (srcvar);
1251 : else
1252 290767 : 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 22865 : if (srcvar == NULL_TREE)
1258 : {
1259 19735 : if (src_align >= TYPE_ALIGN (desttype))
1260 19717 : 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 3130 : else if (destvar == NULL_TREE)
1275 : {
1276 3130 : if (dest_align >= TYPE_ALIGN (srctype))
1277 3130 : 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 22865 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1298 : dest, src, len, len,
1299 22865 : false, false))
1300 1263 : if (warning != OPT_Wrestrict)
1301 : return false;
1302 :
1303 21610 : gimple *new_stmt;
1304 21610 : 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 21059 : 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 42112 : desttype = build_array_type_nelts (unsigned_char_type_node,
1333 21056 : tree_to_uhwi (len));
1334 21056 : srctype = desttype;
1335 21056 : if (src_align > TYPE_ALIGN (srctype))
1336 12642 : srctype = build_aligned_type (srctype, src_align);
1337 21056 : srcvar = fold_build2 (MEM_REF, srctype, src, off0);
1338 : }
1339 :
1340 21059 : if (dest_align > TYPE_ALIGN (desttype))
1341 13211 : desttype = build_aligned_type (desttype, dest_align);
1342 21059 : destvar = fold_build2 (MEM_REF, desttype, dest, off0);
1343 21059 : new_stmt = gimple_build_assign (destvar, srcvar);
1344 :
1345 21610 : set_vop_and_replace:
1346 21610 : gimple_move_vops (new_stmt, stmt);
1347 21610 : if (!lhs)
1348 : {
1349 21426 : gsi_replace (gsi, new_stmt, false);
1350 21426 : return true;
1351 : }
1352 184 : gimple_set_location (new_stmt, loc);
1353 184 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1354 : }
1355 :
1356 3566 : done:
1357 3566 : gimple_seq stmts = NULL;
1358 3566 : if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
1359 3566 : len = NULL_TREE;
1360 198 : else if (code == BUILT_IN_MEMPCPY)
1361 : {
1362 198 : len = gimple_convert_to_ptrofftype (&stmts, loc, len);
1363 198 : dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
1364 198 : TREE_TYPE (dest), dest, len);
1365 : }
1366 : else
1367 0 : gcc_unreachable ();
1368 :
1369 3566 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1370 3566 : gimple *repl = gimple_build_assign (lhs, dest);
1371 3566 : gsi_replace (gsi, repl, false);
1372 3566 : return true;
1373 : }
1374 :
1375 : /* Transform a call to built-in bcmp(a, b, len) at *GSI into one
1376 : to built-in memcmp (a, b, len). */
1377 :
1378 : static bool
1379 148 : gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
1380 : {
1381 148 : tree fn = builtin_decl_implicit (BUILT_IN_MEMCMP);
1382 :
1383 148 : if (!fn)
1384 : return false;
1385 :
1386 : /* Transform bcmp (a, b, len) into memcmp (a, b, len). */
1387 :
1388 148 : gimple *stmt = gsi_stmt (*gsi);
1389 296 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
1390 : return false;
1391 148 : tree a = gimple_call_arg (stmt, 0);
1392 148 : tree b = gimple_call_arg (stmt, 1);
1393 148 : tree len = gimple_call_arg (stmt, 2);
1394 :
1395 148 : gimple *repl = gimple_build_call (fn, 3, a, b, len);
1396 148 : replace_call_with_call_and_fold (gsi, repl);
1397 :
1398 148 : return true;
1399 : }
1400 :
1401 : /* Transform a call to built-in bcopy (src, dest, len) at *GSI into one
1402 : to built-in memmove (dest, src, len). */
1403 :
1404 : static bool
1405 367 : gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
1406 : {
1407 367 : tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
1408 :
1409 367 : if (!fn)
1410 : return false;
1411 :
1412 : /* bcopy has been removed from POSIX in Issue 7 but Issue 6 specifies
1413 : it's equivalent to memmove (not memcpy). Transform bcopy (src, dest,
1414 : len) into memmove (dest, src, len). */
1415 :
1416 367 : gimple *stmt = gsi_stmt (*gsi);
1417 734 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1418 : return false;
1419 367 : tree src = gimple_call_arg (stmt, 0);
1420 367 : tree dest = gimple_call_arg (stmt, 1);
1421 367 : tree len = gimple_call_arg (stmt, 2);
1422 :
1423 367 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
1424 367 : gimple_call_set_fntype (as_a <gcall *> (stmt), TREE_TYPE (fn));
1425 367 : replace_call_with_call_and_fold (gsi, repl);
1426 :
1427 367 : return true;
1428 : }
1429 :
1430 : /* Transform a call to built-in bzero (dest, len) at *GSI into one
1431 : to built-in memset (dest, 0, len). */
1432 :
1433 : static bool
1434 250 : gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
1435 : {
1436 250 : tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
1437 :
1438 250 : if (!fn)
1439 : return false;
1440 :
1441 : /* Transform bzero (dest, len) into memset (dest, 0, len). */
1442 :
1443 250 : gimple *stmt = gsi_stmt (*gsi);
1444 500 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1445 : return false;
1446 250 : tree dest = gimple_call_arg (stmt, 0);
1447 250 : tree len = gimple_call_arg (stmt, 1);
1448 :
1449 250 : gimple_seq seq = NULL;
1450 250 : gimple *repl = gimple_build_call (fn, 3, dest, integer_zero_node, len);
1451 250 : gimple_seq_add_stmt_without_update (&seq, repl);
1452 250 : gsi_replace_with_seq_vops (gsi, seq);
1453 250 : fold_stmt (gsi);
1454 :
1455 250 : return true;
1456 : }
1457 :
1458 : /* Fold function call to builtin memset or bzero at *GSI setting the
1459 : memory of size LEN to VAL. Return whether a simplification was made. */
1460 :
1461 : static bool
1462 313865 : gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
1463 : {
1464 313865 : gimple *stmt = gsi_stmt (*gsi);
1465 313865 : tree etype;
1466 313865 : unsigned HOST_WIDE_INT length, cval;
1467 :
1468 : /* If the LEN parameter is zero, return DEST. */
1469 313865 : if (integer_zerop (len))
1470 : {
1471 833 : replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
1472 833 : return true;
1473 : }
1474 :
1475 937122 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
1476 : return false;
1477 :
1478 312954 : if (! tree_fits_uhwi_p (len))
1479 : return false;
1480 :
1481 207387 : length = tree_to_uhwi (len);
1482 :
1483 207387 : tree dest = gimple_call_arg (stmt, 0);
1484 207387 : if (length == 1
1485 207387 : && POINTER_TYPE_P (TREE_TYPE (dest)))
1486 : {
1487 : /* Keep the original call until object-size analysis has inspected it. */
1488 3440 : if (!(cfun->curr_properties & PROP_objsz))
1489 : return false;
1490 :
1491 : /* Detect out-of-bounds accesses without issuing warnings.
1492 : Avoid folding out-of-bounds accesses but to avoid false
1493 : positives for unreachable code defer warning until after
1494 : DCE has worked its magic.
1495 : -Wrestrict is still diagnosed. */
1496 587 : if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1497 : dest, NULL_TREE, len,
1498 587 : NULL_TREE, false, false))
1499 20 : if (warning != OPT_Wrestrict)
1500 : return false;
1501 :
1502 567 : etype = unsigned_char_type_node;
1503 567 : tree ptype = TREE_TYPE (TREE_TYPE (dest));
1504 567 : if (TYPE_VOLATILE (ptype))
1505 0 : etype = build_qualified_type (etype, TYPE_QUAL_VOLATILE);
1506 :
1507 567 : location_t loc = gimple_location (stmt);
1508 567 : tree cval_tree;
1509 567 : if (TREE_CODE (c) == INTEGER_CST)
1510 522 : cval_tree = fold_convert (etype, c);
1511 : else
1512 45 : cval_tree = gimple_convert (gsi, true, GSI_SAME_STMT, loc, etype, c);
1513 :
1514 : /* Build accesses at offset zero with a ref-all character type. */
1515 567 : tree off0
1516 567 : = build_int_cst (build_pointer_type_for_mode (char_type_node,
1517 : ptr_mode, true), 0);
1518 567 : tree var = fold_build2_loc (loc, MEM_REF, etype, dest, off0);
1519 567 : gimple *store = gimple_build_assign (var, cval_tree);
1520 567 : gimple_move_vops (store, stmt);
1521 567 : gimple_set_location (store, loc);
1522 567 : copy_warning (store, stmt);
1523 :
1524 567 : tree lhs = gimple_call_lhs (stmt);
1525 567 : if (!lhs)
1526 : {
1527 458 : gsi_replace (gsi, store, false);
1528 458 : return true;
1529 : }
1530 :
1531 109 : gsi_insert_before (gsi, store, GSI_SAME_STMT);
1532 109 : tree ret = dest;
1533 109 : if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (dest)))
1534 0 : ret = gimple_convert (gsi, true, GSI_SAME_STMT, loc,
1535 0 : TREE_TYPE (lhs), dest);
1536 109 : gimple *asgn = gimple_build_assign (lhs, ret);
1537 109 : gsi_replace (gsi, asgn, false);
1538 :
1539 109 : return true;
1540 : }
1541 :
1542 203947 : if (TREE_CODE (c) != INTEGER_CST)
1543 : return false;
1544 :
1545 198353 : tree var = dest;
1546 198353 : if (TREE_CODE (var) != ADDR_EXPR)
1547 : return false;
1548 :
1549 160562 : var = TREE_OPERAND (var, 0);
1550 160562 : if (TREE_THIS_VOLATILE (var))
1551 : return false;
1552 :
1553 160519 : etype = TREE_TYPE (var);
1554 160519 : if (TREE_CODE (etype) == ARRAY_TYPE)
1555 84981 : etype = TREE_TYPE (etype);
1556 :
1557 160519 : if ((!INTEGRAL_TYPE_P (etype)
1558 95493 : && !POINTER_TYPE_P (etype))
1559 161047 : || BITINT_TYPE_P (etype))
1560 : return false;
1561 :
1562 64250 : if (! var_decl_component_p (var))
1563 : return false;
1564 :
1565 64250 : if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
1566 1407 : || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
1567 2814 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
1568 65657 : || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
1569 62843 : return false;
1570 :
1571 1407 : if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
1572 : return false;
1573 :
1574 1407 : if (!type_has_mode_precision_p (etype))
1575 7 : etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype),
1576 7 : TYPE_UNSIGNED (etype));
1577 :
1578 1407 : if (integer_zerop (c))
1579 : cval = 0;
1580 : else
1581 : {
1582 59 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
1583 : return NULL_TREE;
1584 :
1585 59 : cval = TREE_INT_CST_LOW (c);
1586 59 : cval &= 0xff;
1587 59 : cval |= cval << 8;
1588 59 : cval |= cval << 16;
1589 59 : cval |= (cval << 31) << 1;
1590 : }
1591 :
1592 1407 : var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
1593 1407 : gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
1594 1407 : gimple_move_vops (store, stmt);
1595 1407 : gimple_set_location (store, gimple_location (stmt));
1596 1407 : gsi_insert_before (gsi, store, GSI_SAME_STMT);
1597 1407 : if (gimple_call_lhs (stmt))
1598 : {
1599 0 : gimple *asgn = gimple_build_assign (gimple_call_lhs (stmt), dest);
1600 0 : gsi_replace (gsi, asgn, false);
1601 : }
1602 : else
1603 : {
1604 1407 : gimple_stmt_iterator gsi2 = *gsi;
1605 1407 : gsi_prev (gsi);
1606 1407 : gsi_remove (&gsi2, true);
1607 : }
1608 :
1609 : return true;
1610 : }
1611 :
1612 : /* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
1613 :
1614 : static bool
1615 448407 : get_range_strlen_tree (tree arg, bitmap visited, strlen_range_kind rkind,
1616 : c_strlen_data *pdata, unsigned eltsize)
1617 : {
1618 448407 : gcc_assert (TREE_CODE (arg) != SSA_NAME);
1619 :
1620 : /* The length computed by this invocation of the function. */
1621 448407 : 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 448407 : bool tight_bound = false;
1628 :
1629 : /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
1630 448407 : if (TREE_CODE (arg) == ADDR_EXPR
1631 448407 : && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
1632 : {
1633 28849 : tree op = TREE_OPERAND (arg, 0);
1634 28849 : if (integer_zerop (TREE_OPERAND (op, 1)))
1635 : {
1636 12573 : tree aop0 = TREE_OPERAND (op, 0);
1637 12573 : if (TREE_CODE (aop0) == INDIRECT_REF
1638 12573 : && 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 16276 : else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
1643 16276 : && 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 448199 : 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 2573 : return false;
1668 : }
1669 : else
1670 : {
1671 445116 : c_strlen_data lendata = { };
1672 445116 : val = c_strlen (arg, 1, &lendata, eltsize);
1673 :
1674 445116 : if (!val && lendata.decl)
1675 : {
1676 : /* ARG refers to an unterminated const character array.
1677 : DATA.DECL with size DATA.LEN. */
1678 4214 : val = lendata.minlen;
1679 4214 : 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 445626 : bool maxbound = false;
1686 :
1687 445626 : if (!val && rkind == SRK_LENRANGE)
1688 : {
1689 243201 : if (TREE_CODE (arg) == ADDR_EXPR)
1690 87047 : return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
1691 87047 : pdata, eltsize);
1692 :
1693 156154 : if (TREE_CODE (arg) == ARRAY_REF)
1694 : {
1695 18135 : tree optype = TREE_TYPE (TREE_OPERAND (arg, 0));
1696 :
1697 : /* Determine the "innermost" array type. */
1698 18135 : while (TREE_CODE (optype) == ARRAY_TYPE
1699 25081 : && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
1700 6946 : optype = TREE_TYPE (optype);
1701 :
1702 : /* Avoid arrays of pointers. */
1703 18135 : tree eltype = TREE_TYPE (optype);
1704 18135 : if (TREE_CODE (optype) != ARRAY_TYPE
1705 18135 : || !INTEGRAL_TYPE_P (eltype))
1706 : return false;
1707 :
1708 : /* Fail when the array bound is unknown or zero. */
1709 13626 : val = TYPE_SIZE_UNIT (optype);
1710 13626 : if (!val
1711 13554 : || TREE_CODE (val) != INTEGER_CST
1712 27152 : || integer_zerop (val))
1713 105 : return false;
1714 :
1715 13521 : 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 13521 : pdata->minlen = ssize_int (0);
1721 :
1722 13521 : tight_bound = true;
1723 : }
1724 138019 : else if (TREE_CODE (arg) == COMPONENT_REF
1725 138019 : && (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 9876 : tree fld = TREE_OPERAND (arg, 1);
1736 :
1737 9876 : tree optype = TREE_TYPE (fld);
1738 :
1739 : /* Determine the "innermost" array type. */
1740 9876 : while (TREE_CODE (optype) == ARRAY_TYPE
1741 10438 : && 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 9876 : val = TYPE_SIZE_UNIT (optype);
1746 9876 : if (!val
1747 9640 : || TREE_CODE (val) != INTEGER_CST
1748 19481 : || integer_zerop (val))
1749 350 : return false;
1750 9526 : 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 9526 : 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 9526 : tight_bound = true;
1764 : }
1765 128143 : else if (TREE_CODE (arg) == MEM_REF
1766 34227 : && TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
1767 10393 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == INTEGER_TYPE
1768 138098 : && 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 9955 : tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
1775 9955 : if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
1776 19897 : && (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 9829 : val = DECL_SIZE_UNIT (ref);
1782 9829 : if (!val
1783 9657 : || TREE_CODE (val) != INTEGER_CST
1784 19486 : || integer_zerop (val))
1785 371 : return false;
1786 :
1787 9655 : poly_offset_int psiz = wi::to_offset (val);
1788 9655 : poly_offset_int poff = mem_ref_offset (arg);
1789 9655 : if (known_le (psiz, poff))
1790 : return false;
1791 :
1792 9458 : pdata->minlen = ssize_int (0);
1793 :
1794 : /* Subtract the offset and one for the terminating nul. */
1795 9458 : psiz -= poff;
1796 9458 : psiz -= 1;
1797 9458 : 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 118188 : 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 70945 : tree argtype = TREE_TYPE (arg);
1808 70945 : if (TREE_CODE (argtype) == ARRAY_TYPE)
1809 : {
1810 42490 : val = TYPE_SIZE_UNIT (argtype);
1811 42490 : if (!val
1812 41724 : || TREE_CODE (val) != INTEGER_CST
1813 84214 : || integer_zerop (val))
1814 881 : return false;
1815 41609 : val = wide_int_to_tree (TREE_TYPE (val),
1816 41609 : 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 41609 : pdata->minlen = ssize_int (0);
1821 : }
1822 : }
1823 : maxbound = true;
1824 : }
1825 :
1826 352363 : if (!val)
1827 : return false;
1828 :
1829 : /* Adjust the lower bound on the string length as necessary. */
1830 252045 : if (!pdata->minlen
1831 252045 : || (rkind != SRK_STRLEN
1832 78687 : && TREE_CODE (pdata->minlen) == INTEGER_CST
1833 78687 : && TREE_CODE (val) == INTEGER_CST
1834 78682 : && tree_int_cst_lt (val, pdata->minlen)))
1835 173458 : pdata->minlen = val;
1836 :
1837 252045 : 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 7985 : if (TREE_CODE (val) == INTEGER_CST)
1843 : {
1844 7985 : if (tree_int_cst_lt (pdata->maxbound, val))
1845 740 : pdata->maxbound = val;
1846 : }
1847 : else
1848 0 : pdata->maxbound = val;
1849 : }
1850 244060 : 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 70873 : pdata->maxbound = val;
1855 :
1856 252045 : 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 23047 : if (rkind == SRK_LENRANGE)
1863 : {
1864 23047 : poly_int64 offset;
1865 23047 : tree base = get_addr_base_and_unit_offset (arg, &offset);
1866 23047 : if (!base)
1867 : {
1868 : /* When the call above fails due to a non-constant offset
1869 : assume the offset is zero and use the size of the whole
1870 : enclosing object instead. */
1871 7837 : base = get_base_address (arg);
1872 7837 : offset = 0;
1873 : }
1874 : /* If the base object is a pointer no upper bound on the length
1875 : can be determined. Otherwise the maximum length is equal to
1876 : the size of the enclosing object minus the offset of
1877 : the referenced subobject minus 1 (for the terminating nul). */
1878 23047 : tree type = TREE_TYPE (base);
1879 23047 : if (POINTER_TYPE_P (type)
1880 23043 : || (TREE_CODE (base) != PARM_DECL && !VAR_P (base))
1881 41749 : || !(val = DECL_SIZE_UNIT (base)))
1882 5592 : val = build_all_ones_cst (size_type_node);
1883 : else
1884 : {
1885 17455 : val = DECL_SIZE_UNIT (base);
1886 17455 : val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
1887 : size_int (offset + 1));
1888 : }
1889 : }
1890 : else
1891 : return false;
1892 : }
1893 :
1894 252045 : if (pdata->maxlen)
1895 : {
1896 : /* Adjust the more conservative bound if possible/necessary
1897 : and fail otherwise. */
1898 15057 : if (rkind != SRK_STRLEN)
1899 : {
1900 14126 : if (TREE_CODE (pdata->maxlen) != INTEGER_CST
1901 14126 : || TREE_CODE (val) != INTEGER_CST)
1902 : return false;
1903 :
1904 14121 : if (tree_int_cst_lt (pdata->maxlen, val))
1905 1463 : pdata->maxlen = val;
1906 14121 : 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 237112 : pdata->maxlen = val;
1917 237112 : 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 1360089 : get_range_strlen (tree arg, bitmap visited,
1938 : strlen_range_kind rkind,
1939 : c_strlen_data *pdata, unsigned eltsize)
1940 : {
1941 :
1942 1440413 : if (TREE_CODE (arg) != SSA_NAME)
1943 448407 : 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 992006 : if (name_registered_for_update_p (arg))
1948 : return false;
1949 :
1950 : /* If we were already here, break the infinite cycle. */
1951 992006 : if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
1952 : return true;
1953 :
1954 986452 : tree var = arg;
1955 986452 : gimple *def_stmt = SSA_NAME_DEF_STMT (var);
1956 :
1957 986452 : switch (gimple_code (def_stmt))
1958 : {
1959 123446 : 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 123446 : if (gimple_assign_single_p (def_stmt)
1964 123446 : || gimple_assign_unary_nop_p (def_stmt))
1965 : {
1966 80324 : tree rhs = gimple_assign_rhs1 (def_stmt);
1967 80324 : return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
1968 : }
1969 43122 : 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 82451 : for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
1997 : {
1998 59971 : 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 59971 : if (arg == gimple_phi_result (def_stmt))
2007 0 : continue;
2008 :
2009 59971 : if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
2010 : {
2011 28083 : 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 26349 : 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 1139247 : get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
2047 : {
2048 1139247 : auto_bitmap visited;
2049 1139247 : tree maxbound = pdata->maxbound;
2050 :
2051 1139247 : 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 915324 : pdata->minlen = ssize_int (0);
2057 915324 : pdata->maxlen = build_all_ones_cst (size_type_node);
2058 : }
2059 223923 : else if (!pdata->minlen)
2060 8530 : 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 1139247 : if (maxbound && pdata->maxbound == maxbound)
2065 650932 : pdata->maxbound = build_all_ones_cst (size_type_node);
2066 :
2067 1139247 : return !integer_all_onesp (pdata->maxlen);
2068 1139247 : }
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 96160 : 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 96160 : gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL);
2085 :
2086 : // If arg is already a constant, simply return it.
2087 96160 : 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 73233 : gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
2092 :
2093 73332 : auto_bitmap visited;
2094 :
2095 : /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
2096 : is unbounded. */
2097 73332 : c_strlen_data lendata = { };
2098 73332 : if (!get_range_strlen (arg, visited, rkind, &lendata, /* eltsize = */1))
2099 50094 : lendata.maxlen = NULL_TREE;
2100 23238 : else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
2101 0 : lendata.maxlen = NULL_TREE;
2102 :
2103 73332 : 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 24212 : *nonstr = lendata.decl;
2109 24212 : return lendata.maxlen;
2110 : }
2111 :
2112 : /* Fail if the constant array isn't nul-terminated. */
2113 49120 : return lendata.decl ? NULL_TREE : lendata.maxlen;
2114 73332 : }
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 63164 : known_lower (gimple *stmt, tree len, tree size, bool strict = false)
2122 : {
2123 63164 : if (len == NULL_TREE)
2124 : return false;
2125 :
2126 236250 : wide_int size_range[2];
2127 236250 : wide_int len_range[2];
2128 47250 : if (get_range (len, stmt, len_range) && get_range (size, stmt, size_range))
2129 : {
2130 16547 : if (strict)
2131 1859 : 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 283500 : }
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 26274 : gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
2145 : tree dest, tree src)
2146 : {
2147 26274 : gimple *stmt = gsi_stmt (*gsi);
2148 26274 : location_t loc = gimple_location (stmt);
2149 26274 : tree fn;
2150 :
2151 : /* If SRC and DEST are the same (and not volatile), return DEST. */
2152 26274 : 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 26188 : if (optimize_function_for_size_p (cfun))
2172 : return false;
2173 :
2174 24212 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2175 24212 : if (!fn)
2176 : return false;
2177 :
2178 : /* Set to non-null if ARG refers to an unterminated array. */
2179 24212 : tree nonstr = NULL;
2180 24212 : tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);
2181 :
2182 24212 : 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 29079 : if (!len || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
2192 : return false;
2193 :
2194 2891 : len = fold_convert_loc (loc, size_type_node, len);
2195 2891 : len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
2196 2891 : len = force_gimple_operand_gsi (gsi, len, true,
2197 : NULL_TREE, true, GSI_SAME_STMT);
2198 2891 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2199 2891 : replace_call_with_call_and_fold (gsi, repl);
2200 2891 : 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 17802 : 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 5471 : gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
2285 : {
2286 5471 : gimple *stmt = gsi_stmt (*gsi);
2287 5471 : tree str = gimple_call_arg (stmt, 0);
2288 5471 : tree c = gimple_call_arg (stmt, 1);
2289 5471 : location_t loc = gimple_location (stmt);
2290 5471 : const char *p;
2291 5471 : char ch;
2292 :
2293 5471 : 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 5461 : if (!check_nul_terminated_array (NULL_TREE, str))
2299 : return false;
2300 :
2301 5377 : 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 5418 : 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 5427 : 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 4478 : gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
2373 : {
2374 4478 : gimple *stmt = gsi_stmt (*gsi);
2375 4478 : if (!gimple_call_lhs (stmt))
2376 : return false;
2377 :
2378 4475 : tree haystack = gimple_call_arg (stmt, 0);
2379 4475 : 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 4475 : if (!check_nul_terminated_array (NULL_TREE, haystack)
2384 4475 : || !check_nul_terminated_array (NULL_TREE, needle))
2385 19 : return false;
2386 :
2387 4456 : const char *q = c_getstr (needle);
2388 4456 : if (q == NULL)
2389 : return false;
2390 :
2391 3252 : 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 3238 : if (q[0] == '\0')
2413 : {
2414 6 : replace_call_with_value (gsi, haystack);
2415 6 : return true;
2416 : }
2417 :
2418 10900 : if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
2419 : return false;
2420 :
2421 : /* Transform strstr (x, "c") into strchr (x, 'c'). */
2422 3232 : 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 7475 : gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
2457 : {
2458 7475 : gimple *stmt = gsi_stmt (*gsi);
2459 7475 : location_t loc = gimple_location (stmt);
2460 :
2461 7475 : const char *p = c_getstr (src);
2462 :
2463 : /* If the string length is zero, return the dst parameter. */
2464 7475 : if (p && *p == '\0')
2465 : {
2466 72 : replace_call_with_value (gsi, dst);
2467 72 : return true;
2468 : }
2469 :
2470 7403 : if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
2471 : return false;
2472 :
2473 20196 : 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 6816 : tree newdst;
2478 6816 : tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2479 6816 : tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2480 :
2481 6816 : 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 6816 : tree len = get_maxval_strlen (src, SRK_STRLEN);
2487 6816 : if (! len)
2488 : return false;
2489 :
2490 : /* Create strlen (dst). */
2491 839 : gimple_seq stmts = NULL, stmts2;
2492 839 : gimple *repl = gimple_build_call (strlen_fn, 1, dst);
2493 839 : gimple_set_location (repl, loc);
2494 839 : newdst = make_ssa_name (size_type_node);
2495 839 : gimple_call_set_lhs (repl, newdst);
2496 839 : gimple_seq_add_stmt_without_update (&stmts, repl);
2497 :
2498 : /* Create (dst p+ strlen (dst)). */
2499 839 : newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
2500 839 : newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE);
2501 839 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2502 :
2503 839 : len = fold_convert_loc (loc, size_type_node, len);
2504 839 : len = size_binop_loc (loc, PLUS_EXPR, len,
2505 : build_int_cst (size_type_node, 1));
2506 839 : len = force_gimple_operand (len, &stmts2, true, NULL_TREE);
2507 839 : gimple_seq_add_seq_without_update (&stmts, stmts2);
2508 :
2509 839 : repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
2510 839 : gimple_seq_add_stmt_without_update (&stmts, repl);
2511 839 : 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 674 : gsi_replace_with_seq_vops (gsi, stmts);
2527 674 : 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 1351 : return false;
2555 :
2556 1515 : 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 6099 : 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 6803 : 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 2988 : 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 469 : gimple_load_first_char (location_t loc, tree str, gimple_seq *stmts)
2717 : {
2718 469 : tree var;
2719 :
2720 469 : tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2721 469 : tree cst_uchar_ptr_node
2722 469 : = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
2723 469 : tree off0 = build_int_cst (cst_uchar_ptr_node, 0);
2724 :
2725 469 : tree temp = fold_build2_loc (loc, MEM_REF, cst_uchar_node, str, off0);
2726 469 : gassign *stmt = gimple_build_assign (NULL_TREE, temp);
2727 469 : var = make_ssa_name (cst_uchar_node, stmt);
2728 :
2729 469 : gimple_assign_set_lhs (stmt, var);
2730 469 : gimple_seq_add_stmt_without_update (stmts, stmt);
2731 :
2732 469 : return var;
2733 : }
2734 :
2735 : /* Fold a call to the str{n}{case}cmp builtin pointed by GSI iterator. */
2736 :
2737 : static bool
2738 1250740 : gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
2739 : {
2740 1250740 : gimple *stmt = gsi_stmt (*gsi);
2741 1250740 : tree callee = gimple_call_fndecl (stmt);
2742 1250740 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
2743 :
2744 1250740 : tree type = integer_type_node;
2745 1250740 : tree str1 = gimple_call_arg (stmt, 0);
2746 1250740 : tree str2 = gimple_call_arg (stmt, 1);
2747 1250740 : tree lhs = gimple_call_lhs (stmt);
2748 :
2749 1250740 : tree bound_node = NULL_TREE;
2750 1250740 : unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;
2751 :
2752 : /* Handle strncmp and strncasecmp functions. */
2753 1250740 : if (gimple_call_num_args (stmt) == 3)
2754 : {
2755 22968 : bound_node = gimple_call_arg (stmt, 2);
2756 22968 : if (tree_fits_uhwi_p (bound_node))
2757 17244 : bound = tree_to_uhwi (bound_node);
2758 : }
2759 :
2760 : /* If the BOUND parameter is zero, return zero. */
2761 17244 : 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 1250736 : 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 2501390 : 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 1250695 : unsigned HOST_WIDE_INT len1 = HOST_WIDE_INT_MAX, len2 = len1;
2783 1250695 : const char *p1 = getbyterep (str1, &len1);
2784 1250695 : 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 1250695 : unsigned HOST_WIDE_INT nulpos1 = HOST_WIDE_INT_MAX, nulpos2 = nulpos1;
2789 :
2790 1250695 : if (p1)
2791 : {
2792 42807 : size_t n = strnlen (p1, len1);
2793 42807 : if (n < len1)
2794 42700 : len1 = nulpos1 = n;
2795 : }
2796 :
2797 1250695 : if (p2)
2798 : {
2799 1219635 : size_t n = strnlen (p2, len2);
2800 1219635 : if (n < len2)
2801 1219576 : len2 = nulpos2 = n;
2802 : }
2803 :
2804 : /* For known strings, return an immediate value. */
2805 1250695 : 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 2425026 : bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U)
2869 1195413 : || fcode == BUILT_IN_STRCMP
2870 1195413 : || fcode == BUILT_IN_STRCMP_EQ
2871 1218415 : || fcode == BUILT_IN_STRCASECMP;
2872 :
2873 1212513 : location_t loc = gimple_location (stmt);
2874 :
2875 : /* If the second arg is "", return *(const unsigned char*)arg1. */
2876 1212513 : 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 1212363 : 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 1212264 : 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 1212154 : if (fcode == BUILT_IN_STRNCMP
2940 17706 : && bound > 0 && bound < HOST_WIDE_INT_M1U
2941 12114 : && ((p2 && len2 < bound && len2 == nulpos2)
2942 11882 : || (p1 && len1 < bound && len1 == nulpos1)))
2943 : {
2944 1212154 : 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 31742 : gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
2959 : {
2960 31742 : gimple *stmt = gsi_stmt (*gsi);
2961 31742 : tree lhs = gimple_call_lhs (stmt);
2962 31742 : tree arg1 = gimple_call_arg (stmt, 0);
2963 31742 : tree arg2 = gimple_call_arg (stmt, 1);
2964 31742 : tree len = gimple_call_arg (stmt, 2);
2965 :
2966 : /* If the LEN parameter is zero, return zero. */
2967 31742 : 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 31741 : char c;
2974 31741 : if (TREE_CODE (arg2) != INTEGER_CST
2975 17583 : || !tree_fits_uhwi_p (len)
2976 32455 : || !target_char_cst_p (arg2, &c))
2977 31027 : return false;
2978 :
2979 714 : unsigned HOST_WIDE_INT length = tree_to_uhwi (len);
2980 714 : unsigned HOST_WIDE_INT string_length;
2981 714 : const char *p1 = getbyterep (arg1, &string_length);
2982 :
2983 714 : if (p1)
2984 : {
2985 96 : const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
2986 96 : if (r == NULL)
2987 : {
2988 14 : tree mem_size, offset_node;
2989 14 : byte_representation (arg1, &offset_node, &mem_size, NULL);
2990 14 : unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
2991 14 : ? 0 : tree_to_uhwi (offset_node);
2992 : /* MEM_SIZE is the size of the array the string literal
2993 : is stored in. */
2994 14 : unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
2995 14 : gcc_checking_assert (string_length <= string_size);
2996 14 : if (length <= string_size)
2997 : {
2998 4 : replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
2999 4 : return true;
3000 : }
3001 : }
3002 : else
3003 : {
3004 82 : unsigned HOST_WIDE_INT offset = r - p1;
3005 82 : gimple_seq stmts = NULL;
3006 82 : if (lhs != NULL_TREE)
3007 : {
3008 80 : tree offset_cst = build_int_cst (sizetype, offset);
3009 80 : gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
3010 : arg1, offset_cst);
3011 80 : gimple_seq_add_stmt_without_update (&stmts, stmt);
3012 : }
3013 : else
3014 2 : gimple_seq_add_stmt_without_update (&stmts,
3015 : gimple_build_nop ());
3016 :
3017 82 : gsi_replace_with_seq_vops (gsi, stmts);
3018 82 : return true;
3019 : }
3020 : }
3021 :
3022 : return false;
3023 : }
3024 :
3025 : /* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
3026 : to the call. IGNORE is true if the value returned
3027 : by the builtin will be ignored. UNLOCKED is true is true if this
3028 : actually a call to fputs_unlocked. If LEN in non-NULL, it represents
3029 : the known length of the string. Return NULL_TREE if no simplification
3030 : was possible. */
3031 :
3032 : static bool
3033 20775 : gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
3034 : tree arg0, tree arg1,
3035 : bool unlocked)
3036 : {
3037 20775 : gimple *stmt = gsi_stmt (*gsi);
3038 :
3039 : /* If we're using an unlocked function, assume the other unlocked
3040 : functions exist explicitly. */
3041 20775 : tree const fn_fputc = (unlocked
3042 20775 : ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
3043 20732 : : builtin_decl_implicit (BUILT_IN_FPUTC));
3044 20732 : tree const fn_fwrite = (unlocked
3045 43 : ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
3046 20775 : : builtin_decl_implicit (BUILT_IN_FWRITE));
3047 :
3048 : /* If the return value is used, don't do the transformation. */
3049 20775 : 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 20704 : tree len = get_maxval_strlen (arg0, SRK_STRLEN);
3055 20704 : if (!len || TREE_CODE (len) != INTEGER_CST)
3056 : return false;
3057 :
3058 16268 : 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 15127 : case 1: /* length is greater than 1, call fwrite. */
3082 15127 : {
3083 : /* If optimizing for size keep fputs. */
3084 15127 : 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 27918 : if (!fn_fwrite || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3089 : return false;
3090 :
3091 8284 : gimple *repl
3092 8284 : = gimple_build_call (fn_fwrite, 4, arg0, size_one_node,
3093 : fold_convert (size_type_node, len), arg1);
3094 8284 : replace_call_with_call_and_fold (gsi, repl);
3095 8284 : return true;
3096 : }
3097 0 : default:
3098 0 : gcc_unreachable ();
3099 : }
3100 : }
3101 :
3102 : /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
3103 : DEST, SRC, LEN, and SIZE are the arguments to the call.
3104 : IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
3105 : code of the builtin. If MAXLEN is not NULL, it is maximum length
3106 : passed as third argument. */
3107 :
3108 : static bool
3109 25701 : gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
3110 : tree dest, tree src, tree len, tree size,
3111 : enum built_in_function fcode)
3112 : {
3113 25701 : gimple *stmt = gsi_stmt (*gsi);
3114 25701 : location_t loc = gimple_location (stmt);
3115 25701 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3116 25701 : tree fn;
3117 :
3118 : /* If SRC and DEST are the same (and not volatile), return DEST
3119 : (resp. DEST+LEN for __mempcpy_chk). */
3120 25701 : if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
3121 : {
3122 13 : if (fcode != BUILT_IN_MEMPCPY_CHK)
3123 : {
3124 7 : replace_call_with_value (gsi, dest);
3125 7 : return true;
3126 : }
3127 : else
3128 : {
3129 6 : gimple_seq stmts = NULL;
3130 6 : len = gimple_convert_to_ptrofftype (&stmts, loc, len);
3131 6 : tree temp = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
3132 6 : TREE_TYPE (dest), dest, len);
3133 6 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3134 6 : replace_call_with_value (gsi, temp);
3135 6 : return true;
3136 : }
3137 : }
3138 :
3139 68495 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3140 : return false;
3141 :
3142 25688 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3143 25688 : if (! integer_all_onesp (size)
3144 24689 : && !known_lower (stmt, len, size)
3145 42927 : && !known_lower (stmt, maxlen, size))
3146 : {
3147 : /* MAXLEN and LEN both cannot be proved to be less than SIZE, at
3148 : least try to optimize (void) __mempcpy_chk () into
3149 : (void) __memcpy_chk () */
3150 17162 : if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
3151 : {
3152 43 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3153 43 : if (!fn)
3154 : return false;
3155 :
3156 43 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3157 43 : replace_call_with_call_and_fold (gsi, repl);
3158 43 : return true;
3159 : }
3160 : return false;
3161 : }
3162 :
3163 8526 : fn = NULL_TREE;
3164 : /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
3165 : mem{cpy,pcpy,move,set} is available. */
3166 8526 : switch (fcode)
3167 : {
3168 1781 : case BUILT_IN_MEMCPY_CHK:
3169 1781 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
3170 1781 : break;
3171 1068 : case BUILT_IN_MEMPCPY_CHK:
3172 1068 : fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
3173 1068 : break;
3174 1652 : case BUILT_IN_MEMMOVE_CHK:
3175 1652 : fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
3176 1652 : break;
3177 4025 : case BUILT_IN_MEMSET_CHK:
3178 4025 : fn = builtin_decl_explicit (BUILT_IN_MEMSET);
3179 4025 : break;
3180 : default:
3181 : break;
3182 : }
3183 :
3184 8526 : if (!fn)
3185 : return false;
3186 :
3187 8526 : gimple *repl = gimple_build_call (fn, 3, dest, src, len);
3188 8526 : replace_call_with_call_and_fold (gsi, repl);
3189 8526 : return true;
3190 : }
3191 :
3192 : /* Fold a call to the __st[rp]cpy_chk builtin.
3193 : DEST, SRC, and SIZE are the arguments to the call.
3194 : IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
3195 : code of the builtin. If MAXLEN is not NULL, it is maximum length of
3196 : strings passed as second argument. */
3197 :
3198 : static bool
3199 2566 : gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
3200 : tree dest,
3201 : tree src, tree size,
3202 : enum built_in_function fcode)
3203 : {
3204 2566 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3205 2566 : location_t loc = gimple_location (stmt);
3206 2566 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3207 2566 : tree len, fn;
3208 :
3209 : /* If SRC and DEST are the same (and not volatile), return DEST. */
3210 2566 : if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
3211 : {
3212 : /* Issue -Wrestrict unless the pointers are null (those do
3213 : not point to objects and so do not indicate an overlap;
3214 : such calls could be the result of sanitization and jump
3215 : threading). */
3216 0 : if (!integer_zerop (dest)
3217 0 : && !warning_suppressed_p (stmt, OPT_Wrestrict))
3218 : {
3219 0 : tree func = gimple_call_fndecl (stmt);
3220 :
3221 0 : warning_at (loc, OPT_Wrestrict,
3222 : "%qD source argument is the same as destination",
3223 : func);
3224 : }
3225 :
3226 0 : replace_call_with_value (gsi, dest);
3227 0 : return true;
3228 : }
3229 :
3230 5132 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3231 : return false;
3232 :
3233 2566 : tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
3234 2566 : if (! integer_all_onesp (size))
3235 : {
3236 2497 : len = c_strlen (src, 1);
3237 2497 : if (!known_lower (stmt, len, size, true)
3238 2497 : && !known_lower (stmt, maxlen, size, true))
3239 : {
3240 2185 : if (fcode == BUILT_IN_STPCPY_CHK)
3241 : {
3242 1077 : if (! ignore)
3243 : return false;
3244 :
3245 : /* If return value of __stpcpy_chk is ignored,
3246 : optimize into __strcpy_chk. */
3247 35 : fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
3248 35 : if (!fn)
3249 : return false;
3250 :
3251 35 : gimple *repl = gimple_build_call (fn, 3, dest, src, size);
3252 35 : replace_call_with_call_and_fold (gsi, repl);
3253 35 : return true;
3254 : }
3255 :
3256 1108 : if (! len || TREE_SIDE_EFFECTS (len))
3257 : return false;
3258 :
3259 : /* If c_strlen returned something, but not provably less than size,
3260 : transform __strcpy_chk into __memcpy_chk. */
3261 106 : fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3262 106 : if (!fn)
3263 : return false;
3264 :
3265 106 : gimple_seq stmts = NULL;
3266 106 : len = force_gimple_operand (len, &stmts, true, NULL_TREE);
3267 106 : len = gimple_convert (&stmts, loc, size_type_node, len);
3268 106 : len = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node, len,
3269 : build_int_cst (size_type_node, 1));
3270 106 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3271 106 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3272 106 : replace_call_with_call_and_fold (gsi, repl);
3273 106 : return true;
3274 : }
3275 : }
3276 :
3277 : /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
3278 618 : fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK && !ignore
3279 : ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
3280 381 : if (!fn)
3281 : return false;
3282 :
3283 381 : gcall *repl = gimple_build_call (fn, 2, dest, src);
3284 381 : replace_call_with_call_and_fold (gsi, repl);
3285 381 : return true;
3286 : }
3287 :
3288 : /* Fold a call to the __st{r,p}ncpy_chk builtin. DEST, SRC, LEN, and SIZE
3289 : are the arguments to the call. If MAXLEN is not NULL, it is maximum
3290 : length passed as third argument. IGNORE is true if return value can be
3291 : ignored. FCODE is the BUILT_IN_* code of the builtin. */
3292 :
3293 : static bool
3294 2721 : gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
3295 : tree dest, tree src,
3296 : tree len, tree size,
3297 : enum built_in_function fcode)
3298 : {
3299 2721 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3300 2721 : bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
3301 2721 : tree fn;
3302 :
3303 2721 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3304 2721 : if (! integer_all_onesp (size)
3305 2721 : && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3306 : {
3307 2264 : if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
3308 : {
3309 : /* If return value of __stpncpy_chk is ignored,
3310 : optimize into __strncpy_chk. */
3311 39 : fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
3312 39 : if (fn)
3313 : {
3314 39 : gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3315 39 : replace_call_with_call_and_fold (gsi, repl);
3316 39 : return true;
3317 : }
3318 : }
3319 : return false;
3320 : }
3321 :
3322 : /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */
3323 717 : fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK && !ignore
3324 : ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
3325 3139 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3326 : return false;
3327 :
3328 457 : gcall *repl = gimple_build_call (fn, 3, dest, src, len);
3329 457 : replace_call_with_call_and_fold (gsi, repl);
3330 457 : return true;
3331 : }
3332 :
3333 : /* Fold function call to builtin stpcpy with arguments DEST and SRC.
3334 : Return NULL_TREE if no simplification can be made. */
3335 :
3336 : static bool
3337 3674 : gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
3338 : {
3339 3674 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3340 3674 : location_t loc = gimple_location (stmt);
3341 3674 : tree dest = gimple_call_arg (stmt, 0);
3342 3674 : tree src = gimple_call_arg (stmt, 1);
3343 3674 : tree fn, lenp1;
3344 :
3345 7348 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3346 : return false;
3347 :
3348 : /* If the result is unused, replace stpcpy with strcpy. */
3349 3674 : if (gimple_call_lhs (stmt) == NULL_TREE)
3350 : {
3351 29 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3352 29 : if (!fn)
3353 : return false;
3354 29 : gimple_call_set_fndecl (stmt, fn);
3355 29 : fold_stmt (gsi);
3356 29 : return true;
3357 : }
3358 :
3359 : /* Set to non-null if ARG refers to an unterminated array. */
3360 3645 : c_strlen_data data = { };
3361 : /* The size of the unterminated array if SRC refers to one. */
3362 3645 : tree size;
3363 : /* True if the size is exact/constant, false if it's the lower bound
3364 : of a range. */
3365 3645 : bool exact;
3366 3645 : tree len = c_strlen (src, 1, &data, 1);
3367 3645 : if (!len
3368 703 : || TREE_CODE (len) != INTEGER_CST)
3369 : {
3370 3174 : data.decl = unterminated_array (src, &size, &exact);
3371 3174 : if (!data.decl)
3372 : return false;
3373 : }
3374 :
3375 1076 : if (data.decl)
3376 : {
3377 : /* Avoid folding calls with unterminated arrays. */
3378 605 : if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
3379 75 : warn_string_no_nul (loc, stmt, "stpcpy", src, data.decl, size,
3380 : exact);
3381 605 : suppress_warning (stmt, OPT_Wstringop_overread);
3382 605 : return false;
3383 : }
3384 :
3385 471 : if (optimize_function_for_size_p (cfun)
3386 : /* If length is zero it's small enough. */
3387 471 : && !integer_zerop (len))
3388 : return false;
3389 :
3390 : /* If the source has a known length replace stpcpy with memcpy. */
3391 3645 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3392 287 : if (!fn)
3393 : return false;
3394 :
3395 287 : gimple_seq stmts = NULL;
3396 287 : tree tem = gimple_convert (&stmts, loc, size_type_node, len);
3397 287 : lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
3398 : tem, build_int_cst (size_type_node, 1));
3399 287 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3400 287 : gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
3401 287 : gimple_move_vops (repl, stmt);
3402 287 : gsi_insert_before (gsi, repl, GSI_SAME_STMT);
3403 : /* Replace the result with dest + len. */
3404 287 : stmts = NULL;
3405 287 : tem = gimple_convert (&stmts, loc, sizetype, len);
3406 287 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3407 287 : gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
3408 : POINTER_PLUS_EXPR, dest, tem);
3409 287 : gsi_replace (gsi, ret, false);
3410 : /* Finally fold the memcpy call. */
3411 287 : gimple_stmt_iterator gsi2 = *gsi;
3412 287 : gsi_prev (&gsi2);
3413 287 : fold_stmt (&gsi2);
3414 287 : return true;
3415 : }
3416 :
3417 : /* Simplify mempcpy call stmt at GSI, returning true if simplified.
3418 : Currently only handling mempcpy -> memcpy when the return value
3419 : is ignored. */
3420 :
3421 : static bool
3422 9536 : gimple_fold_builtin_mempcpy (gimple_stmt_iterator *gsi)
3423 : {
3424 9536 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3425 :
3426 9536 : if (gimple_call_lhs (stmt) != NULL_TREE)
3427 : return false;
3428 :
3429 385 : tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
3430 385 : if (!fn)
3431 : return false;
3432 :
3433 385 : tree dest = gimple_call_arg (stmt, 0);
3434 385 : tree src = gimple_call_arg (stmt, 1);
3435 385 : tree n = gimple_call_arg (stmt, 2);
3436 :
3437 385 : gcall *repl = gimple_build_call (fn, 3, dest, src, n);
3438 385 : replace_call_with_call_and_fold (gsi, repl);
3439 :
3440 385 : return true;
3441 : }
3442 :
3443 : /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS. Return
3444 : NULL_TREE if a normal call should be emitted rather than expanding
3445 : the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
3446 : BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
3447 : passed as second argument. */
3448 :
3449 : static bool
3450 2359 : gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
3451 : enum built_in_function fcode)
3452 : {
3453 2359 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3454 2359 : tree dest, size, len, fn, fmt, flag;
3455 2359 : const char *fmt_str;
3456 :
3457 : /* Verify the required arguments in the original call. */
3458 2359 : if (gimple_call_num_args (stmt) < 5)
3459 : return false;
3460 :
3461 2359 : dest = gimple_call_arg (stmt, 0);
3462 2359 : len = gimple_call_arg (stmt, 1);
3463 2359 : flag = gimple_call_arg (stmt, 2);
3464 2359 : size = gimple_call_arg (stmt, 3);
3465 2359 : fmt = gimple_call_arg (stmt, 4);
3466 :
3467 2359 : tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3468 2359 : if (! integer_all_onesp (size)
3469 2359 : && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3470 : return false;
3471 :
3472 308 : if (!init_target_chars ())
3473 : return false;
3474 :
3475 : /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
3476 : or if format doesn't contain % chars or is "%s". */
3477 308 : if (! integer_zerop (flag))
3478 : {
3479 52 : fmt_str = c_getstr (fmt);
3480 52 : if (fmt_str == NULL)
3481 : return false;
3482 52 : if (strchr (fmt_str, target_percent) != NULL
3483 51 : && strcmp (fmt_str, target_percent_s))
3484 : return false;
3485 : }
3486 :
3487 : /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
3488 : available. */
3489 415 : fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
3490 : ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
3491 2618 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3492 : return false;
3493 :
3494 : /* Replace the called function and the first 5 argument by 3 retaining
3495 : trailing varargs. */
3496 259 : gimple_call_set_fndecl (stmt, fn);
3497 259 : gimple_call_set_fntype (stmt, TREE_TYPE (fn));
3498 259 : gimple_call_set_arg (stmt, 0, dest);
3499 259 : gimple_call_set_arg (stmt, 1, len);
3500 259 : gimple_call_set_arg (stmt, 2, fmt);
3501 546 : for (unsigned i = 3; i < gimple_call_num_args (stmt) - 2; ++i)
3502 287 : gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3503 259 : gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3504 259 : fold_stmt (gsi);
3505 259 : return true;
3506 : }
3507 :
3508 : /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
3509 : Return NULL_TREE if a normal call should be emitted rather than
3510 : expanding the function inline. FCODE is either BUILT_IN_SPRINTF_CHK
3511 : or BUILT_IN_VSPRINTF_CHK. */
3512 :
3513 : static bool
3514 4459 : gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
3515 : enum built_in_function fcode)
3516 : {
3517 4459 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3518 4459 : tree dest, size, len, fn, fmt, flag;
3519 4459 : const char *fmt_str;
3520 4459 : unsigned nargs = gimple_call_num_args (stmt);
3521 :
3522 : /* Verify the required arguments in the original call. */
3523 4459 : if (nargs < 4)
3524 : return false;
3525 4459 : dest = gimple_call_arg (stmt, 0);
3526 4459 : flag = gimple_call_arg (stmt, 1);
3527 4459 : size = gimple_call_arg (stmt, 2);
3528 4459 : fmt = gimple_call_arg (stmt, 3);
3529 :
3530 4459 : len = NULL_TREE;
3531 :
3532 4459 : if (!init_target_chars ())
3533 : return false;
3534 :
3535 : /* Check whether the format is a literal string constant. */
3536 4459 : fmt_str = c_getstr (fmt);
3537 4459 : if (fmt_str != NULL)
3538 : {
3539 : /* If the format doesn't contain % args or %%, we know the size. */
3540 4069 : if (strchr (fmt_str, target_percent) == 0)
3541 : {
3542 251 : if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
3543 251 : len = build_int_cstu (size_type_node, strlen (fmt_str));
3544 : }
3545 : /* If the format is "%s" and first ... argument is a string literal,
3546 : we know the size too. */
3547 3818 : else if (fcode == BUILT_IN_SPRINTF_CHK
3548 2962 : && strcmp (fmt_str, target_percent_s) == 0)
3549 : {
3550 395 : tree arg;
3551 :
3552 395 : if (nargs == 5)
3553 : {
3554 395 : arg = gimple_call_arg (stmt, 4);
3555 395 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
3556 363 : len = c_strlen (arg, 1);
3557 : }
3558 : }
3559 : }
3560 :
3561 4459 : if (! integer_all_onesp (size) && !known_lower (stmt, len, size, true))
3562 : return false;
3563 :
3564 : /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
3565 : or if format doesn't contain % chars or is "%s". */
3566 202 : if (! integer_zerop (flag))
3567 : {
3568 1 : if (fmt_str == NULL)
3569 : return false;
3570 1 : if (strchr (fmt_str, target_percent) != NULL
3571 0 : && strcmp (fmt_str, target_percent_s))
3572 : return false;
3573 : }
3574 :
3575 : /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
3576 347 : fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
3577 : ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
3578 4661 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3579 : return false;
3580 :
3581 : /* Replace the called function and the first 4 argument by 2 retaining
3582 : trailing varargs. */
3583 202 : gimple_call_set_fndecl (stmt, fn);
3584 202 : gimple_call_set_fntype (stmt, TREE_TYPE (fn));
3585 202 : gimple_call_set_arg (stmt, 0, dest);
3586 202 : gimple_call_set_arg (stmt, 1, fmt);
3587 400 : for (unsigned i = 2; i < gimple_call_num_args (stmt) - 2; ++i)
3588 198 : gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3589 202 : gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3590 202 : fold_stmt (gsi);
3591 202 : return true;
3592 : }
3593 :
3594 : /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
3595 : ORIG may be null if this is a 2-argument call. We don't attempt to
3596 : simplify calls with more than 3 arguments.
3597 :
3598 : Return true if simplification was possible, otherwise false. */
3599 :
3600 : bool
3601 2284 : gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
3602 : {
3603 2284 : gimple *stmt = gsi_stmt (*gsi);
3604 :
3605 : /* Verify the required arguments in the original call. We deal with two
3606 : types of sprintf() calls: 'sprintf (str, fmt)' and
3607 : 'sprintf (dest, "%s", orig)'. */
3608 2284 : if (gimple_call_num_args (stmt) > 3)
3609 : return false;
3610 :
3611 1883 : tree orig = NULL_TREE;
3612 1883 : if (gimple_call_num_args (stmt) == 3)
3613 1785 : orig = gimple_call_arg (stmt, 2);
3614 :
3615 : /* Check whether the format is a literal string constant. */
3616 1883 : tree fmt = gimple_call_arg (stmt, 1);
3617 1883 : const char *fmt_str = c_getstr (fmt);
3618 1883 : if (fmt_str == NULL)
3619 : return false;
3620 :
3621 1883 : tree dest = gimple_call_arg (stmt, 0);
3622 :
3623 1883 : if (!init_target_chars ())
3624 : return false;
3625 :
3626 1883 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3627 5192 : if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3628 : return false;
3629 :
3630 : /* If the format doesn't contain % args or %%, use strcpy. */
3631 1883 : if (strchr (fmt_str, target_percent) == NULL)
3632 : {
3633 : /* Don't optimize sprintf (buf, "abc", ptr++). */
3634 110 : if (orig)
3635 : return false;
3636 :
3637 : /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
3638 : 'format' is known to contain no % formats. */
3639 97 : gimple_seq stmts = NULL;
3640 97 : gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3641 :
3642 : /* Propagate the NO_WARNING bit to avoid issuing the same
3643 : warning more than once. */
3644 97 : copy_warning (repl, stmt);
3645 :
3646 97 : gimple_seq_add_stmt_without_update (&stmts, repl);
3647 97 : if (tree lhs = gimple_call_lhs (stmt))
3648 : {
3649 0 : repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs),
3650 0 : strlen (fmt_str)));
3651 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3652 0 : gsi_replace_with_seq_vops (gsi, stmts);
3653 : /* gsi now points at the assignment to the lhs, get a
3654 : stmt iterator to the memcpy call.
3655 : ??? We can't use gsi_for_stmt as that doesn't work when the
3656 : CFG isn't built yet. */
3657 0 : gimple_stmt_iterator gsi2 = *gsi;
3658 0 : gsi_prev (&gsi2);
3659 0 : fold_stmt (&gsi2);
3660 : }
3661 : else
3662 : {
3663 97 : gsi_replace_with_seq_vops (gsi, stmts);
3664 97 : fold_stmt (gsi);
3665 : }
3666 97 : return true;
3667 : }
3668 :
3669 : /* If the format is "%s", use strcpy if the result isn't used. */
3670 1773 : else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3671 : {
3672 : /* Don't crash on sprintf (str1, "%s"). */
3673 748 : if (!orig)
3674 : return false;
3675 :
3676 : /* Don't fold calls with source arguments of invalid (nonpointer)
3677 : types. */
3678 747 : if (!POINTER_TYPE_P (TREE_TYPE (orig)))
3679 : return false;
3680 :
3681 741 : tree orig_len = NULL_TREE;
3682 741 : if (gimple_call_lhs (stmt))
3683 : {
3684 17 : orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3685 17 : if (!orig_len)
3686 : return false;
3687 : }
3688 :
3689 : /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
3690 724 : gimple_seq stmts = NULL;
3691 724 : gimple *repl = gimple_build_call (fn, 2, dest, orig);
3692 :
3693 : /* Propagate the NO_WARNING bit to avoid issuing the same
3694 : warning more than once. */
3695 724 : copy_warning (repl, stmt);
3696 :
3697 724 : gimple_seq_add_stmt_without_update (&stmts, repl);
3698 724 : if (tree lhs = gimple_call_lhs (stmt))
3699 : {
3700 0 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
3701 0 : TREE_TYPE (orig_len)))
3702 0 : orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
3703 0 : repl = gimple_build_assign (lhs, orig_len);
3704 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3705 0 : gsi_replace_with_seq_vops (gsi, stmts);
3706 : /* gsi now points at the assignment to the lhs, get a
3707 : stmt iterator to the memcpy call.
3708 : ??? We can't use gsi_for_stmt as that doesn't work when the
3709 : CFG isn't built yet. */
3710 0 : gimple_stmt_iterator gsi2 = *gsi;
3711 0 : gsi_prev (&gsi2);
3712 0 : fold_stmt (&gsi2);
3713 : }
3714 : else
3715 : {
3716 724 : gsi_replace_with_seq_vops (gsi, stmts);
3717 724 : fold_stmt (gsi);
3718 : }
3719 724 : return true;
3720 : }
3721 : return false;
3722 : }
3723 :
3724 : /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
3725 : FMT, and ORIG. ORIG may be null if this is a 3-argument call. We don't
3726 : attempt to simplify calls with more than 4 arguments.
3727 :
3728 : Return true if simplification was possible, otherwise false. */
3729 :
3730 : bool
3731 1733 : gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
3732 : {
3733 1733 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3734 1733 : tree dest = gimple_call_arg (stmt, 0);
3735 1733 : tree destsize = gimple_call_arg (stmt, 1);
3736 1733 : tree fmt = gimple_call_arg (stmt, 2);
3737 1733 : tree orig = NULL_TREE;
3738 1733 : const char *fmt_str = NULL;
3739 :
3740 1733 : if (gimple_call_num_args (stmt) > 4
3741 2991 : || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
3742 : return false;
3743 :
3744 812 : if (gimple_call_num_args (stmt) == 4)
3745 613 : orig = gimple_call_arg (stmt, 3);
3746 :
3747 : /* Check whether the format is a literal string constant. */
3748 812 : fmt_str = c_getstr (fmt);
3749 812 : if (fmt_str == NULL)
3750 : return false;
3751 :
3752 812 : if (!init_target_chars ())
3753 : return false;
3754 :
3755 : /* If the format doesn't contain % args or %%, use strcpy. */
3756 812 : if (strchr (fmt_str, target_percent) == NULL)
3757 : {
3758 228 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3759 198 : if (!fn)
3760 : return false;
3761 :
3762 : /* Don't optimize snprintf (buf, 4, "abc", ptr++). */
3763 198 : if (orig)
3764 : return false;
3765 :
3766 198 : tree len = build_int_cstu (TREE_TYPE (destsize), strlen (fmt_str));
3767 :
3768 : /* We could expand this as
3769 : memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
3770 : or to
3771 : memcpy (str, fmt_with_nul_at_cstm1, cst);
3772 : but in the former case that might increase code size
3773 : and in the latter case grow .rodata section too much.
3774 : So punt for now. */
3775 198 : if (!known_lower (stmt, len, destsize, true))
3776 : return false;
3777 :
3778 168 : gimple_seq stmts = NULL;
3779 168 : gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3780 168 : gimple_seq_add_stmt_without_update (&stmts, repl);
3781 168 : if (tree lhs = gimple_call_lhs (stmt))
3782 : {
3783 0 : repl = gimple_build_assign (lhs,
3784 0 : fold_convert (TREE_TYPE (lhs), len));
3785 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3786 0 : gsi_replace_with_seq_vops (gsi, stmts);
3787 : /* gsi now points at the assignment to the lhs, get a
3788 : stmt iterator to the memcpy call.
3789 : ??? We can't use gsi_for_stmt as that doesn't work when the
3790 : CFG isn't built yet. */
3791 0 : gimple_stmt_iterator gsi2 = *gsi;
3792 0 : gsi_prev (&gsi2);
3793 0 : fold_stmt (&gsi2);
3794 : }
3795 : else
3796 : {
3797 168 : gsi_replace_with_seq_vops (gsi, stmts);
3798 168 : fold_stmt (gsi);
3799 : }
3800 168 : return true;
3801 : }
3802 :
3803 : /* If the format is "%s", use strcpy if the result isn't used. */
3804 614 : else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3805 : {
3806 292 : tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3807 174 : if (!fn)
3808 : return false;
3809 :
3810 : /* Don't crash on snprintf (str1, cst, "%s"). */
3811 174 : if (!orig)
3812 : return false;
3813 :
3814 174 : tree orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3815 :
3816 : /* We could expand this as
3817 : memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
3818 : or to
3819 : memcpy (str1, str2_with_nul_at_cstm1, cst);
3820 : but in the former case that might increase code size
3821 : and in the latter case grow .rodata section too much.
3822 : So punt for now. */
3823 174 : if (!known_lower (stmt, orig_len, destsize, true))
3824 : return false;
3825 :
3826 : /* Convert snprintf (str1, cst, "%s", str2) into
3827 : strcpy (str1, str2) if strlen (str2) < cst. */
3828 56 : gimple_seq stmts = NULL;
3829 56 : gimple *repl = gimple_build_call (fn, 2, dest, orig);
3830 56 : gimple_seq_add_stmt_without_update (&stmts, repl);
3831 56 : if (tree lhs = gimple_call_lhs (stmt))
3832 : {
3833 0 : if (!useless_type_conversion_p (TREE_TYPE (lhs),
3834 0 : TREE_TYPE (orig_len)))
3835 0 : orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
3836 0 : repl = gimple_build_assign (lhs, orig_len);
3837 0 : gimple_seq_add_stmt_without_update (&stmts, repl);
3838 0 : gsi_replace_with_seq_vops (gsi, stmts);
3839 : /* gsi now points at the assignment to the lhs, get a
3840 : stmt iterator to the memcpy call.
3841 : ??? We can't use gsi_for_stmt as that doesn't work when the
3842 : CFG isn't built yet. */
3843 0 : gimple_stmt_iterator gsi2 = *gsi;
3844 0 : gsi_prev (&gsi2);
3845 0 : fold_stmt (&gsi2);
3846 : }
3847 : else
3848 : {
3849 56 : gsi_replace_with_seq_vops (gsi, stmts);
3850 56 : fold_stmt (gsi);
3851 : }
3852 56 : return true;
3853 : }
3854 : return false;
3855 : }
3856 :
3857 : /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
3858 : FP, FMT, and ARG are the arguments to the call. We don't fold calls with
3859 : more than 3 arguments, and ARG may be null in the 2-argument case.
3860 :
3861 : Return NULL_TREE if no simplification was possible, otherwise return the
3862 : simplified form of the call as a tree. FCODE is the BUILT_IN_*
3863 : code of the function to be simplified. */
3864 :
3865 : static bool
3866 54628 : gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
3867 : tree fp, tree fmt, tree arg,
3868 : enum built_in_function fcode)
3869 : {
3870 54628 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3871 54628 : tree fn_fputc, fn_fputs;
3872 54628 : const char *fmt_str = NULL;
3873 :
3874 : /* If the return value is used, don't do the transformation. */
3875 54628 : if (gimple_call_lhs (stmt) != NULL_TREE)
3876 : return false;
3877 :
3878 : /* Check whether the format is a literal string constant. */
3879 50451 : fmt_str = c_getstr (fmt);
3880 50451 : if (fmt_str == NULL)
3881 : return false;
3882 :
3883 50121 : if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
3884 : {
3885 : /* If we're using an unlocked function, assume the other
3886 : unlocked functions exist explicitly. */
3887 80 : fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
3888 80 : fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
3889 : }
3890 : else
3891 : {
3892 50041 : fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
3893 50041 : fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
3894 : }
3895 :
3896 50121 : if (!init_target_chars ())
3897 : return false;
3898 :
3899 144509 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3900 : return false;
3901 :
3902 : /* If the format doesn't contain % args or %%, use strcpy. */
3903 50121 : if (strchr (fmt_str, target_percent) == NULL)
3904 : {
3905 9669 : if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
3906 9599 : && arg)
3907 : return false;
3908 :
3909 : /* If the format specifier was "", fprintf does nothing. */
3910 9669 : if (fmt_str[0] == '\0')
3911 : {
3912 58 : replace_call_with_value (gsi, NULL_TREE);
3913 58 : return true;
3914 : }
3915 :
3916 : /* When "string" doesn't contain %, replace all cases of
3917 : fprintf (fp, string) with fputs (string, fp). The fputs
3918 : builtin will take care of special cases like length == 1. */
3919 9611 : if (fn_fputs)
3920 : {
3921 9611 : gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
3922 9611 : replace_call_with_call_and_fold (gsi, repl);
3923 9611 : return true;
3924 : }
3925 : }
3926 :
3927 : /* The other optimizations can be done only on the non-va_list variants. */
3928 40452 : else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
3929 : return false;
3930 :
3931 : /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
3932 39403 : else if (strcmp (fmt_str, target_percent_s) == 0)
3933 : {
3934 643 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
3935 : return false;
3936 643 : if (fn_fputs)
3937 : {
3938 643 : gcall *repl = gimple_build_call (fn_fputs, 2, arg, fp);
3939 643 : replace_call_with_call_and_fold (gsi, repl);
3940 643 : return true;
3941 : }
3942 : }
3943 :
3944 : /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
3945 38760 : else if (strcmp (fmt_str, target_percent_c) == 0)
3946 : {
3947 49 : if (!arg
3948 49 : || ! useless_type_conversion_p (integer_type_node, TREE_TYPE (arg)))
3949 0 : return false;
3950 49 : if (fn_fputc)
3951 : {
3952 49 : gcall *repl = gimple_build_call (fn_fputc, 2, arg, fp);
3953 49 : replace_call_with_call_and_fold (gsi, repl);
3954 49 : return true;
3955 : }
3956 : }
3957 :
3958 : return false;
3959 : }
3960 :
3961 : /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
3962 : FMT and ARG are the arguments to the call; we don't fold cases with
3963 : more than 2 arguments, and ARG may be null if this is a 1-argument case.
3964 :
3965 : Return NULL_TREE if no simplification was possible, otherwise return the
3966 : simplified form of the call as a tree. FCODE is the BUILT_IN_*
3967 : code of the function to be simplified. */
3968 :
3969 : static bool
3970 124140 : gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
3971 : tree arg, enum built_in_function fcode)
3972 : {
3973 124140 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3974 124140 : tree fn_putchar, fn_puts, newarg;
3975 124140 : const char *fmt_str = NULL;
3976 :
3977 : /* If the return value is used, don't do the transformation. */
3978 124140 : if (gimple_call_lhs (stmt) != NULL_TREE)
3979 : return false;
3980 :
3981 361007 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
3982 : return false;
3983 :
3984 : /* Check whether the format is a literal string constant. */
3985 120882 : fmt_str = c_getstr (fmt);
3986 120882 : if (fmt_str == NULL)
3987 : return false;
3988 :
3989 117845 : if (fcode == BUILT_IN_PRINTF_UNLOCKED)
3990 : {
3991 : /* If we're using an unlocked function, assume the other
3992 : unlocked functions exist explicitly. */
3993 80 : fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
3994 80 : fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
3995 : }
3996 : else
3997 : {
3998 117765 : fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
3999 117765 : fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
4000 : }
4001 :
4002 117845 : if (!init_target_chars ())
4003 : return false;
4004 :
4005 117845 : if (strcmp (fmt_str, target_percent_s) == 0
4006 111459 : || strchr (fmt_str, target_percent) == NULL)
4007 : {
4008 14209 : const char *str;
4009 :
4010 14209 : if (strcmp (fmt_str, target_percent_s) == 0)
4011 : {
4012 6386 : if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
4013 : return false;
4014 :
4015 6098 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
4016 : return false;
4017 :
4018 6093 : str = c_getstr (arg);
4019 6093 : if (str == NULL)
4020 : return false;
4021 : }
4022 : else
4023 : {
4024 : /* The format specifier doesn't contain any '%' characters. */
4025 7823 : if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
4026 7691 : && arg)
4027 : return false;
4028 : str = fmt_str;
4029 : }
4030 :
4031 : /* If the string was "", printf does nothing. */
4032 5774 : if (str[0] == '\0')
4033 : {
4034 109 : replace_call_with_value (gsi, NULL_TREE);
4035 109 : return true;
4036 : }
4037 :
4038 : /* If the string has length of 1, call putchar. */
4039 5665 : if (str[1] == '\0')
4040 : {
4041 : /* Given printf("c"), (where c is any one character,)
4042 : convert "c"[0] to an int and pass that to the replacement
4043 : function. */
4044 559 : newarg = build_int_cst (integer_type_node, str[0]);
4045 559 : if (fn_putchar)
4046 : {
4047 559 : gcall *repl = gimple_build_call (fn_putchar, 1, newarg);
4048 559 : replace_call_with_call_and_fold (gsi, repl);
4049 559 : return true;
4050 : }
4051 : }
4052 : else
4053 : {
4054 : /* If the string was "string\n", call puts("string"). */
4055 5106 : size_t len = strlen (str);
4056 5106 : if ((unsigned char)str[len - 1] == target_newline
4057 4006 : && (size_t) (int) len == len
4058 4006 : && (int) len > 0)
4059 : {
4060 4006 : char *newstr;
4061 :
4062 : /* Create a NUL-terminated string that's one char shorter
4063 : than the original, stripping off the trailing '\n'. */
4064 4006 : newstr = xstrdup (str);
4065 4006 : newstr[len - 1] = '\0';
4066 4006 : newarg = build_string_literal (len, newstr);
4067 4006 : free (newstr);
4068 4006 : if (fn_puts)
4069 : {
4070 4006 : gcall *repl = gimple_build_call (fn_puts, 1, newarg);
4071 4006 : replace_call_with_call_and_fold (gsi, repl);
4072 4006 : return true;
4073 : }
4074 : }
4075 : else
4076 : /* We'd like to arrange to call fputs(string,stdout) here,
4077 : but we need stdout and don't have a way to get it yet. */
4078 : return false;
4079 : }
4080 : }
4081 :
4082 : /* The other optimizations can be done only on the non-va_list variants. */
4083 103636 : else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
4084 : return false;
4085 :
4086 : /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4087 103386 : else if (strcmp (fmt_str, target_percent_s_newline) == 0)
4088 : {
4089 176 : if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
4090 : return false;
4091 176 : if (fn_puts)
4092 : {
4093 176 : gcall *repl = gimple_build_call (fn_puts, 1, arg);
4094 176 : replace_call_with_call_and_fold (gsi, repl);
4095 176 : return true;
4096 : }
4097 : }
4098 :
4099 : /* If the format specifier was "%c", call __builtin_putchar(arg). */
4100 103210 : else if (strcmp (fmt_str, target_percent_c) == 0)
4101 : {
4102 94 : if (!arg || ! useless_type_conversion_p (integer_type_node,
4103 47 : TREE_TYPE (arg)))
4104 0 : return false;
4105 47 : if (fn_putchar)
4106 : {
4107 47 : gcall *repl = gimple_build_call (fn_putchar, 1, arg);
4108 47 : replace_call_with_call_and_fold (gsi, repl);
4109 47 : return true;
4110 : }
4111 : }
4112 :
4113 : return false;
4114 : }
4115 :
4116 :
4117 :
4118 : /* Fold a call to __builtin_strlen with known length LEN. */
4119 :
4120 : static bool
4121 142340 : gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
4122 : {
4123 142340 : gimple *stmt = gsi_stmt (*gsi);
4124 142340 : tree arg = gimple_call_arg (stmt, 0);
4125 :
4126 142340 : wide_int minlen;
4127 142340 : wide_int maxlen;
4128 :
4129 142340 : c_strlen_data lendata = { };
4130 142340 : if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
4131 35029 : && !lendata.decl
4132 32066 : && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
4133 174301 : && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
4134 : {
4135 : /* The range of lengths refers to either a single constant
4136 : string or to the longest and shortest constant string
4137 : referenced by the argument of the strlen() call, or to
4138 : the strings that can possibly be stored in the arrays
4139 : the argument refers to. */
4140 31961 : minlen = wi::to_wide (lendata.minlen);
4141 31961 : maxlen = wi::to_wide (lendata.maxlen);
4142 : }
4143 : else
4144 : {
4145 110379 : unsigned prec = TYPE_PRECISION (sizetype);
4146 :
4147 110379 : minlen = wi::shwi (0, prec);
4148 110379 : maxlen = wi::to_wide (max_object_size (), prec) - 2;
4149 : }
4150 :
4151 : /* For -fsanitize=address, don't optimize the upper bound of the
4152 : length to be able to diagnose UB on non-zero terminated arrays. */
4153 142340 : if (sanitize_flags_p (SANITIZE_ADDRESS))
4154 278 : maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED);
4155 :
4156 142340 : if (minlen == maxlen)
4157 : {
4158 : /* Fold the strlen call to a constant. */
4159 1620 : tree type = TREE_TYPE (lendata.minlen);
4160 3240 : tree len = force_gimple_operand_gsi (gsi,
4161 1620 : wide_int_to_tree (type, minlen),
4162 : true, NULL, true, GSI_SAME_STMT);
4163 1620 : replace_call_with_value (gsi, len);
4164 1620 : return true;
4165 : }
4166 :
4167 : /* Set the strlen() range to [0, MAXLEN]. */
4168 140720 : if (tree lhs = gimple_call_lhs (stmt))
4169 140715 : set_strlen_range (lhs, minlen, maxlen);
4170 :
4171 : return false;
4172 142340 : }
4173 :
4174 : static bool
4175 245 : gimple_fold_builtin_omp_is_initial_device (gimple_stmt_iterator *gsi)
4176 : {
4177 : #if ACCEL_COMPILER
4178 : replace_call_with_value (gsi, integer_zero_node);
4179 : return true;
4180 : #else
4181 245 : if (!ENABLE_OFFLOADING || symtab->state == EXPANSION)
4182 : {
4183 0 : replace_call_with_value (gsi, integer_one_node);
4184 245 : return true;
4185 : }
4186 : #endif
4187 : return false;
4188 : }
4189 :
4190 : /* omp_get_initial_device was in OpenMP 5.0/5.1 explicitly and in
4191 : 5.0 implicitly the same as omp_get_num_devices; since 6.0 it is
4192 : unspecified whether -1 or omp_get_num_devices() is returned. For
4193 : better backward compatibility, use omp_get_num_devices() on the
4194 : host - and -1 on the device (where the result is unspecified). */
4195 :
4196 : static bool
4197 103 : gimple_fold_builtin_omp_get_initial_device (gimple_stmt_iterator *gsi)
4198 : {
4199 : #if ACCEL_COMPILER
4200 : replace_call_with_value (gsi, build_int_cst (integer_type_node, -1));
4201 : #else
4202 103 : if (!ENABLE_OFFLOADING)
4203 0 : replace_call_with_value (gsi, integer_zero_node);
4204 : else
4205 : {
4206 : tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_DEVICES);
4207 : gcall *repl = gimple_build_call (fn, 0);
4208 : replace_call_with_call_and_fold (gsi, repl);
4209 : }
4210 : #endif
4211 103 : return true;
4212 : }
4213 :
4214 : static bool
4215 321 : gimple_fold_builtin_omp_get_num_devices (gimple_stmt_iterator *gsi)
4216 : {
4217 321 : if (!ENABLE_OFFLOADING)
4218 : {
4219 0 : replace_call_with_value (gsi, integer_zero_node);
4220 321 : return true;
4221 : }
4222 : return false;
4223 : }
4224 :
4225 : /* Fold a call to __builtin_acc_on_device. */
4226 :
4227 : static bool
4228 2866 : gimple_fold_builtin_acc_on_device (gimple_stmt_iterator *gsi, tree arg0)
4229 : {
4230 : /* Defer folding until we know which compiler we're in. */
4231 2866 : if (symtab->state != EXPANSION)
4232 : return false;
4233 :
4234 554 : unsigned val_host = GOMP_DEVICE_HOST;
4235 554 : unsigned val_dev = GOMP_DEVICE_NONE;
4236 :
4237 : #ifdef ACCEL_COMPILER
4238 : val_host = GOMP_DEVICE_NOT_HOST;
4239 : val_dev = ACCEL_COMPILER_acc_device;
4240 : #endif
4241 :
4242 554 : location_t loc = gimple_location (gsi_stmt (*gsi));
4243 :
4244 554 : tree host_eq = make_ssa_name (boolean_type_node);
4245 554 : gimple *host_ass = gimple_build_assign
4246 554 : (host_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_host));
4247 554 : gimple_set_location (host_ass, loc);
4248 554 : gsi_insert_before (gsi, host_ass, GSI_SAME_STMT);
4249 :
4250 554 : tree dev_eq = make_ssa_name (boolean_type_node);
4251 554 : gimple *dev_ass = gimple_build_assign
4252 554 : (dev_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_dev));
4253 554 : gimple_set_location (dev_ass, loc);
4254 554 : gsi_insert_before (gsi, dev_ass, GSI_SAME_STMT);
4255 :
4256 554 : tree result = make_ssa_name (boolean_type_node);
4257 554 : gimple *result_ass = gimple_build_assign
4258 554 : (result, BIT_IOR_EXPR, host_eq, dev_eq);
4259 554 : gimple_set_location (result_ass, loc);
4260 554 : gsi_insert_before (gsi, result_ass, GSI_SAME_STMT);
4261 :
4262 554 : replace_call_with_value (gsi, result);
4263 :
4264 554 : return true;
4265 : }
4266 :
4267 : /* Fold realloc (0, n) -> malloc (n). */
4268 :
4269 : static bool
4270 49410 : gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
4271 : {
4272 49410 : gimple *stmt = gsi_stmt (*gsi);
4273 49410 : tree arg = gimple_call_arg (stmt, 0);
4274 49410 : tree size = gimple_call_arg (stmt, 1);
4275 :
4276 146837 : if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
4277 : return false;
4278 :
4279 49410 : if (operand_equal_p (arg, null_pointer_node, 0))
4280 : {
4281 1393 : tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
4282 1393 : if (fn_malloc)
4283 : {
4284 1393 : gcall *repl = gimple_build_call (fn_malloc, 1, size);
4285 1393 : replace_call_with_call_and_fold (gsi, repl);
4286 1393 : return true;
4287 : }
4288 : }
4289 : return false;
4290 : }
4291 :
4292 : /* Number of bytes into which any type but aggregate, vector or
4293 : _BitInt types should fit. */
4294 : static constexpr size_t clear_padding_unit
4295 : = MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT;
4296 : /* Buffer size on which __builtin_clear_padding folding code works. */
4297 : static const size_t clear_padding_buf_size = 32 * clear_padding_unit;
4298 :
4299 : /* Data passed through __builtin_clear_padding folding. */
4300 : struct clear_padding_struct {
4301 : location_t loc;
4302 : /* 0 during __builtin_clear_padding folding, nonzero during
4303 : clear_type_padding_in_mask. In that case, instead of clearing the
4304 : non-padding bits in union_ptr array clear the padding bits in there. */
4305 : bool clear_in_mask;
4306 : tree base;
4307 : tree alias_type;
4308 : gimple_stmt_iterator *gsi;
4309 : /* Alignment of buf->base + 0. */
4310 : unsigned align;
4311 : /* Offset from buf->base. Should be always a multiple of UNITS_PER_WORD. */
4312 : HOST_WIDE_INT off;
4313 : /* Number of padding bytes before buf->off that don't have padding clear
4314 : code emitted yet. */
4315 : HOST_WIDE_INT padding_bytes;
4316 : /* The size of the whole object. Never emit code to touch
4317 : buf->base + buf->sz or following bytes. */
4318 : HOST_WIDE_INT sz;
4319 : /* Number of bytes recorded in buf->buf. */
4320 : size_t size;
4321 : /* When inside union, instead of emitting code we and bits inside of
4322 : the union_ptr array. */
4323 : unsigned char *union_ptr;
4324 : /* Set bits mean padding bits that need to be cleared by the builtin. */
4325 : unsigned char buf[clear_padding_buf_size + clear_padding_unit];
4326 : };
4327 :
4328 : /* Emit code to clear padding requested in BUF->buf - set bits
4329 : in there stand for padding that should be cleared. FULL is true
4330 : if everything from the buffer should be flushed, otherwise
4331 : it can leave up to 2 * clear_padding_unit bytes for further
4332 : processing. */
4333 :
4334 : static void
4335 38891 : clear_padding_flush (clear_padding_struct *buf, bool full)
4336 : {
4337 38891 : gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0);
4338 38891 : if (!full && buf->size < 2 * clear_padding_unit)
4339 38891 : return;
4340 39939 : gcc_assert ((buf->off % UNITS_PER_WORD) == 0);
4341 38849 : size_t end = buf->size;
4342 38849 : if (!full)
4343 42 : end = ((end - clear_padding_unit - 1) / clear_padding_unit
4344 : * clear_padding_unit);
4345 38849 : size_t padding_bytes = buf->padding_bytes;
4346 38849 : if (buf->union_ptr)
4347 : {
4348 38082 : if (buf->clear_in_mask)
4349 : {
4350 : /* During clear_type_padding_in_mask, clear the padding
4351 : bits set in buf->buf in the buf->union_ptr mask. */
4352 333464 : for (size_t i = 0; i < end; i++)
4353 : {
4354 295775 : if (buf->buf[i] == (unsigned char) ~0)
4355 9052 : padding_bytes++;
4356 : else
4357 : {
4358 286723 : memset (&buf->union_ptr[buf->off + i - padding_bytes],
4359 : 0, padding_bytes);
4360 286723 : padding_bytes = 0;
4361 286723 : buf->union_ptr[buf->off + i] &= ~buf->buf[i];
4362 : }
4363 : }
4364 37689 : if (full)
4365 : {
4366 37689 : memset (&buf->union_ptr[buf->off + end - padding_bytes],
4367 : 0, padding_bytes);
4368 37689 : buf->off = 0;
4369 37689 : buf->size = 0;
4370 37689 : buf->padding_bytes = 0;
4371 : }
4372 : else
4373 : {
4374 0 : memmove (buf->buf, buf->buf + end, buf->size - end);
4375 0 : buf->off += end;
4376 0 : buf->size -= end;
4377 0 : buf->padding_bytes = padding_bytes;
4378 : }
4379 37689 : return;
4380 : }
4381 : /* Inside of a union, instead of emitting any code, instead
4382 : clear all bits in the union_ptr buffer that are clear
4383 : in buf. Whole padding bytes don't clear anything. */
4384 3017 : for (size_t i = 0; i < end; i++)
4385 : {
4386 2624 : if (buf->buf[i] == (unsigned char) ~0)
4387 1424 : padding_bytes++;
4388 : else
4389 : {
4390 1200 : padding_bytes = 0;
4391 1200 : buf->union_ptr[buf->off + i] &= buf->buf[i];
4392 : }
4393 : }
4394 393 : if (full)
4395 : {
4396 393 : buf->off = 0;
4397 393 : buf->size = 0;
4398 393 : buf->padding_bytes = 0;
4399 : }
4400 : else
4401 : {
4402 0 : memmove (buf->buf, buf->buf + end, buf->size - end);
4403 0 : buf->off += end;
4404 0 : buf->size -= end;
4405 0 : buf->padding_bytes = padding_bytes;
4406 : }
4407 393 : return;
4408 : }
4409 767 : size_t wordsize = UNITS_PER_WORD;
4410 23514 : for (size_t i = 0; i < end; i += wordsize)
4411 : {
4412 22747 : size_t nonzero_first = wordsize;
4413 22747 : size_t nonzero_last = 0;
4414 22747 : size_t zero_first = wordsize;
4415 22747 : size_t zero_last = 0;
4416 22747 : bool all_ones = true, bytes_only = true;
4417 23033 : if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize)
4418 22747 : > (unsigned HOST_WIDE_INT) buf->sz)
4419 : {
4420 286 : gcc_assert (wordsize > 1);
4421 286 : wordsize /= 2;
4422 286 : i -= wordsize;
4423 286 : continue;
4424 : }
4425 22461 : size_t endsize = end - i > wordsize ? wordsize : end - i;
4426 200904 : for (size_t j = i; j < i + endsize; j++)
4427 : {
4428 178443 : if (buf->buf[j])
4429 : {
4430 168410 : if (nonzero_first == wordsize)
4431 : {
4432 21519 : nonzero_first = j - i;
4433 21519 : nonzero_last = j - i;
4434 : }
4435 168410 : if (nonzero_last != j - i)
4436 166 : all_ones = false;
4437 168410 : nonzero_last = j + 1 - i;
4438 : }
4439 : else
4440 : {
4441 10033 : if (zero_first == wordsize)
4442 1946 : zero_first = j - i;
4443 10033 : zero_last = j + 1 - i;
4444 : }
4445 178443 : if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
4446 : {
4447 101 : all_ones = false;
4448 101 : bytes_only = false;
4449 : }
4450 : }
4451 22461 : size_t padding_end = i;
4452 22461 : if (padding_bytes)
4453 : {
4454 20849 : if (nonzero_first == 0
4455 20849 : && nonzero_last == endsize
4456 20400 : && all_ones)
4457 : {
4458 : /* All bits are padding and we had some padding
4459 : before too. Just extend it. */
4460 20400 : padding_bytes += endsize;
4461 20400 : continue;
4462 : }
4463 449 : if (all_ones && nonzero_first == 0)
4464 : {
4465 4 : padding_bytes += nonzero_last;
4466 4 : padding_end += nonzero_last;
4467 4 : nonzero_first = wordsize;
4468 4 : nonzero_last = 0;
4469 : }
4470 445 : else if (bytes_only && nonzero_first == 0)
4471 : {
4472 0 : gcc_assert (zero_first && zero_first != wordsize);
4473 0 : padding_bytes += zero_first;
4474 0 : padding_end += zero_first;
4475 : }
4476 449 : tree atype, src;
4477 449 : if (padding_bytes == 1)
4478 : {
4479 33 : atype = char_type_node;
4480 33 : src = build_zero_cst (char_type_node);
4481 : }
4482 : else
4483 : {
4484 416 : atype = build_array_type_nelts (char_type_node, padding_bytes);
4485 416 : src = build_constructor (atype, NULL);
4486 : }
4487 449 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4488 : build_int_cst (buf->alias_type,
4489 449 : buf->off + padding_end
4490 449 : - padding_bytes));
4491 449 : gimple *g = gimple_build_assign (dst, src);
4492 449 : gimple_set_location (g, buf->loc);
4493 449 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4494 449 : padding_bytes = 0;
4495 449 : buf->padding_bytes = 0;
4496 : }
4497 2061 : if (nonzero_first == wordsize)
4498 : /* All bits in a word are 0, there are no padding bits. */
4499 946 : continue;
4500 1115 : if (all_ones && nonzero_last == endsize)
4501 : {
4502 : /* All bits between nonzero_first and end of word are padding
4503 : bits, start counting padding_bytes. */
4504 841 : padding_bytes = nonzero_last - nonzero_first;
4505 841 : continue;
4506 : }
4507 274 : if (bytes_only)
4508 : {
4509 : /* If bitfields aren't involved in this word, prefer storing
4510 : individual bytes or groups of them over performing a RMW
4511 : operation on the whole word. */
4512 227 : gcc_assert (i + zero_last <= end);
4513 1117 : for (size_t j = padding_end; j < i + zero_last; j++)
4514 : {
4515 890 : if (buf->buf[j])
4516 : {
4517 : size_t k;
4518 606 : for (k = j; k < i + zero_last; k++)
4519 606 : if (buf->buf[k] == 0)
4520 : break;
4521 259 : HOST_WIDE_INT off = buf->off + j;
4522 259 : tree atype, src;
4523 259 : if (k - j == 1)
4524 : {
4525 215 : atype = char_type_node;
4526 215 : src = build_zero_cst (char_type_node);
4527 : }
4528 : else
4529 : {
4530 44 : atype = build_array_type_nelts (char_type_node, k - j);
4531 44 : src = build_constructor (atype, NULL);
4532 : }
4533 259 : tree dst = build2_loc (buf->loc, MEM_REF, atype,
4534 : buf->base,
4535 259 : build_int_cst (buf->alias_type, off));
4536 259 : gimple *g = gimple_build_assign (dst, src);
4537 259 : gimple_set_location (g, buf->loc);
4538 259 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4539 259 : j = k;
4540 : }
4541 : }
4542 227 : if (nonzero_last == endsize)
4543 98 : padding_bytes = nonzero_last - zero_last;
4544 227 : continue;
4545 227 : }
4546 158 : for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
4547 : {
4548 158 : if (nonzero_last - nonzero_first <= eltsz
4549 47 : && ((nonzero_first & ~(eltsz - 1))
4550 47 : == ((nonzero_last - 1) & ~(eltsz - 1))))
4551 : {
4552 47 : tree type;
4553 47 : if (eltsz == 1)
4554 2 : type = char_type_node;
4555 : else
4556 45 : type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT,
4557 : 0);
4558 47 : size_t start = nonzero_first & ~(eltsz - 1);
4559 47 : HOST_WIDE_INT off = buf->off + i + start;
4560 47 : tree atype = type;
4561 47 : if (eltsz > 1 && buf->align < TYPE_ALIGN (type))
4562 8 : atype = build_aligned_type (type, buf->align);
4563 47 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4564 47 : build_int_cst (buf->alias_type, off));
4565 47 : tree src;
4566 47 : gimple *g;
4567 47 : if (all_ones
4568 47 : && nonzero_first == start
4569 0 : && nonzero_last == start + eltsz)
4570 0 : src = build_zero_cst (type);
4571 : else
4572 : {
4573 47 : src = make_ssa_name (type);
4574 47 : tree tmp_dst = unshare_expr (dst);
4575 : /* The folding introduces a read from the tmp_dst, we should
4576 : prevent uninitialized warning analysis from issuing warning
4577 : for such fake read. In order to suppress warning only for
4578 : this expr, we should set the location of tmp_dst to
4579 : UNKNOWN_LOCATION first, then suppress_warning will call
4580 : set_no_warning_bit to set the no_warning flag only for
4581 : tmp_dst. */
4582 47 : SET_EXPR_LOCATION (tmp_dst, UNKNOWN_LOCATION);
4583 47 : suppress_warning (tmp_dst, OPT_Wuninitialized);
4584 47 : g = gimple_build_assign (src, tmp_dst);
4585 47 : gimple_set_location (g, buf->loc);
4586 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4587 94 : tree mask = native_interpret_expr (type,
4588 47 : buf->buf + i + start,
4589 : eltsz);
4590 47 : gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
4591 47 : mask = fold_build1 (BIT_NOT_EXPR, type, mask);
4592 47 : tree src_masked = make_ssa_name (type);
4593 47 : g = gimple_build_assign (src_masked, BIT_AND_EXPR,
4594 : src, mask);
4595 47 : gimple_set_location (g, buf->loc);
4596 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4597 47 : src = src_masked;
4598 : }
4599 47 : g = gimple_build_assign (dst, src);
4600 47 : gimple_set_location (g, buf->loc);
4601 47 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4602 47 : break;
4603 : }
4604 : }
4605 : }
4606 767 : if (full)
4607 : {
4608 725 : if (padding_bytes)
4609 : {
4610 490 : tree atype, src;
4611 490 : if (padding_bytes == 1)
4612 : {
4613 110 : atype = char_type_node;
4614 110 : src = build_zero_cst (char_type_node);
4615 : }
4616 : else
4617 : {
4618 380 : atype = build_array_type_nelts (char_type_node, padding_bytes);
4619 380 : src = build_constructor (atype, NULL);
4620 : }
4621 490 : tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4622 : build_int_cst (buf->alias_type,
4623 490 : buf->off + end
4624 490 : - padding_bytes));
4625 490 : gimple *g = gimple_build_assign (dst, src);
4626 490 : gimple_set_location (g, buf->loc);
4627 490 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4628 : }
4629 725 : size_t end_rem = end % UNITS_PER_WORD;
4630 725 : buf->off += end - end_rem;
4631 725 : buf->size = end_rem;
4632 725 : memset (buf->buf, 0, buf->size);
4633 725 : buf->padding_bytes = 0;
4634 : }
4635 : else
4636 : {
4637 42 : memmove (buf->buf, buf->buf + end, buf->size - end);
4638 42 : buf->off += end;
4639 42 : buf->size -= end;
4640 42 : buf->padding_bytes = padding_bytes;
4641 : }
4642 : }
4643 :
4644 : /* Append PADDING_BYTES padding bytes. */
4645 :
4646 : static void
4647 26529 : clear_padding_add_padding (clear_padding_struct *buf,
4648 : HOST_WIDE_INT padding_bytes)
4649 : {
4650 26529 : if (padding_bytes == 0)
4651 : return;
4652 1713 : if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
4653 : > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
4654 42 : clear_padding_flush (buf, false);
4655 1713 : if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
4656 : > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
4657 : {
4658 42 : memset (buf->buf + buf->size, ~0, clear_padding_buf_size - buf->size);
4659 42 : padding_bytes -= clear_padding_buf_size - buf->size;
4660 42 : buf->size = clear_padding_buf_size;
4661 42 : clear_padding_flush (buf, false);
4662 42 : gcc_assert (buf->padding_bytes);
4663 : /* At this point buf->buf[0] through buf->buf[buf->size - 1]
4664 : is guaranteed to be all ones. */
4665 42 : padding_bytes += buf->size;
4666 42 : buf->size = padding_bytes % UNITS_PER_WORD;
4667 42 : memset (buf->buf, ~0, buf->size);
4668 42 : buf->off += padding_bytes - buf->size;
4669 42 : buf->padding_bytes += padding_bytes - buf->size;
4670 : }
4671 : else
4672 : {
4673 1671 : memset (buf->buf + buf->size, ~0, padding_bytes);
4674 1671 : buf->size += padding_bytes;
4675 : }
4676 : }
4677 :
4678 : static void clear_padding_type (clear_padding_struct *, tree,
4679 : HOST_WIDE_INT, bool);
4680 :
4681 : /* Clear padding bits of union type TYPE. */
4682 :
4683 : static void
4684 128 : clear_padding_union (clear_padding_struct *buf, tree type,
4685 : HOST_WIDE_INT sz, bool for_auto_init)
4686 : {
4687 128 : clear_padding_struct *union_buf;
4688 128 : HOST_WIDE_INT start_off = 0, next_off = 0;
4689 128 : size_t start_size = 0;
4690 128 : if (buf->union_ptr)
4691 : {
4692 42 : start_off = buf->off + buf->size;
4693 42 : next_off = start_off + sz;
4694 42 : start_size = start_off % UNITS_PER_WORD;
4695 42 : start_off -= start_size;
4696 42 : clear_padding_flush (buf, true);
4697 42 : union_buf = buf;
4698 : }
4699 : else
4700 : {
4701 86 : if (sz + buf->size > clear_padding_buf_size)
4702 0 : clear_padding_flush (buf, false);
4703 86 : union_buf = XALLOCA (clear_padding_struct);
4704 86 : union_buf->loc = buf->loc;
4705 86 : union_buf->clear_in_mask = buf->clear_in_mask;
4706 86 : union_buf->base = NULL_TREE;
4707 86 : union_buf->alias_type = NULL_TREE;
4708 86 : union_buf->gsi = NULL;
4709 86 : union_buf->align = 0;
4710 86 : union_buf->off = 0;
4711 86 : union_buf->padding_bytes = 0;
4712 86 : union_buf->sz = sz;
4713 86 : union_buf->size = 0;
4714 86 : if (sz + buf->size <= clear_padding_buf_size)
4715 86 : union_buf->union_ptr = buf->buf + buf->size;
4716 : else
4717 0 : union_buf->union_ptr = XNEWVEC (unsigned char, sz);
4718 86 : memset (union_buf->union_ptr, ~0, sz);
4719 : }
4720 :
4721 1193 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
4722 1065 : if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
4723 : {
4724 359 : if (DECL_SIZE_UNIT (field) == NULL_TREE)
4725 : {
4726 8 : if (TREE_TYPE (field) == error_mark_node)
4727 0 : continue;
4728 8 : gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
4729 : && !COMPLETE_TYPE_P (TREE_TYPE (field)));
4730 8 : if (!buf->clear_in_mask && !for_auto_init)
4731 8 : error_at (buf->loc, "flexible array member %qD does not have "
4732 : "well defined padding bits for %qs",
4733 : field, "__builtin_clear_padding");
4734 8 : continue;
4735 : }
4736 351 : HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
4737 351 : gcc_assert (union_buf->size == 0);
4738 351 : union_buf->off = start_off;
4739 351 : union_buf->size = start_size;
4740 351 : memset (union_buf->buf, ~0, start_size);
4741 351 : clear_padding_type (union_buf, TREE_TYPE (field), fldsz, for_auto_init);
4742 351 : clear_padding_add_padding (union_buf, sz - fldsz);
4743 351 : clear_padding_flush (union_buf, true);
4744 : }
4745 :
4746 128 : if (buf == union_buf)
4747 : {
4748 42 : buf->off = next_off;
4749 42 : buf->size = next_off % UNITS_PER_WORD;
4750 42 : buf->off -= buf->size;
4751 42 : memset (buf->buf, ~0, buf->size);
4752 : }
4753 86 : else if (sz + buf->size <= clear_padding_buf_size)
4754 86 : buf->size += sz;
4755 : else
4756 : {
4757 0 : unsigned char *union_ptr = union_buf->union_ptr;
4758 0 : while (sz)
4759 : {
4760 0 : clear_padding_flush (buf, false);
4761 0 : HOST_WIDE_INT this_sz
4762 0 : = MIN ((unsigned HOST_WIDE_INT) sz,
4763 : clear_padding_buf_size - buf->size);
4764 0 : memcpy (buf->buf + buf->size, union_ptr, this_sz);
4765 0 : buf->size += this_sz;
4766 0 : union_ptr += this_sz;
4767 0 : sz -= this_sz;
4768 : }
4769 0 : XDELETE (union_buf->union_ptr);
4770 : }
4771 128 : }
4772 :
4773 : /* The only known floating point formats with padding bits are the
4774 : IEEE extended ones. */
4775 :
4776 : static bool
4777 38161 : clear_padding_real_needs_padding_p (tree type)
4778 : {
4779 38161 : const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
4780 38161 : return (fmt->b == 2
4781 37550 : && fmt->signbit_ro == fmt->signbit_rw
4782 75711 : && (fmt->signbit_ro == 79 || fmt->signbit_ro == 95));
4783 : }
4784 :
4785 : /* _BitInt has padding bits if it isn't extended in the ABI and has smaller
4786 : precision than bits in limb or corresponding number of limbs. */
4787 :
4788 : static bool
4789 54 : clear_padding_bitint_needs_padding_p (tree type)
4790 : {
4791 54 : struct bitint_info info;
4792 54 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
4793 54 : gcc_assert (ok);
4794 54 : if (info.extended)
4795 : return false;
4796 54 : scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.abi_limb_mode);
4797 54 : if (TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
4798 : return true;
4799 4 : else if (TYPE_PRECISION (type) == GET_MODE_PRECISION (limb_mode))
4800 : return false;
4801 : else
4802 4 : return (((unsigned) TYPE_PRECISION (type))
4803 4 : % GET_MODE_PRECISION (limb_mode)) != 0;
4804 : }
4805 :
4806 : /* Return true if TYPE might contain any padding bits. */
4807 :
4808 : bool
4809 945987 : clear_padding_type_may_have_padding_p (tree type)
4810 : {
4811 1085250 : switch (TREE_CODE (type))
4812 : {
4813 : case RECORD_TYPE:
4814 : case UNION_TYPE:
4815 : return true;
4816 139263 : case ARRAY_TYPE:
4817 139263 : case COMPLEX_TYPE:
4818 139263 : case VECTOR_TYPE:
4819 139263 : return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
4820 1930 : case REAL_TYPE:
4821 1930 : return clear_padding_real_needs_padding_p (type);
4822 63 : case ENUMERAL_TYPE:
4823 63 : if (BITINT_TYPE_P (type))
4824 0 : return clear_padding_bitint_needs_padding_p (type);
4825 : return false;
4826 54 : case BITINT_TYPE:
4827 54 : return clear_padding_bitint_needs_padding_p (type);
4828 : default:
4829 : return false;
4830 : }
4831 : }
4832 :
4833 : /* Return true if TYPE has padding bits aside from those in fields,
4834 : elements, etc. */
4835 :
4836 : bool
4837 1200734 : type_has_padding_at_level_p (tree type)
4838 : {
4839 1200734 : switch (TREE_CODE (type))
4840 : {
4841 1058396 : case RECORD_TYPE:
4842 1058396 : {
4843 1058396 : tree bitpos = size_zero_node;
4844 : /* Expect fields to be sorted by bit position. */
4845 8599820 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4846 7546824 : if (TREE_CODE (f) == FIELD_DECL)
4847 : {
4848 2302994 : if (DECL_PADDING_P (f))
4849 : return true;
4850 2302991 : tree pos = bit_position (f);
4851 2302991 : if (simple_cst_equal (bitpos, pos) != 1)
4852 : return true;
4853 2297617 : if (!DECL_SIZE (f))
4854 : return true;
4855 2297594 : bitpos = int_const_binop (PLUS_EXPR, pos, DECL_SIZE (f));
4856 : }
4857 1052996 : if (simple_cst_equal (bitpos, TYPE_SIZE (type)) != 1)
4858 : return true;
4859 : return false;
4860 : }
4861 3 : case UNION_TYPE:
4862 3 : case QUAL_UNION_TYPE:
4863 3 : bool any_fields;
4864 3 : any_fields = false;
4865 : /* If any of the fields is smaller than the whole, there is padding. */
4866 6 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4867 3 : if (TREE_CODE (f) != FIELD_DECL || TREE_TYPE (f) == error_mark_node)
4868 3 : continue;
4869 0 : else if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
4870 0 : TYPE_SIZE (type)) != 1)
4871 : return true;
4872 : else
4873 : any_fields = true;
4874 : /* If the union doesn't have any fields and still has non-zero size,
4875 : all of it is padding. */
4876 3 : if (!any_fields && !integer_zerop (TYPE_SIZE (type)))
4877 : return true;
4878 : return false;
4879 : case ARRAY_TYPE:
4880 : case COMPLEX_TYPE:
4881 : case VECTOR_TYPE:
4882 : /* No recursing here, no padding at this level. */
4883 : return false;
4884 0 : case REAL_TYPE:
4885 0 : return clear_padding_real_needs_padding_p (type);
4886 0 : case ENUMERAL_TYPE:
4887 0 : if (BITINT_TYPE_P (type))
4888 0 : return clear_padding_bitint_needs_padding_p (type);
4889 : return false;
4890 0 : case BITINT_TYPE:
4891 0 : return clear_padding_bitint_needs_padding_p (type);
4892 : default:
4893 : return false;
4894 : }
4895 : }
4896 :
4897 : /* Emit a runtime loop:
4898 : for (; buf.base != end; buf.base += sz)
4899 : __builtin_clear_padding (buf.base); */
4900 :
4901 : static void
4902 114 : clear_padding_emit_loop (clear_padding_struct *buf, tree type,
4903 : tree end, bool for_auto_init)
4904 : {
4905 114 : tree l1 = create_artificial_label (buf->loc);
4906 114 : tree l2 = create_artificial_label (buf->loc);
4907 114 : tree l3 = create_artificial_label (buf->loc);
4908 114 : gimple *g = gimple_build_goto (l2);
4909 114 : gimple_set_location (g, buf->loc);
4910 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4911 114 : g = gimple_build_label (l1);
4912 114 : gimple_set_location (g, buf->loc);
4913 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4914 114 : clear_padding_type (buf, type, buf->sz, for_auto_init);
4915 114 : clear_padding_flush (buf, true);
4916 114 : g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
4917 114 : size_int (buf->sz));
4918 114 : gimple_set_location (g, buf->loc);
4919 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4920 114 : g = gimple_build_label (l2);
4921 114 : gimple_set_location (g, buf->loc);
4922 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4923 114 : g = gimple_build_cond (NE_EXPR, buf->base, end, l1, l3);
4924 114 : gimple_set_location (g, buf->loc);
4925 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4926 114 : g = gimple_build_label (l3);
4927 114 : gimple_set_location (g, buf->loc);
4928 114 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4929 114 : }
4930 :
4931 : /* Clear padding bits for TYPE. Called recursively from
4932 : gimple_fold_builtin_clear_padding. If FOR_AUTO_INIT is true,
4933 : the __builtin_clear_padding is not called by the end user,
4934 : instead, it's inserted by the compiler to initialize the
4935 : paddings of automatic variable. Therefore, we should not
4936 : emit the error messages for flexible array members to confuse
4937 : the end user. */
4938 :
4939 : static void
4940 73769 : clear_padding_type (clear_padding_struct *buf, tree type,
4941 : HOST_WIDE_INT sz, bool for_auto_init)
4942 : {
4943 73769 : switch (TREE_CODE (type))
4944 : {
4945 10304 : case RECORD_TYPE:
4946 10304 : HOST_WIDE_INT cur_pos;
4947 10304 : cur_pos = 0;
4948 793667 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
4949 783363 : if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
4950 : {
4951 24977 : tree ftype = TREE_TYPE (field);
4952 24977 : if (DECL_BIT_FIELD (field))
4953 : {
4954 292 : HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype);
4955 292 : if (fldsz == 0)
4956 0 : continue;
4957 292 : HOST_WIDE_INT pos = int_byte_position (field);
4958 292 : if (pos >= sz)
4959 0 : continue;
4960 292 : HOST_WIDE_INT bpos
4961 292 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
4962 292 : bpos %= BITS_PER_UNIT;
4963 292 : HOST_WIDE_INT end
4964 292 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
4965 292 : if (pos + end > cur_pos)
4966 : {
4967 215 : clear_padding_add_padding (buf, pos + end - cur_pos);
4968 215 : cur_pos = pos + end;
4969 : }
4970 292 : gcc_assert (cur_pos > pos
4971 : && ((unsigned HOST_WIDE_INT) buf->size
4972 : >= (unsigned HOST_WIDE_INT) cur_pos - pos));
4973 292 : unsigned char *p = buf->buf + buf->size - (cur_pos - pos);
4974 292 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4975 : sorry_at (buf->loc, "PDP11 bit-field handling unsupported"
4976 : " in %qs", "__builtin_clear_padding");
4977 292 : else if (BYTES_BIG_ENDIAN)
4978 : {
4979 : /* Big endian. */
4980 : if (bpos + fldsz <= BITS_PER_UNIT)
4981 : *p &= ~(((1 << fldsz) - 1)
4982 : << (BITS_PER_UNIT - bpos - fldsz));
4983 : else
4984 : {
4985 : if (bpos)
4986 : {
4987 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
4988 : p++;
4989 : fldsz -= BITS_PER_UNIT - bpos;
4990 : }
4991 : memset (p, 0, fldsz / BITS_PER_UNIT);
4992 : p += fldsz / BITS_PER_UNIT;
4993 : fldsz %= BITS_PER_UNIT;
4994 : if (fldsz)
4995 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
4996 : }
4997 : }
4998 : else
4999 : {
5000 : /* Little endian. */
5001 292 : if (bpos + fldsz <= BITS_PER_UNIT)
5002 175 : *p &= ~(((1 << fldsz) - 1) << bpos);
5003 : else
5004 : {
5005 117 : if (bpos)
5006 : {
5007 33 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
5008 33 : p++;
5009 33 : fldsz -= BITS_PER_UNIT - bpos;
5010 : }
5011 117 : memset (p, 0, fldsz / BITS_PER_UNIT);
5012 117 : p += fldsz / BITS_PER_UNIT;
5013 117 : fldsz %= BITS_PER_UNIT;
5014 117 : if (fldsz)
5015 72 : *p &= ~((1 << fldsz) - 1);
5016 : }
5017 : }
5018 : }
5019 24685 : else if (DECL_SIZE_UNIT (field) == NULL_TREE)
5020 : {
5021 32 : if (ftype == error_mark_node)
5022 0 : continue;
5023 32 : gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
5024 : && !COMPLETE_TYPE_P (ftype));
5025 32 : if (!buf->clear_in_mask && !for_auto_init)
5026 24 : error_at (buf->loc, "flexible array member %qD does not "
5027 : "have well defined padding bits for %qs",
5028 : field, "__builtin_clear_padding");
5029 : }
5030 24653 : else if (is_empty_type (ftype))
5031 8994 : continue;
5032 : else
5033 : {
5034 15659 : HOST_WIDE_INT pos = int_byte_position (field);
5035 15659 : if (pos >= sz)
5036 0 : continue;
5037 15659 : HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
5038 15659 : gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
5039 15659 : clear_padding_add_padding (buf, pos - cur_pos);
5040 15659 : cur_pos = pos;
5041 15659 : if (tree asbase = lang_hooks.types.classtype_as_base (field))
5042 300 : ftype = asbase;
5043 15659 : clear_padding_type (buf, ftype, fldsz, for_auto_init);
5044 15659 : cur_pos += fldsz;
5045 : }
5046 : }
5047 10304 : gcc_assert (sz >= cur_pos);
5048 10304 : clear_padding_add_padding (buf, sz - cur_pos);
5049 10304 : break;
5050 326 : case ARRAY_TYPE:
5051 326 : HOST_WIDE_INT nelts, fldsz;
5052 326 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5053 326 : if (fldsz == 0)
5054 : break;
5055 312 : nelts = sz / fldsz;
5056 312 : if (nelts > 1
5057 305 : && sz > 8 * UNITS_PER_WORD
5058 78 : && buf->union_ptr == NULL
5059 390 : && clear_padding_type_may_have_padding_p (TREE_TYPE (type)))
5060 : {
5061 : /* For sufficiently large array of more than one elements,
5062 : emit a runtime loop to keep code size manageable. */
5063 66 : tree base = buf->base;
5064 66 : unsigned int prev_align = buf->align;
5065 66 : HOST_WIDE_INT off = buf->off + buf->size;
5066 66 : HOST_WIDE_INT prev_sz = buf->sz;
5067 66 : clear_padding_flush (buf, true);
5068 66 : tree elttype = TREE_TYPE (type);
5069 66 : buf->base = create_tmp_var (build_pointer_type (elttype));
5070 66 : tree end = make_ssa_name (TREE_TYPE (buf->base));
5071 66 : gimple *g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR,
5072 66 : base, size_int (off));
5073 66 : gimple_set_location (g, buf->loc);
5074 66 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
5075 66 : g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf->base,
5076 66 : size_int (sz));
5077 66 : gimple_set_location (g, buf->loc);
5078 66 : gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
5079 66 : buf->sz = fldsz;
5080 66 : buf->align = TYPE_ALIGN (elttype);
5081 66 : buf->off = 0;
5082 66 : buf->size = 0;
5083 66 : clear_padding_emit_loop (buf, elttype, end, for_auto_init);
5084 66 : off += sz;
5085 66 : buf->base = base;
5086 66 : buf->sz = prev_sz;
5087 66 : buf->align = prev_align;
5088 66 : buf->size = off % UNITS_PER_WORD;
5089 66 : buf->off = off - buf->size;
5090 66 : memset (buf->buf, 0, buf->size);
5091 66 : break;
5092 : }
5093 1180 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5094 934 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5095 : break;
5096 128 : case UNION_TYPE:
5097 128 : clear_padding_union (buf, type, sz, for_auto_init);
5098 128 : break;
5099 36231 : case REAL_TYPE:
5100 36231 : gcc_assert ((size_t) sz <= clear_padding_unit);
5101 36231 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5102 0 : clear_padding_flush (buf, false);
5103 36231 : if (clear_padding_real_needs_padding_p (type))
5104 : {
5105 : /* Use native_interpret_real + native_encode_expr to figure out
5106 : which bits are padding. */
5107 1587 : memset (buf->buf + buf->size, ~0, sz);
5108 1587 : tree cst = native_interpret_real (type, buf->buf + buf->size, sz);
5109 1587 : gcc_assert (cst && TREE_CODE (cst) == REAL_CST);
5110 1587 : int len = native_encode_expr (cst, buf->buf + buf->size, sz);
5111 1587 : gcc_assert (len > 0 && (size_t) len == (size_t) sz);
5112 26979 : for (size_t i = 0; i < (size_t) sz; i++)
5113 25392 : buf->buf[buf->size + i] ^= ~0;
5114 : }
5115 : else
5116 34644 : memset (buf->buf + buf->size, 0, sz);
5117 36231 : buf->size += sz;
5118 36231 : break;
5119 0 : case COMPLEX_TYPE:
5120 0 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5121 0 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5122 0 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5123 0 : break;
5124 5180 : case VECTOR_TYPE:
5125 5180 : nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
5126 5180 : fldsz = int_size_in_bytes (TREE_TYPE (type));
5127 23648 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5128 18468 : clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
5129 : break;
5130 7 : case NULLPTR_TYPE:
5131 7 : gcc_assert ((size_t) sz <= clear_padding_unit);
5132 7 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5133 0 : clear_padding_flush (buf, false);
5134 7 : memset (buf->buf + buf->size, ~0, sz);
5135 7 : buf->size += sz;
5136 7 : break;
5137 4 : case BITINT_TYPE:
5138 4 : do_bitint:
5139 4 : {
5140 4 : struct bitint_info info;
5141 4 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
5142 4 : gcc_assert (ok);
5143 4 : scalar_int_mode limb_mode
5144 4 : = as_a <scalar_int_mode> (info.abi_limb_mode);
5145 4 : if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
5146 : {
5147 2 : gcc_assert ((size_t) sz <= clear_padding_unit);
5148 2 : if ((unsigned HOST_WIDE_INT) sz + buf->size
5149 : > clear_padding_buf_size)
5150 0 : clear_padding_flush (buf, false);
5151 2 : if (!info.extended
5152 2 : && TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
5153 : {
5154 2 : int tprec = GET_MODE_PRECISION (limb_mode);
5155 2 : int prec = TYPE_PRECISION (type);
5156 2 : tree t = build_nonstandard_integer_type (tprec, 1);
5157 2 : tree cst = wide_int_to_tree (t, wi::mask (prec, true, tprec));
5158 2 : int len = native_encode_expr (cst, buf->buf + buf->size, sz);
5159 2 : gcc_assert (len > 0 && (size_t) len == (size_t) sz);
5160 : }
5161 : else
5162 0 : memset (buf->buf + buf->size, 0, sz);
5163 2 : buf->size += sz;
5164 2 : break;
5165 : }
5166 2 : tree limbtype
5167 2 : = build_nonstandard_integer_type (GET_MODE_PRECISION (limb_mode), 1);
5168 2 : fldsz = int_size_in_bytes (limbtype);
5169 2 : nelts = int_size_in_bytes (type) / fldsz;
5170 13 : for (HOST_WIDE_INT i = 0; i < nelts; i++)
5171 : {
5172 11 : if (!info.extended
5173 11 : && i == (info.big_endian ? 0 : nelts - 1)
5174 13 : && (((unsigned) TYPE_PRECISION (type))
5175 2 : % TYPE_PRECISION (limbtype)) != 0)
5176 : {
5177 2 : int tprec = GET_MODE_PRECISION (limb_mode);
5178 2 : int prec = (((unsigned) TYPE_PRECISION (type)) % tprec);
5179 2 : tree cst = wide_int_to_tree (limbtype,
5180 2 : wi::mask (prec, true, tprec));
5181 2 : int len = native_encode_expr (cst, buf->buf + buf->size,
5182 : fldsz);
5183 2 : gcc_assert (len > 0 && (size_t) len == (size_t) fldsz);
5184 2 : buf->size += fldsz;
5185 : }
5186 : else
5187 9 : clear_padding_type (buf, limbtype, fldsz, for_auto_init);
5188 : }
5189 : break;
5190 : }
5191 0 : case ENUMERAL_TYPE:
5192 0 : if (BITINT_TYPE_P (type))
5193 0 : goto do_bitint;
5194 : /* FALLTHRU */
5195 21589 : default:
5196 21589 : gcc_assert ((size_t) sz <= clear_padding_unit);
5197 21589 : if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
5198 0 : clear_padding_flush (buf, false);
5199 21589 : memset (buf->buf + buf->size, 0, sz);
5200 21589 : buf->size += sz;
5201 21589 : break;
5202 : }
5203 73769 : }
5204 :
5205 : /* Clear padding bits of TYPE in MASK. */
5206 :
5207 : void
5208 37689 : clear_type_padding_in_mask (tree type, unsigned char *mask)
5209 : {
5210 37689 : clear_padding_struct buf;
5211 37689 : buf.loc = UNKNOWN_LOCATION;
5212 37689 : buf.clear_in_mask = true;
5213 37689 : buf.base = NULL_TREE;
5214 37689 : buf.alias_type = NULL_TREE;
5215 37689 : buf.gsi = NULL;
5216 37689 : buf.align = 0;
5217 37689 : buf.off = 0;
5218 37689 : buf.padding_bytes = 0;
5219 37689 : buf.sz = int_size_in_bytes (type);
5220 37689 : buf.size = 0;
5221 37689 : buf.union_ptr = mask;
5222 37689 : clear_padding_type (&buf, type, buf.sz, false);
5223 37689 : clear_padding_flush (&buf, true);
5224 37689 : }
5225 :
5226 : /* Fold __builtin_clear_padding builtin. */
5227 :
5228 : static bool
5229 631 : gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
5230 : {
5231 631 : gimple *stmt = gsi_stmt (*gsi);
5232 631 : gcc_assert (gimple_call_num_args (stmt) == 2);
5233 631 : tree ptr = gimple_call_arg (stmt, 0);
5234 631 : tree typearg = gimple_call_arg (stmt, 1);
5235 : /* The 2nd argument of __builtin_clear_padding's value is used to
5236 : distinguish whether this call is made by the user or by the compiler
5237 : for automatic variable initialization. */
5238 631 : bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg);
5239 631 : tree type = TREE_TYPE (TREE_TYPE (typearg));
5240 631 : location_t loc = gimple_location (stmt);
5241 631 : clear_padding_struct buf;
5242 631 : gimple_stmt_iterator gsiprev = *gsi;
5243 : /* This should be folded during the lower pass. */
5244 1262 : gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL);
5245 631 : gcc_assert (COMPLETE_TYPE_P (type));
5246 631 : gsi_prev (&gsiprev);
5247 :
5248 631 : buf.loc = loc;
5249 631 : buf.clear_in_mask = false;
5250 631 : buf.base = ptr;
5251 631 : buf.alias_type = NULL_TREE;
5252 631 : buf.gsi = gsi;
5253 631 : buf.align = get_pointer_alignment (ptr);
5254 631 : unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT;
5255 631 : buf.align = MAX (buf.align, talign);
5256 631 : buf.off = 0;
5257 631 : buf.padding_bytes = 0;
5258 631 : buf.size = 0;
5259 631 : buf.sz = int_size_in_bytes (type);
5260 631 : buf.union_ptr = NULL;
5261 631 : if (buf.sz < 0 && int_size_in_bytes (strip_array_types (type)) < 0)
5262 1 : sorry_at (loc, "%s not supported for variable length aggregates",
5263 : "__builtin_clear_padding");
5264 : /* The implementation currently assumes 8-bit host and target
5265 : chars which is the case for all currently supported targets
5266 : and hosts and is required e.g. for native_{encode,interpret}* APIs. */
5267 630 : else if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
5268 : sorry_at (loc, "%s not supported on this target",
5269 : "__builtin_clear_padding");
5270 630 : else if (!clear_padding_type_may_have_padding_p (type))
5271 : ;
5272 593 : else if (TREE_CODE (type) == ARRAY_TYPE && buf.sz < 0)
5273 : {
5274 48 : tree sz = TYPE_SIZE_UNIT (type);
5275 48 : tree elttype = type;
5276 : /* Only supports C/C++ VLAs and flattens all the VLA levels. */
5277 48 : while (TREE_CODE (elttype) == ARRAY_TYPE
5278 144 : && int_size_in_bytes (elttype) < 0)
5279 96 : elttype = TREE_TYPE (elttype);
5280 48 : HOST_WIDE_INT eltsz = int_size_in_bytes (elttype);
5281 48 : gcc_assert (eltsz >= 0);
5282 48 : if (eltsz)
5283 : {
5284 48 : buf.base = create_tmp_var (build_pointer_type (elttype));
5285 48 : tree end = make_ssa_name (TREE_TYPE (buf.base));
5286 48 : gimple *g = gimple_build_assign (buf.base, ptr);
5287 48 : gimple_set_location (g, loc);
5288 48 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5289 48 : g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf.base, sz);
5290 48 : gimple_set_location (g, loc);
5291 48 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5292 48 : buf.sz = eltsz;
5293 48 : buf.align = TYPE_ALIGN (elttype);
5294 48 : buf.alias_type = build_pointer_type (elttype);
5295 48 : clear_padding_emit_loop (&buf, elttype, end, for_auto_init);
5296 : }
5297 : }
5298 : else
5299 : {
5300 545 : if (!is_gimple_mem_ref_addr (buf.base))
5301 : {
5302 28 : buf.base = make_ssa_name (TREE_TYPE (ptr));
5303 28 : gimple *g = gimple_build_assign (buf.base, ptr);
5304 28 : gimple_set_location (g, loc);
5305 28 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5306 : }
5307 545 : buf.alias_type = build_pointer_type (type);
5308 545 : clear_padding_type (&buf, type, buf.sz, for_auto_init);
5309 545 : clear_padding_flush (&buf, true);
5310 : }
5311 :
5312 631 : gimple_stmt_iterator gsiprev2 = *gsi;
5313 631 : gsi_prev (&gsiprev2);
5314 631 : if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
5315 126 : gsi_replace (gsi, gimple_build_nop (), true);
5316 : else
5317 : {
5318 505 : gsi_remove (gsi, true);
5319 505 : *gsi = gsiprev2;
5320 : }
5321 631 : return true;
5322 : }
5323 :
5324 : /* Fold __builtin_constant_p builtin. */
5325 :
5326 : static bool
5327 176906 : gimple_fold_builtin_constant_p (gimple_stmt_iterator *gsi)
5328 : {
5329 176906 : gcall *call = as_a<gcall*>(gsi_stmt (*gsi));
5330 :
5331 176906 : if (gimple_call_num_args (call) != 1)
5332 : return false;
5333 :
5334 176901 : tree arg = gimple_call_arg (call, 0);
5335 176901 : tree result = fold_builtin_constant_p (arg);
5336 :
5337 : /* Resolve __builtin_constant_p. If it hasn't been
5338 : folded to integer_one_node by now, it's fairly
5339 : certain that the value simply isn't constant. */
5340 351959 : if (!result && fold_before_rtl_expansion_p ())
5341 3 : result = integer_zero_node;
5342 :
5343 176901 : if (!result)
5344 : return false;
5345 :
5346 1846 : gimplify_and_update_call_from_tree (gsi, result);
5347 1846 : return true;
5348 : }
5349 :
5350 : /* If va_list type is a simple pointer and nothing special is needed,
5351 : optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
5352 : __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
5353 : pointer assignment. Returns true if a change happened. */
5354 :
5355 : static bool
5356 115157 : gimple_fold_builtin_stdarg (gimple_stmt_iterator *gsi, gcall *call)
5357 : {
5358 : /* These shouldn't be folded before pass_stdarg. */
5359 115157 : if (!fold_before_rtl_expansion_p ())
5360 : return false;
5361 :
5362 10826 : tree callee, lhs, rhs, cfun_va_list;
5363 10826 : bool va_list_simple_ptr;
5364 10826 : location_t loc = gimple_location (call);
5365 10826 : gimple *nstmt0, *nstmt;
5366 10826 : tree tlhs, oldvdef, newvdef;
5367 :
5368 10826 : callee = gimple_call_fndecl (call);
5369 :
5370 10826 : cfun_va_list = targetm.fn_abi_va_list (callee);
5371 21652 : va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
5372 10826 : && (TREE_TYPE (cfun_va_list) == void_type_node
5373 436 : || TREE_TYPE (cfun_va_list) == char_type_node);
5374 :
5375 10826 : switch (DECL_FUNCTION_CODE (callee))
5376 : {
5377 7013 : case BUILT_IN_VA_START:
5378 7013 : if (!va_list_simple_ptr
5379 172 : || targetm.expand_builtin_va_start != NULL
5380 7169 : || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
5381 : return false;
5382 :
5383 156 : if (gimple_call_num_args (call) != 2)
5384 : return false;
5385 :
5386 156 : lhs = gimple_call_arg (call, 0);
5387 156 : if (!POINTER_TYPE_P (TREE_TYPE (lhs))
5388 156 : || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
5389 156 : != TYPE_MAIN_VARIANT (cfun_va_list))
5390 : return false;
5391 : /* Create `tlhs = __builtin_next_arg(0);`. */
5392 156 : tlhs = make_ssa_name (cfun_va_list);
5393 156 : nstmt0 = gimple_build_call (builtin_decl_explicit (BUILT_IN_NEXT_ARG), 1, integer_zero_node);
5394 156 : lhs = fold_build2 (MEM_REF, cfun_va_list, lhs, build_zero_cst (TREE_TYPE (lhs)));
5395 156 : gimple_call_set_lhs (nstmt0, tlhs);
5396 156 : gimple_set_location (nstmt0, loc);
5397 156 : gimple_move_vops (nstmt0, call);
5398 156 : gsi_replace (gsi, nstmt0, false);
5399 156 : oldvdef = gimple_vdef (nstmt0);
5400 156 : newvdef = make_ssa_name (gimple_vop (cfun), nstmt0);
5401 156 : gimple_set_vdef (nstmt0, newvdef);
5402 :
5403 : /* Create `*lhs = tlhs;`. */
5404 156 : nstmt = gimple_build_assign (lhs, tlhs);
5405 156 : gimple_set_location (nstmt, loc);
5406 156 : gimple_set_vuse (nstmt, newvdef);
5407 156 : gimple_set_vdef (nstmt, oldvdef);
5408 156 : SSA_NAME_DEF_STMT (oldvdef) = nstmt;
5409 156 : gsi_insert_after (gsi, nstmt, GSI_NEW_STMT);
5410 :
5411 156 : if (dump_file && (dump_flags & TDF_DETAILS))
5412 : {
5413 0 : fprintf (dump_file, "Simplified\n ");
5414 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5415 0 : fprintf (dump_file, "into\n ");
5416 0 : print_gimple_stmt (dump_file, nstmt0, 0, dump_flags);
5417 0 : fprintf (dump_file, " ");
5418 0 : print_gimple_stmt (dump_file, nstmt, 0, dump_flags);
5419 : }
5420 : return true;
5421 :
5422 244 : case BUILT_IN_VA_COPY:
5423 244 : if (!va_list_simple_ptr)
5424 : return false;
5425 :
5426 47 : if (gimple_call_num_args (call) != 2)
5427 : return false;
5428 :
5429 47 : lhs = gimple_call_arg (call, 0);
5430 47 : if (!POINTER_TYPE_P (TREE_TYPE (lhs))
5431 47 : || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
5432 47 : != TYPE_MAIN_VARIANT (cfun_va_list))
5433 : return false;
5434 47 : rhs = gimple_call_arg (call, 1);
5435 47 : if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
5436 47 : != TYPE_MAIN_VARIANT (cfun_va_list))
5437 : return false;
5438 :
5439 47 : lhs = fold_build2 (MEM_REF, cfun_va_list, lhs, build_zero_cst (TREE_TYPE (lhs)));
5440 47 : nstmt = gimple_build_assign (lhs, rhs);
5441 47 : gimple_set_location (nstmt, loc);
5442 47 : gimple_move_vops (nstmt, call);
5443 47 : gsi_replace (gsi, nstmt, false);
5444 :
5445 47 : if (dump_file && (dump_flags & TDF_DETAILS))
5446 : {
5447 0 : fprintf (dump_file, "Simplified\n ");
5448 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5449 0 : fprintf (dump_file, "into\n ");
5450 0 : print_gimple_stmt (dump_file, nstmt, 0, dump_flags);
5451 : }
5452 : return true;
5453 :
5454 3569 : case BUILT_IN_VA_END:
5455 : /* No effect, so the statement will be deleted. */
5456 3569 : if (dump_file && (dump_flags & TDF_DETAILS))
5457 : {
5458 0 : fprintf (dump_file, "Removed\n ");
5459 0 : print_gimple_stmt (dump_file, call, 0, dump_flags);
5460 : }
5461 3569 : unlink_stmt_vdef (call);
5462 3569 : release_defs (call);
5463 3569 : gsi_replace (gsi, gimple_build_nop (), false);
5464 3569 : return true;
5465 :
5466 0 : default:
5467 0 : gcc_unreachable ();
5468 : }
5469 : }
5470 :
5471 : /* Fold __builtin_call_{code_address,static_chain} builtins. This handles
5472 : only the trivial left-over cases not processed in tree-nested.cc. */
5473 :
5474 : static bool
5475 2 : gimple_fold_builtin_call_info (gimple_stmt_iterator *gsi,
5476 : enum built_in_function fcode)
5477 : {
5478 2 : gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
5479 2 : tree arg = gimple_call_arg (stmt, 0);
5480 :
5481 : /* The error will be emitted in builtins.cc. */
5482 2 : if (TREE_CODE (arg) != ADDR_EXPR
5483 2 : || FUNCTION_DECL != TREE_CODE (TREE_OPERAND (arg, 0)))
5484 : return false;
5485 :
5486 : /* The case with static chain is handled in tree-nested.cc. */
5487 2 : gcc_assert (!DECL_STATIC_CHAIN (TREE_OPERAND (arg, 0)));
5488 :
5489 2 : if (fcode == BUILT_IN_CALL_STATIC_CHAIN)
5490 1 : replace_call_with_value (gsi, null_pointer_node);
5491 : else
5492 1 : replace_call_with_value (gsi, arg);
5493 :
5494 : return true;
5495 : }
5496 :
5497 :
5498 : /* Fold the non-target builtin at *GSI and return whether any simplification
5499 : was made. */
5500 :
5501 : static bool
5502 9533874 : gimple_fold_builtin (gimple_stmt_iterator *gsi)
5503 : {
5504 9533874 : gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
5505 9533874 : tree callee = gimple_call_fndecl (stmt);
5506 :
5507 : /* Give up for always_inline inline builtins until they are
5508 : inlined. */
5509 9533874 : if (avoid_folding_inline_builtin (callee))
5510 : return false;
5511 :
5512 9532698 : unsigned n = gimple_call_num_args (stmt);
5513 9532698 : enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
5514 9532698 : switch (fcode)
5515 : {
5516 115157 : case BUILT_IN_VA_START:
5517 115157 : case BUILT_IN_VA_END:
5518 115157 : case BUILT_IN_VA_COPY:
5519 115157 : return gimple_fold_builtin_stdarg (gsi, stmt);
5520 148 : case BUILT_IN_BCMP:
5521 148 : return gimple_fold_builtin_bcmp (gsi);
5522 367 : case BUILT_IN_BCOPY:
5523 367 : return gimple_fold_builtin_bcopy (gsi);
5524 250 : case BUILT_IN_BZERO:
5525 250 : return gimple_fold_builtin_bzero (gsi);
5526 :
5527 313865 : case BUILT_IN_MEMSET:
5528 313865 : return gimple_fold_builtin_memset (gsi,
5529 : gimple_call_arg (stmt, 1),
5530 313865 : gimple_call_arg (stmt, 2));
5531 10276 : case BUILT_IN_MEMPCPY:
5532 10276 : if (gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5533 : gimple_call_arg (stmt, 1), fcode))
5534 : return true;
5535 9536 : return gimple_fold_builtin_mempcpy (gsi);
5536 1007196 : case BUILT_IN_MEMCPY:
5537 1007196 : case BUILT_IN_MEMMOVE:
5538 1007196 : return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5539 1007196 : gimple_call_arg (stmt, 1), fcode);
5540 4459 : case BUILT_IN_SPRINTF_CHK:
5541 4459 : case BUILT_IN_VSPRINTF_CHK:
5542 4459 : return gimple_fold_builtin_sprintf_chk (gsi, fcode);
5543 1493 : case BUILT_IN_STRCAT_CHK:
5544 1493 : return gimple_fold_builtin_strcat_chk (gsi);
5545 1116 : case BUILT_IN_STRNCAT_CHK:
5546 1116 : return gimple_fold_builtin_strncat_chk (gsi);
5547 142340 : case BUILT_IN_STRLEN:
5548 142340 : return gimple_fold_builtin_strlen (gsi);
5549 26274 : case BUILT_IN_STRCPY:
5550 26274 : return gimple_fold_builtin_strcpy (gsi,
5551 : gimple_call_arg (stmt, 0),
5552 26274 : gimple_call_arg (stmt, 1));
5553 17274 : case BUILT_IN_STRNCPY:
5554 17274 : return gimple_fold_builtin_strncpy (gsi,
5555 : gimple_call_arg (stmt, 0),
5556 : gimple_call_arg (stmt, 1),
5557 17274 : gimple_call_arg (stmt, 2));
5558 7475 : case BUILT_IN_STRCAT:
5559 7475 : return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
5560 7475 : gimple_call_arg (stmt, 1));
5561 6786 : case BUILT_IN_STRNCAT:
5562 6786 : return gimple_fold_builtin_strncat (gsi);
5563 4743 : case BUILT_IN_INDEX:
5564 4743 : case BUILT_IN_STRCHR:
5565 4743 : return gimple_fold_builtin_strchr (gsi, false);
5566 728 : case BUILT_IN_RINDEX:
5567 728 : case BUILT_IN_STRRCHR:
5568 728 : return gimple_fold_builtin_strchr (gsi, true);
5569 4478 : case BUILT_IN_STRSTR:
5570 4478 : return gimple_fold_builtin_strstr (gsi);
5571 1250740 : case BUILT_IN_STRCMP:
5572 1250740 : case BUILT_IN_STRCMP_EQ:
5573 1250740 : case BUILT_IN_STRCASECMP:
5574 1250740 : case BUILT_IN_STRNCMP:
5575 1250740 : case BUILT_IN_STRNCMP_EQ:
5576 1250740 : case BUILT_IN_STRNCASECMP:
5577 1250740 : return gimple_fold_builtin_string_compare (gsi);
5578 31742 : case BUILT_IN_MEMCHR:
5579 31742 : return gimple_fold_builtin_memchr (gsi);
5580 20732 : case BUILT_IN_FPUTS:
5581 20732 : return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5582 20732 : gimple_call_arg (stmt, 1), false);
5583 43 : case BUILT_IN_FPUTS_UNLOCKED:
5584 43 : return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5585 43 : gimple_call_arg (stmt, 1), true);
5586 25701 : case BUILT_IN_MEMCPY_CHK:
5587 25701 : case BUILT_IN_MEMPCPY_CHK:
5588 25701 : case BUILT_IN_MEMMOVE_CHK:
5589 25701 : case BUILT_IN_MEMSET_CHK:
5590 25701 : return gimple_fold_builtin_memory_chk (gsi,
5591 : gimple_call_arg (stmt, 0),
5592 : gimple_call_arg (stmt, 1),
5593 : gimple_call_arg (stmt, 2),
5594 : gimple_call_arg (stmt, 3),
5595 25701 : fcode);
5596 3674 : case BUILT_IN_STPCPY:
5597 3674 : return gimple_fold_builtin_stpcpy (gsi);
5598 2566 : case BUILT_IN_STRCPY_CHK:
5599 2566 : case BUILT_IN_STPCPY_CHK:
5600 2566 : return gimple_fold_builtin_stxcpy_chk (gsi,
5601 : gimple_call_arg (stmt, 0),
5602 : gimple_call_arg (stmt, 1),
5603 : gimple_call_arg (stmt, 2),
5604 2566 : fcode);
5605 2721 : case BUILT_IN_STRNCPY_CHK:
5606 2721 : case BUILT_IN_STPNCPY_CHK:
5607 2721 : return gimple_fold_builtin_stxncpy_chk (gsi,
5608 : gimple_call_arg (stmt, 0),
5609 : gimple_call_arg (stmt, 1),
5610 : gimple_call_arg (stmt, 2),
5611 : gimple_call_arg (stmt, 3),
5612 2721 : fcode);
5613 2359 : case BUILT_IN_SNPRINTF_CHK:
5614 2359 : case BUILT_IN_VSNPRINTF_CHK:
5615 2359 : return gimple_fold_builtin_snprintf_chk (gsi, fcode);
5616 :
5617 847572 : case BUILT_IN_FPRINTF:
5618 847572 : case BUILT_IN_FPRINTF_UNLOCKED:
5619 847572 : case BUILT_IN_VFPRINTF:
5620 847572 : if (n == 2 || n == 3)
5621 95140 : return gimple_fold_builtin_fprintf (gsi,
5622 : gimple_call_arg (stmt, 0),
5623 : gimple_call_arg (stmt, 1),
5624 : n == 3
5625 42582 : ? gimple_call_arg (stmt, 2)
5626 : : NULL_TREE,
5627 52558 : fcode);
5628 : break;
5629 2229 : case BUILT_IN_FPRINTF_CHK:
5630 2229 : case BUILT_IN_VFPRINTF_CHK:
5631 2229 : if (n == 3 || n == 4)
5632 3814 : return gimple_fold_builtin_fprintf (gsi,
5633 : gimple_call_arg (stmt, 0),
5634 : gimple_call_arg (stmt, 2),
5635 : n == 4
5636 1744 : ? gimple_call_arg (stmt, 3)
5637 : : NULL_TREE,
5638 2070 : fcode);
5639 : break;
5640 199965 : case BUILT_IN_PRINTF:
5641 199965 : case BUILT_IN_PRINTF_UNLOCKED:
5642 199965 : case BUILT_IN_VPRINTF:
5643 199965 : if (n == 1 || n == 2)
5644 234936 : return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
5645 : n == 2
5646 112918 : ? gimple_call_arg (stmt, 1)
5647 122018 : : NULL_TREE, fcode);
5648 : break;
5649 2273 : case BUILT_IN_PRINTF_CHK:
5650 2273 : case BUILT_IN_VPRINTF_CHK:
5651 2273 : if (n == 2 || n == 3)
5652 3893 : return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 1),
5653 : n == 3
5654 1771 : ? gimple_call_arg (stmt, 2)
5655 2122 : : NULL_TREE, fcode);
5656 : break;
5657 2866 : case BUILT_IN_ACC_ON_DEVICE:
5658 2866 : return gimple_fold_builtin_acc_on_device (gsi,
5659 2866 : gimple_call_arg (stmt, 0));
5660 245 : case BUILT_IN_OMP_IS_INITIAL_DEVICE:
5661 245 : return gimple_fold_builtin_omp_is_initial_device (gsi);
5662 :
5663 103 : case BUILT_IN_OMP_GET_INITIAL_DEVICE:
5664 103 : return gimple_fold_builtin_omp_get_initial_device (gsi);
5665 :
5666 321 : case BUILT_IN_OMP_GET_NUM_DEVICES:
5667 321 : return gimple_fold_builtin_omp_get_num_devices (gsi);
5668 :
5669 49410 : case BUILT_IN_REALLOC:
5670 49410 : return gimple_fold_builtin_realloc (gsi);
5671 :
5672 631 : case BUILT_IN_CLEAR_PADDING:
5673 631 : return gimple_fold_builtin_clear_padding (gsi);
5674 :
5675 176906 : case BUILT_IN_CONSTANT_P:
5676 176906 : return gimple_fold_builtin_constant_p (gsi);
5677 :
5678 2 : case BUILT_IN_CALL_CODE_ADDRESS:
5679 2 : case BUILT_IN_CALL_STATIC_CHAIN:
5680 2 : return gimple_fold_builtin_call_info (gsi, fcode);
5681 :
5682 6118743 : default:;
5683 : }
5684 :
5685 : /* Try the generic builtin folder. */
5686 6118743 : bool ignore = (gimple_call_lhs (stmt) == NULL);
5687 6118743 : tree result = fold_call_stmt (stmt, ignore);
5688 6118743 : if (result)
5689 : {
5690 5071 : if (ignore)
5691 1235 : STRIP_NOPS (result);
5692 : else
5693 3836 : result = fold_convert (gimple_call_return_type (stmt), result);
5694 5071 : gimplify_and_update_call_from_tree (gsi, result);
5695 5071 : return true;
5696 : }
5697 :
5698 : return false;
5699 : }
5700 :
5701 : /* Transform IFN_GOACC_DIM_SIZE and IFN_GOACC_DIM_POS internal
5702 : function calls to constants, where possible. */
5703 :
5704 : static tree
5705 20589 : fold_internal_goacc_dim (const gimple *call)
5706 : {
5707 20589 : int axis = oacc_get_ifn_dim_arg (call);
5708 20589 : int size = oacc_get_fn_dim_size (current_function_decl, axis);
5709 20589 : tree result = NULL_TREE;
5710 20589 : tree type = TREE_TYPE (gimple_call_lhs (call));
5711 :
5712 20589 : switch (gimple_call_internal_fn (call))
5713 : {
5714 8915 : case IFN_GOACC_DIM_POS:
5715 : /* If the size is 1, we know the answer. */
5716 8915 : if (size == 1)
5717 8915 : result = build_int_cst (type, 0);
5718 : break;
5719 11674 : case IFN_GOACC_DIM_SIZE:
5720 : /* If the size is not dynamic, we know the answer. */
5721 11674 : if (size)
5722 11674 : result = build_int_cst (type, size);
5723 : break;
5724 : default:
5725 : break;
5726 : }
5727 :
5728 20589 : return result;
5729 : }
5730 :
5731 : /* Return true if stmt is __atomic_compare_exchange_N call which is suitable
5732 : for conversion into ATOMIC_COMPARE_EXCHANGE if the second argument is
5733 : &var where var is only addressable because of such calls. */
5734 :
5735 : bool
5736 59894988 : optimize_atomic_compare_exchange_p (gimple *stmt)
5737 : {
5738 59894988 : if (gimple_call_num_args (stmt) != 6
5739 1653652 : || !flag_inline_atomics
5740 1653652 : || !optimize
5741 1653652 : || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
5742 1653571 : || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
5743 1110354 : || !gimple_vdef (stmt)
5744 60885641 : || !gimple_vuse (stmt))
5745 58904335 : return false;
5746 :
5747 990653 : tree fndecl = gimple_call_fndecl (stmt);
5748 990653 : switch (DECL_FUNCTION_CODE (fndecl))
5749 : {
5750 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
5751 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
5752 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
5753 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
5754 51845 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
5755 51845 : break;
5756 : default:
5757 : return false;
5758 : }
5759 :
5760 51845 : tree expected = gimple_call_arg (stmt, 1);
5761 51845 : if (TREE_CODE (expected) != ADDR_EXPR
5762 51845 : || !SSA_VAR_P (TREE_OPERAND (expected, 0)))
5763 : return false;
5764 :
5765 49464 : tree etype = TREE_TYPE (TREE_OPERAND (expected, 0));
5766 49464 : if (!is_gimple_reg_type (etype)
5767 49037 : || !auto_var_in_fn_p (TREE_OPERAND (expected, 0), current_function_decl)
5768 46625 : || TREE_THIS_VOLATILE (etype)
5769 46625 : || VECTOR_TYPE_P (etype)
5770 : || TREE_CODE (etype) == COMPLEX_TYPE
5771 : /* Don't optimize floating point expected vars, VIEW_CONVERT_EXPRs
5772 : might not preserve all the bits. See PR71716. */
5773 : || SCALAR_FLOAT_TYPE_P (etype)
5774 67482 : || maybe_ne (TYPE_PRECISION (etype),
5775 36036 : GET_MODE_BITSIZE (TYPE_MODE (etype))))
5776 37854 : return false;
5777 :
5778 11610 : tree weak = gimple_call_arg (stmt, 3);
5779 11610 : if (!integer_zerop (weak) && !integer_onep (weak))
5780 : return false;
5781 :
5782 11610 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5783 11610 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5784 11610 : machine_mode mode = TYPE_MODE (itype);
5785 :
5786 11610 : if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
5787 : == CODE_FOR_nothing
5788 11610 : && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
5789 : return false;
5790 :
5791 23220 : if (maybe_ne (int_size_in_bytes (etype), GET_MODE_SIZE (mode)))
5792 : return false;
5793 :
5794 : return true;
5795 : }
5796 :
5797 : /* Fold
5798 : r = __atomic_compare_exchange_N (p, &e, d, w, s, f);
5799 : into
5800 : _Complex uintN_t t = ATOMIC_COMPARE_EXCHANGE (p, e, d, w * 256 + N, s, f);
5801 : i = IMAGPART_EXPR <t>;
5802 : r = (_Bool) i;
5803 : e = REALPART_EXPR <t>; */
5804 :
5805 : void
5806 5730 : fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
5807 : {
5808 5730 : gimple *stmt = gsi_stmt (*gsi);
5809 5730 : tree fndecl = gimple_call_fndecl (stmt);
5810 5730 : tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5811 5730 : tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
5812 5730 : tree ctype = build_complex_type (itype);
5813 5730 : tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
5814 5730 : bool throws = false;
5815 5730 : edge e = NULL;
5816 5730 : gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5817 : expected);
5818 5730 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5819 5730 : gimple_stmt_iterator gsiret = gsi_for_stmt (g);
5820 5730 : if (!useless_type_conversion_p (itype, TREE_TYPE (expected)))
5821 : {
5822 2648 : g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
5823 : build1 (VIEW_CONVERT_EXPR, itype,
5824 : gimple_assign_lhs (g)));
5825 2648 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5826 : }
5827 5730 : int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
5828 11077 : + int_size_in_bytes (itype);
5829 5730 : g = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE, 6,
5830 : gimple_call_arg (stmt, 0),
5831 : gimple_assign_lhs (g),
5832 : gimple_call_arg (stmt, 2),
5833 5730 : build_int_cst (integer_type_node, flag),
5834 : gimple_call_arg (stmt, 4),
5835 : gimple_call_arg (stmt, 5));
5836 5730 : tree lhs = make_ssa_name (ctype);
5837 5730 : gimple_call_set_lhs (g, lhs);
5838 5730 : gimple_move_vops (g, stmt);
5839 5730 : tree oldlhs = gimple_call_lhs (stmt);
5840 5730 : if (stmt_can_throw_internal (cfun, stmt))
5841 : {
5842 203 : throws = true;
5843 203 : e = find_fallthru_edge (gsi_bb (*gsi)->succs);
5844 : }
5845 5730 : gimple_call_set_nothrow (as_a <gcall *> (g),
5846 5730 : gimple_call_nothrow_p (as_a <gcall *> (stmt)));
5847 5730 : gimple_call_set_lhs (stmt, NULL_TREE);
5848 5730 : gsi_replace (gsi, g, true);
5849 5730 : if (oldlhs)
5850 : {
5851 5683 : g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
5852 : build1 (IMAGPART_EXPR, itype, lhs));
5853 5683 : if (throws)
5854 : {
5855 197 : gsi_insert_on_edge_immediate (e, g);
5856 197 : *gsi = gsi_for_stmt (g);
5857 : }
5858 : else
5859 5486 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5860 5683 : g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
5861 5683 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5862 : }
5863 5730 : g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
5864 : build1 (REALPART_EXPR, itype, lhs));
5865 5730 : if (throws && oldlhs == NULL_TREE)
5866 : {
5867 6 : gsi_insert_on_edge_immediate (e, g);
5868 6 : *gsi = gsi_for_stmt (g);
5869 : }
5870 : else
5871 5724 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5872 5730 : if (!useless_type_conversion_p (TREE_TYPE (expected), itype))
5873 : {
5874 5296 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
5875 : VIEW_CONVERT_EXPR,
5876 2648 : build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected),
5877 : gimple_assign_lhs (g)));
5878 2648 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5879 : }
5880 5730 : g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
5881 5730 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
5882 5730 : *gsi = gsiret;
5883 5730 : }
5884 :
5885 : /* Return true if ARG0 CODE ARG1 in infinite signed precision operation
5886 : doesn't fit into TYPE. The test for overflow should be regardless of
5887 : -fwrapv, and even for unsigned types. */
5888 :
5889 : bool
5890 447001 : arith_overflowed_p (enum tree_code code, const_tree type,
5891 : const_tree arg0, const_tree arg1)
5892 : {
5893 447001 : widest2_int warg0 = widest2_int_cst (arg0);
5894 447001 : widest2_int warg1 = widest2_int_cst (arg1);
5895 447001 : widest2_int wres;
5896 447001 : switch (code)
5897 : {
5898 96367 : case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
5899 115675 : case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
5900 236410 : case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
5901 0 : default: gcc_unreachable ();
5902 : }
5903 447001 : signop sign = TYPE_SIGN (type);
5904 447001 : if (sign == UNSIGNED && wi::neg_p (wres))
5905 : return true;
5906 375074 : return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
5907 447141 : }
5908 :
5909 : /* Mask state for partial load/store operations (mask and length). */
5910 : enum mask_load_store_state {
5911 : MASK_ALL_INACTIVE, /* All lanes/elements are inactive (can be elided). */
5912 : MASK_ALL_ACTIVE, /* All lanes/elements are active (unconditional). */
5913 : MASK_UNKNOWN
5914 : };
5915 :
5916 : /* Check the mask/length state of IFN_{MASK,LEN,MASK_LEN}_LOAD/STORE call CALL.
5917 : Returns whether all elements are active, all inactive, or mixed.
5918 : VECTYPE is the vector type of the operation. */
5919 :
5920 : static enum mask_load_store_state
5921 7951 : partial_load_store_mask_state (gcall *call, tree vectype)
5922 : {
5923 7951 : internal_fn ifn = gimple_call_internal_fn (call);
5924 7951 : int mask_index = internal_fn_mask_index (ifn);
5925 7951 : int len_index = internal_fn_len_index (ifn);
5926 :
5927 : /* Extract length and mask arguments up front. */
5928 7951 : tree len = len_index != -1 ? gimple_call_arg (call, len_index) : NULL_TREE;
5929 0 : tree bias = len ? gimple_call_arg (call, len_index + 1) : NULL_TREE;
5930 7951 : tree mask = mask_index != -1 ? gimple_call_arg (call, mask_index) : NULL_TREE;
5931 :
5932 15902 : poly_int64 nelts = GET_MODE_NUNITS (TYPE_MODE (vectype));
5933 :
5934 7951 : poly_widest_int wlen = -1;
5935 7951 : bool full_length_p = !len; /* No length means full length. */
5936 :
5937 : /* Compute effective length. */
5938 7951 : if (len && poly_int_tree_p (len))
5939 : {
5940 0 : gcc_assert (TREE_CODE (bias) == INTEGER_CST);
5941 0 : wlen = wi::to_poly_widest (len) + wi::to_widest (bias);
5942 :
5943 0 : if (known_eq (wlen, 0))
5944 : return MASK_ALL_INACTIVE;
5945 :
5946 0 : if (known_eq (wlen, nelts))
5947 : full_length_p = true;
5948 : else
5949 : full_length_p = false;
5950 : }
5951 :
5952 : /* Check mask for early return cases. */
5953 7951 : if (mask)
5954 : {
5955 7951 : if (integer_zerop (mask))
5956 : return MASK_ALL_INACTIVE;
5957 :
5958 7936 : if (full_length_p && integer_all_onesp (mask))
5959 : return MASK_ALL_ACTIVE;
5960 : }
5961 0 : else if (full_length_p)
5962 : /* No mask and full length means all active. */
5963 : return MASK_ALL_ACTIVE;
5964 :
5965 : /* For VLA vectors, we can't do much more. */
5966 7786 : if (!nelts.is_constant ())
5967 : return MASK_UNKNOWN;
5968 :
5969 : /* Same for VLS vectors with non-constant mask. */
5970 7786 : if (mask && TREE_CODE (mask) != VECTOR_CST)
5971 : return MASK_UNKNOWN;
5972 :
5973 : /* Check VLS vector elements. */
5974 504 : gcc_assert (wlen.is_constant ());
5975 :
5976 504 : HOST_WIDE_INT active_len = wlen.to_constant ().to_shwi ();
5977 504 : if (active_len == -1)
5978 504 : active_len = nelts.to_constant ();
5979 :
5980 : /* Check if all elements in the active range match the mask. */
5981 1038 : for (HOST_WIDE_INT i = 0; i < active_len; i++)
5982 : {
5983 1038 : bool elt_active = !mask || !integer_zerop (vector_cst_elt (mask, i));
5984 534 : if (!elt_active)
5985 : {
5986 : /* Found an inactive element. Check if all are inactive. */
5987 1002 : for (HOST_WIDE_INT j = 0; j < active_len; j++)
5988 1002 : if (!mask || !integer_zerop (vector_cst_elt (mask, j)))
5989 : return MASK_UNKNOWN; /* Mixed state. */
5990 : return MASK_ALL_INACTIVE;
5991 : }
5992 : }
5993 :
5994 : /* All elements in active range are active. */
5995 0 : return full_length_p ? MASK_ALL_ACTIVE : MASK_UNKNOWN;
5996 7951 : }
5997 :
5998 :
5999 : /* If IFN_{MASK,LEN,MASK_LEN}_LOAD/STORE call CALL is unconditional
6000 : (all lanes active), return a MEM_REF for the memory it references.
6001 : Otherwise return NULL_TREE. VECTYPE is the type of the memory vector. */
6002 :
6003 : static tree
6004 3968 : gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype)
6005 : {
6006 : /* Only fold if all lanes are active (unconditional). */
6007 3968 : if (partial_load_store_mask_state (call, vectype) != MASK_ALL_ACTIVE)
6008 : return NULL_TREE;
6009 :
6010 75 : tree ptr = gimple_call_arg (call, 0);
6011 75 : tree alias_align = gimple_call_arg (call, 1);
6012 75 : if (!tree_fits_uhwi_p (alias_align))
6013 : return NULL_TREE;
6014 :
6015 75 : unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
6016 75 : if (TYPE_ALIGN (vectype) != align)
6017 14 : vectype = build_aligned_type (vectype, align);
6018 75 : tree offset = build_zero_cst (TREE_TYPE (alias_align));
6019 75 : return fold_build2 (MEM_REF, vectype, ptr, offset);
6020 : }
6021 :
6022 : /* Try to fold IFN_{MASK,LEN}_LOAD/STORE call CALL. Return true on success. */
6023 :
6024 : static bool
6025 3983 : gimple_fold_partial_load_store (gimple_stmt_iterator *gsi, gcall *call)
6026 : {
6027 3983 : internal_fn ifn = gimple_call_internal_fn (call);
6028 3983 : tree lhs = gimple_call_lhs (call);
6029 3983 : bool is_load = (lhs != NULL_TREE);
6030 3983 : tree vectype;
6031 :
6032 3983 : if (is_load)
6033 1991 : vectype = TREE_TYPE (lhs);
6034 : else
6035 : {
6036 1992 : tree rhs = gimple_call_arg (call, internal_fn_stored_value_index (ifn));
6037 1992 : vectype = TREE_TYPE (rhs);
6038 : }
6039 :
6040 3983 : enum mask_load_store_state state
6041 3983 : = partial_load_store_mask_state (call, vectype);
6042 :
6043 : /* Handle all-inactive case. */
6044 3983 : if (state == MASK_ALL_INACTIVE)
6045 : {
6046 15 : if (is_load)
6047 : {
6048 : /* Replace load with else value. */
6049 15 : int else_index = internal_fn_else_index (ifn);
6050 15 : tree else_value = gimple_call_arg (call, else_index);
6051 15 : if (!is_gimple_reg (lhs))
6052 : {
6053 0 : if (!zerop (else_value))
6054 : return false;
6055 0 : else_value = build_constructor (TREE_TYPE (lhs), NULL);
6056 : }
6057 15 : gassign *new_stmt = gimple_build_assign (lhs, else_value);
6058 15 : gimple_set_location (new_stmt, gimple_location (call));
6059 : /* When the lhs is an array for LANES version, then there is still
6060 : a store, move the vops from the old stmt to the new one. */
6061 15 : if (!is_gimple_reg (lhs))
6062 0 : gimple_move_vops (new_stmt, call);
6063 15 : gsi_replace (gsi, new_stmt, false);
6064 15 : return true;
6065 : }
6066 : else
6067 : {
6068 : /* Remove inactive store altogether. */
6069 0 : unlink_stmt_vdef (call);
6070 0 : release_defs (call);
6071 0 : gsi_replace (gsi, gimple_build_nop (), true);
6072 0 : return true;
6073 : }
6074 : }
6075 :
6076 : /* We cannot simplify a gather/scatter or load/store lanes further. */
6077 3968 : if (internal_gather_scatter_fn_p (ifn)
6078 3968 : || TREE_CODE (vectype) == ARRAY_TYPE)
6079 : return false;
6080 :
6081 : /* Handle all-active case by folding to regular memory operation. */
6082 3968 : if (tree mem_ref = gimple_fold_partial_load_store_mem_ref (call, vectype))
6083 : {
6084 75 : gassign *new_stmt;
6085 75 : if (is_load)
6086 21 : new_stmt = gimple_build_assign (lhs, mem_ref);
6087 : else
6088 : {
6089 54 : tree rhs
6090 54 : = gimple_call_arg (call, internal_fn_stored_value_index (ifn));
6091 54 : new_stmt = gimple_build_assign (mem_ref, rhs);
6092 : }
6093 :
6094 75 : gimple_set_location (new_stmt, gimple_location (call));
6095 75 : gimple_move_vops (new_stmt, call);
6096 75 : gsi_replace (gsi, new_stmt, false);
6097 75 : return true;
6098 : }
6099 : return false;
6100 : }
6101 :
6102 : /* Attempt to fold a call statement referenced by the statement iterator GSI.
6103 : The statement may be replaced by another statement, e.g., if the call
6104 : simplifies to a constant value. Return true if any changes were made.
6105 : It is assumed that the operands have been previously folded. */
6106 :
6107 : static bool
6108 57176435 : gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
6109 : {
6110 57176435 : gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
6111 57176435 : tree callee;
6112 57176435 : bool changed = false;
6113 :
6114 : /* Check for virtual calls that became direct calls. */
6115 57176435 : callee = gimple_call_fn (stmt);
6116 57176435 : if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
6117 : {
6118 448404 : if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
6119 : {
6120 6 : if (dump_file && virtual_method_call_p (callee)
6121 408 : && !possible_polymorphic_call_target_p
6122 6 : (callee, stmt, cgraph_node::get (gimple_call_addr_fndecl
6123 6 : (OBJ_TYPE_REF_EXPR (callee)))))
6124 : {
6125 0 : fprintf (dump_file,
6126 : "Type inheritance inconsistent devirtualization of ");
6127 0 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
6128 0 : fprintf (dump_file, " to ");
6129 0 : print_generic_expr (dump_file, callee, TDF_SLIM);
6130 0 : fprintf (dump_file, "\n");
6131 : }
6132 :
6133 402 : gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
6134 402 : changed = true;
6135 : }
6136 448002 : else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
6137 : {
6138 442919 : bool final;
6139 442919 : vec <cgraph_node *>targets
6140 442919 : = possible_polymorphic_call_targets (callee, stmt, &final);
6141 445583 : if (final && targets.length () <= 1 && dbg_cnt (devirt))
6142 : {
6143 2028 : tree lhs = gimple_call_lhs (stmt);
6144 2028 : if (dump_enabled_p ())
6145 : {
6146 34 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
6147 : "folding virtual function call to %s\n",
6148 34 : targets.length () == 1
6149 17 : ? targets[0]->name ()
6150 : : "__builtin_unreachable");
6151 : }
6152 2028 : if (targets.length () == 1)
6153 : {
6154 1989 : tree fndecl = targets[0]->decl;
6155 1989 : gimple_call_set_fndecl (stmt, fndecl);
6156 1989 : changed = true;
6157 : /* If changing the call to __cxa_pure_virtual
6158 : or similar noreturn function, adjust gimple_call_fntype
6159 : too. */
6160 1989 : if (gimple_call_noreturn_p (stmt)
6161 19 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
6162 13 : && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
6163 2002 : && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
6164 13 : == void_type_node))
6165 13 : gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
6166 : /* If the call becomes noreturn, remove the lhs. */
6167 1989 : if (lhs
6168 1668 : && gimple_call_noreturn_p (stmt)
6169 2004 : && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
6170 6 : || should_remove_lhs_p (lhs)))
6171 : {
6172 12 : if (TREE_CODE (lhs) == SSA_NAME)
6173 : {
6174 0 : tree var = create_tmp_var (TREE_TYPE (lhs));
6175 0 : tree def = get_or_create_ssa_default_def (cfun, var);
6176 0 : gimple *new_stmt = gimple_build_assign (lhs, def);
6177 0 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
6178 : }
6179 12 : gimple_call_set_lhs (stmt, NULL_TREE);
6180 : }
6181 1989 : maybe_remove_unused_call_args (cfun, stmt);
6182 : }
6183 : else
6184 : {
6185 39 : location_t loc = gimple_location (stmt);
6186 39 : gimple *new_stmt = gimple_build_builtin_unreachable (loc);
6187 39 : gimple_call_set_ctrl_altering (new_stmt, false);
6188 : /* If the call had a SSA name as lhs morph that into
6189 : an uninitialized value. */
6190 39 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
6191 : {
6192 12 : tree var = create_tmp_var (TREE_TYPE (lhs));
6193 12 : SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
6194 12 : SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
6195 12 : set_ssa_default_def (cfun, var, lhs);
6196 : }
6197 39 : gimple_move_vops (new_stmt, stmt);
6198 39 : gsi_replace (gsi, new_stmt, false);
6199 39 : return true;
6200 : }
6201 : }
6202 : }
6203 : }
6204 :
6205 : /* Check for indirect calls that became direct calls, and then
6206 : no longer require a static chain. */
6207 57176396 : if (gimple_call_chain (stmt))
6208 : {
6209 246567 : tree fn = gimple_call_fndecl (stmt);
6210 295602 : if (fn && !DECL_STATIC_CHAIN (fn))
6211 : {
6212 2054 : gimple_call_set_chain (stmt, NULL);
6213 2054 : changed = true;
6214 : }
6215 : }
6216 :
6217 57176396 : if (inplace)
6218 : return changed;
6219 :
6220 : /* Don't constant fold functions which can change the control. */
6221 57173330 : if (gimple_call_ctrl_altering_p (stmt))
6222 : return changed;
6223 :
6224 : /* Check for builtins that CCP can handle using information not
6225 : available in the generic fold routines. */
6226 49355696 : if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
6227 : {
6228 9533874 : if (gimple_fold_builtin (gsi))
6229 210655 : changed = true;
6230 : }
6231 39821822 : else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
6232 : {
6233 1154467 : changed |= targetm.gimple_fold_builtin (gsi);
6234 : }
6235 38667355 : else if (gimple_call_internal_p (stmt))
6236 : {
6237 1945661 : enum tree_code subcode = ERROR_MARK;
6238 1945661 : tree result = NULL_TREE;
6239 1945661 : bool cplx_result = false;
6240 1945661 : bool uaddc_usubc = false;
6241 1945661 : tree overflow = NULL_TREE;
6242 1945661 : switch (gimple_call_internal_fn (stmt))
6243 : {
6244 852 : case IFN_ASSUME:
6245 : /* Remove .ASSUME calls during the last fold since it is no
6246 : longer needed. */
6247 852 : if (fold_before_rtl_expansion_p ())
6248 116 : replace_call_with_value (gsi, NULL_TREE);
6249 : break;
6250 163798 : case IFN_BUILTIN_EXPECT:
6251 163798 : result = fold_builtin_expect (gimple_location (stmt),
6252 : gimple_call_arg (stmt, 0),
6253 : gimple_call_arg (stmt, 1),
6254 : gimple_call_arg (stmt, 2),
6255 : NULL_TREE);
6256 163798 : break;
6257 8884 : case IFN_UBSAN_OBJECT_SIZE:
6258 8884 : {
6259 8884 : tree offset = gimple_call_arg (stmt, 1);
6260 8884 : tree objsize = gimple_call_arg (stmt, 2);
6261 8884 : if (integer_all_onesp (objsize)
6262 8884 : || (TREE_CODE (offset) == INTEGER_CST
6263 4825 : && TREE_CODE (objsize) == INTEGER_CST
6264 1126 : && tree_int_cst_le (offset, objsize)))
6265 : {
6266 1539 : replace_call_with_value (gsi, NULL_TREE);
6267 1539 : return true;
6268 : }
6269 : }
6270 : break;
6271 11656 : case IFN_UBSAN_PTR:
6272 11656 : if (integer_zerop (gimple_call_arg (stmt, 1)))
6273 : {
6274 30 : replace_call_with_value (gsi, NULL_TREE);
6275 30 : return true;
6276 : }
6277 : break;
6278 8493 : case IFN_UBSAN_BOUNDS:
6279 8493 : {
6280 8493 : tree index = gimple_call_arg (stmt, 1);
6281 8493 : tree bound = gimple_call_arg (stmt, 2);
6282 8493 : if (TREE_CODE (index) == INTEGER_CST
6283 5471 : && TREE_CODE (bound) == INTEGER_CST)
6284 : {
6285 4340 : index = fold_convert (TREE_TYPE (bound), index);
6286 4340 : if (TREE_CODE (index) == INTEGER_CST
6287 4340 : && tree_int_cst_lt (index, bound))
6288 : {
6289 286 : replace_call_with_value (gsi, NULL_TREE);
6290 286 : return true;
6291 : }
6292 : }
6293 : }
6294 : break;
6295 20589 : case IFN_GOACC_DIM_SIZE:
6296 20589 : case IFN_GOACC_DIM_POS:
6297 20589 : result = fold_internal_goacc_dim (stmt);
6298 20589 : break;
6299 : case IFN_UBSAN_CHECK_ADD:
6300 : subcode = PLUS_EXPR;
6301 : break;
6302 : case IFN_UBSAN_CHECK_SUB:
6303 : subcode = MINUS_EXPR;
6304 : break;
6305 : case IFN_UBSAN_CHECK_MUL:
6306 : subcode = MULT_EXPR;
6307 : break;
6308 : case IFN_ADD_OVERFLOW:
6309 : subcode = PLUS_EXPR;
6310 : cplx_result = true;
6311 : break;
6312 : case IFN_SUB_OVERFLOW:
6313 : subcode = MINUS_EXPR;
6314 : cplx_result = true;
6315 : break;
6316 : case IFN_MUL_OVERFLOW:
6317 : subcode = MULT_EXPR;
6318 : cplx_result = true;
6319 : break;
6320 : case IFN_UADDC:
6321 : subcode = PLUS_EXPR;
6322 : cplx_result = true;
6323 : uaddc_usubc = true;
6324 : break;
6325 : case IFN_USUBC:
6326 : subcode = MINUS_EXPR;
6327 : cplx_result = true;
6328 : uaddc_usubc = true;
6329 : break;
6330 3983 : case IFN_LEN_LOAD:
6331 3983 : case IFN_MASK_LOAD:
6332 3983 : case IFN_MASK_LEN_LOAD:
6333 3983 : case IFN_MASK_GATHER_LOAD:
6334 3983 : case IFN_MASK_LEN_GATHER_LOAD:
6335 3983 : case IFN_MASK_LOAD_LANES:
6336 3983 : case IFN_MASK_LEN_LOAD_LANES:
6337 3983 : case IFN_LEN_STORE:
6338 3983 : case IFN_MASK_STORE:
6339 3983 : case IFN_MASK_LEN_STORE:
6340 3983 : case IFN_MASK_SCATTER_STORE:
6341 3983 : case IFN_MASK_LEN_SCATTER_STORE:
6342 3983 : case IFN_MASK_STORE_LANES:
6343 3983 : case IFN_MASK_LEN_STORE_LANES:
6344 3983 : changed |= gimple_fold_partial_load_store (gsi, stmt);
6345 3983 : break;
6346 : default:
6347 : break;
6348 : }
6349 188486 : if (subcode != ERROR_MARK)
6350 : {
6351 495229 : tree arg0 = gimple_call_arg (stmt, 0);
6352 495229 : tree arg1 = gimple_call_arg (stmt, 1);
6353 495229 : tree arg2 = NULL_TREE;
6354 495229 : tree type = TREE_TYPE (arg0);
6355 495229 : if (cplx_result)
6356 : {
6357 476104 : tree lhs = gimple_call_lhs (stmt);
6358 476104 : if (lhs == NULL_TREE)
6359 : type = NULL_TREE;
6360 : else
6361 476104 : type = TREE_TYPE (TREE_TYPE (lhs));
6362 476104 : if (uaddc_usubc)
6363 32477 : arg2 = gimple_call_arg (stmt, 2);
6364 : }
6365 495229 : if (type == NULL_TREE)
6366 : ;
6367 495229 : else if (uaddc_usubc)
6368 : {
6369 32477 : if (!integer_zerop (arg2))
6370 : ;
6371 : /* x = y + 0 + 0; x = y - 0 - 0; */
6372 4922 : else if (integer_zerop (arg1))
6373 : result = arg0;
6374 : /* x = 0 + y + 0; */
6375 4298 : else if (subcode != MINUS_EXPR && integer_zerop (arg0))
6376 : result = arg1;
6377 : /* x = y - y - 0; */
6378 4298 : else if (subcode == MINUS_EXPR
6379 4298 : && operand_equal_p (arg0, arg1, 0))
6380 0 : result = integer_zero_node;
6381 : }
6382 : /* x = y + 0; x = y - 0; x = y * 0; */
6383 462752 : else if (integer_zerop (arg1))
6384 10107 : result = subcode == MULT_EXPR ? integer_zero_node : arg0;
6385 : /* x = 0 + y; x = 0 * y; */
6386 452645 : else if (subcode != MINUS_EXPR && integer_zerop (arg0))
6387 0 : result = subcode == MULT_EXPR ? integer_zero_node : arg1;
6388 : /* x = y - y; */
6389 452645 : else if (subcode == MINUS_EXPR && operand_equal_p (arg0, arg1, 0))
6390 13 : result = integer_zero_node;
6391 : /* x = y * 1; x = 1 * y; */
6392 452632 : else if (subcode == MULT_EXPR && integer_onep (arg1))
6393 : result = arg0;
6394 447398 : else if (subcode == MULT_EXPR && integer_onep (arg0))
6395 : result = arg1;
6396 495229 : if (result)
6397 : {
6398 15978 : if (result == integer_zero_node)
6399 2146 : result = build_zero_cst (type);
6400 13832 : else if (cplx_result && TREE_TYPE (result) != type)
6401 : {
6402 9706 : if (TREE_CODE (result) == INTEGER_CST)
6403 : {
6404 0 : if (arith_overflowed_p (PLUS_EXPR, type, result,
6405 : integer_zero_node))
6406 0 : overflow = build_one_cst (type);
6407 : }
6408 9706 : else if ((!TYPE_UNSIGNED (TREE_TYPE (result))
6409 6988 : && TYPE_UNSIGNED (type))
6410 9888 : || (TYPE_PRECISION (type)
6411 2900 : < (TYPE_PRECISION (TREE_TYPE (result))
6412 2900 : + (TYPE_UNSIGNED (TREE_TYPE (result))
6413 3293 : && !TYPE_UNSIGNED (type)))))
6414 : result = NULL_TREE;
6415 62 : if (result)
6416 62 : result = fold_convert (type, result);
6417 : }
6418 : }
6419 : }
6420 :
6421 1454911 : if (result)
6422 : {
6423 28833 : if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
6424 0 : result = drop_tree_overflow (result);
6425 28833 : if (cplx_result)
6426 : {
6427 6323 : if (overflow == NULL_TREE)
6428 6323 : overflow = build_zero_cst (TREE_TYPE (result));
6429 6323 : tree ctype = build_complex_type (TREE_TYPE (result));
6430 6323 : if (TREE_CODE (result) == INTEGER_CST
6431 2146 : && TREE_CODE (overflow) == INTEGER_CST)
6432 2146 : result = build_complex (ctype, result, overflow);
6433 : else
6434 4177 : result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
6435 : ctype, result, overflow);
6436 : }
6437 28833 : gimplify_and_update_call_from_tree (gsi, result);
6438 28833 : changed = true;
6439 : }
6440 : }
6441 :
6442 : return changed;
6443 : }
6444 :
6445 :
6446 : /* Return true whether NAME has a use on STMT. Note this can return
6447 : false even though there's a use on STMT if SSA operands are not
6448 : up-to-date. */
6449 :
6450 : static bool
6451 1674 : has_use_on_stmt (tree name, gimple *stmt)
6452 : {
6453 1674 : ssa_op_iter iter;
6454 1674 : tree op;
6455 3373 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
6456 1745 : if (op == name)
6457 : return true;
6458 : return false;
6459 : }
6460 :
6461 : /* Add the lhs of each statement of SEQ to DCE_WORKLIST. */
6462 :
6463 : void
6464 4789010 : mark_lhs_in_seq_for_dce (bitmap dce_worklist, gimple_seq seq)
6465 : {
6466 4789010 : if (!dce_worklist)
6467 : return;
6468 :
6469 1651678 : for (gimple_stmt_iterator i = gsi_start (seq);
6470 1930552 : !gsi_end_p (i); gsi_next (&i))
6471 : {
6472 278874 : gimple *stmt = gsi_stmt (i);
6473 278874 : tree name = gimple_get_lhs (stmt);
6474 278874 : if (name && TREE_CODE (name) == SSA_NAME)
6475 278874 : bitmap_set_bit (dce_worklist, SSA_NAME_VERSION (name));
6476 : }
6477 : }
6478 :
6479 : /* Worker for fold_stmt_1 dispatch to pattern based folding with
6480 : gimple_simplify.
6481 :
6482 : Replaces *GSI with the simplification result in RCODE and OPS
6483 : and the associated statements in *SEQ. Does the replacement
6484 : according to INPLACE and returns true if the operation succeeded. */
6485 :
6486 : static bool
6487 9258392 : replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
6488 : gimple_match_op *res_op,
6489 : gimple_seq *seq, bool inplace,
6490 : bitmap dce_worklist)
6491 : {
6492 9258392 : gimple *stmt = gsi_stmt (*gsi);
6493 9258392 : tree *ops = res_op->ops;
6494 9258392 : unsigned int num_ops = res_op->num_ops;
6495 :
6496 : /* Play safe and do not allow abnormals to be mentioned in
6497 : newly created statements. See also maybe_push_res_to_seq.
6498 : As an exception allow such uses if there was a use of the
6499 : same SSA name on the old stmt. */
6500 20525171 : for (unsigned int i = 0; i < num_ops; ++i)
6501 11268407 : if (TREE_CODE (ops[i]) == SSA_NAME
6502 6851088 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i])
6503 11270081 : && !has_use_on_stmt (ops[i], stmt))
6504 : return false;
6505 :
6506 9256764 : if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
6507 0 : for (unsigned int i = 0; i < 2; ++i)
6508 0 : if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
6509 0 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i))
6510 0 : && !has_use_on_stmt (TREE_OPERAND (ops[0], i), stmt))
6511 : return false;
6512 :
6513 : /* Don't insert new statements when INPLACE is true, even if we could
6514 : reuse STMT for the final statement. */
6515 9256764 : if (inplace && !gimple_seq_empty_p (*seq))
6516 : return false;
6517 :
6518 9256764 : if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
6519 : {
6520 6964730 : gcc_assert (res_op->code.is_tree_code ());
6521 6964730 : auto code = tree_code (res_op->code);
6522 6964730 : if (TREE_CODE_CLASS (code) == tcc_comparison
6523 : /* GIMPLE_CONDs condition may not throw. */
6524 6964730 : && ((cfun
6525 1155990 : && (!flag_exceptions
6526 783195 : || !cfun->can_throw_non_call_exceptions))
6527 292021 : || !operation_could_trap_p (code,
6528 292021 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6529 : false, NULL_TREE)))
6530 1144713 : gimple_cond_set_condition (cond_stmt, code, ops[0], ops[1]);
6531 5820017 : else if (code == SSA_NAME)
6532 : {
6533 : /* If setting the gimple cond to the same thing,
6534 : return false as nothing changed. */
6535 4036316 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6536 4011907 : && operand_equal_p (gimple_cond_lhs (cond_stmt), ops[0])
6537 8045676 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6538 : return false;
6539 26956 : gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
6540 26956 : build_zero_cst (TREE_TYPE (ops[0])));
6541 : }
6542 1783701 : else if (code == INTEGER_CST)
6543 : {
6544 : /* Make into the canonical form `1 != 0` and `0 != 0`.
6545 : If already in the canonical form return false
6546 : saying nothing has been done. */
6547 1242344 : if (integer_zerop (ops[0]))
6548 : {
6549 5417098 : if (gimple_cond_false_canonical_p (cond_stmt))
6550 : return false;
6551 503112 : gimple_cond_make_false (cond_stmt);
6552 : }
6553 : else
6554 : {
6555 381500 : if (gimple_cond_true_canonical_p (cond_stmt))
6556 : return false;
6557 206226 : gimple_cond_make_true (cond_stmt);
6558 : }
6559 : }
6560 541357 : else if (!inplace)
6561 : {
6562 : /* For throwing comparisons, see if the GIMPLE_COND is the same as
6563 : the comparison would be.
6564 : This can happen due to the match pattern for
6565 : `(ne (cmp @0 @1) integer_zerop)` which creates a new expression
6566 : for the comparison. */
6567 541357 : if (TREE_CODE_CLASS (code) == tcc_comparison
6568 11277 : && (!cfun
6569 11277 : || (flag_exceptions
6570 11277 : && cfun->can_throw_non_call_exceptions))
6571 552634 : && operation_could_trap_p (code,
6572 11277 : FLOAT_TYPE_P (TREE_TYPE (ops[0])),
6573 : false, NULL_TREE))
6574 : {
6575 11277 : tree lhs = gimple_cond_lhs (cond_stmt);
6576 11277 : if (gimple_cond_code (cond_stmt) == NE_EXPR
6577 11277 : && TREE_CODE (lhs) == SSA_NAME
6578 11277 : && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6579 22554 : && integer_zerop (gimple_cond_rhs (cond_stmt)))
6580 : {
6581 11277 : gimple *s = SSA_NAME_DEF_STMT (lhs);
6582 11277 : if (is_gimple_assign (s)
6583 11277 : && gimple_assign_rhs_code (s) == code
6584 11277 : && operand_equal_p (gimple_assign_rhs1 (s), ops[0])
6585 22554 : && operand_equal_p (gimple_assign_rhs2 (s), ops[1]))
6586 : return false;
6587 : }
6588 : }
6589 530080 : tree res = maybe_push_res_to_seq (res_op, seq);
6590 530080 : if (!res)
6591 : return false;
6592 530080 : gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
6593 530080 : build_zero_cst (TREE_TYPE (res)));
6594 : }
6595 : else
6596 : return false;
6597 2411087 : if (dump_file && (dump_flags & TDF_DETAILS))
6598 : {
6599 857 : fprintf (dump_file, "gimple_simplified to ");
6600 857 : if (!gimple_seq_empty_p (*seq))
6601 0 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6602 857 : print_gimple_stmt (dump_file, gsi_stmt (*gsi),
6603 : 0, TDF_SLIM);
6604 : }
6605 : // Mark the lhs of the new statements maybe for dce
6606 2411087 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6607 2411087 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6608 2411087 : return true;
6609 : }
6610 2292034 : else if (is_gimple_assign (stmt)
6611 2292034 : && res_op->code.is_tree_code ())
6612 : {
6613 2214748 : auto code = tree_code (res_op->code);
6614 2214748 : if (!inplace
6615 2214748 : || gimple_num_ops (stmt) > get_gimple_rhs_num_ops (code))
6616 : {
6617 2214748 : maybe_build_generic_op (res_op);
6618 5224841 : gimple_assign_set_rhs_with_ops (gsi, code,
6619 : res_op->op_or_null (0),
6620 : res_op->op_or_null (1),
6621 : res_op->op_or_null (2));
6622 2214748 : if (dump_file && (dump_flags & TDF_DETAILS))
6623 : {
6624 16854 : fprintf (dump_file, "gimple_simplified to ");
6625 16854 : if (!gimple_seq_empty_p (*seq))
6626 327 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6627 16854 : print_gimple_stmt (dump_file, gsi_stmt (*gsi),
6628 : 0, TDF_SLIM);
6629 : }
6630 : // Mark the lhs of the new statements maybe for dce
6631 2214748 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6632 2214748 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6633 2214748 : return true;
6634 : }
6635 : }
6636 77286 : else if (res_op->code.is_fn_code ()
6637 77286 : && gimple_call_combined_fn (stmt) == combined_fn (res_op->code))
6638 : {
6639 8089 : gcc_assert (num_ops == gimple_call_num_args (stmt));
6640 23938 : for (unsigned int i = 0; i < num_ops; ++i)
6641 15849 : gimple_call_set_arg (stmt, i, ops[i]);
6642 8089 : if (dump_file && (dump_flags & TDF_DETAILS))
6643 : {
6644 0 : fprintf (dump_file, "gimple_simplified to ");
6645 0 : if (!gimple_seq_empty_p (*seq))
6646 0 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6647 0 : print_gimple_stmt (dump_file, gsi_stmt (*gsi), 0, TDF_SLIM);
6648 : }
6649 : // Mark the lhs of the new statements maybe for dce
6650 8089 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6651 8089 : gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
6652 8089 : return true;
6653 : }
6654 69197 : else if (!inplace)
6655 : {
6656 136391 : if (gimple_has_lhs (stmt))
6657 : {
6658 69197 : tree lhs = gimple_get_lhs (stmt);
6659 69197 : if (!maybe_push_res_to_seq (res_op, seq, lhs))
6660 : return false;
6661 68214 : if (dump_file && (dump_flags & TDF_DETAILS))
6662 : {
6663 10 : fprintf (dump_file, "gimple_simplified to ");
6664 10 : print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
6665 : }
6666 : // Mark the lhs of the new statements maybe for dce
6667 68214 : mark_lhs_in_seq_for_dce (dce_worklist, *seq);
6668 68214 : gsi_replace_with_seq_vops (gsi, *seq);
6669 68214 : return true;
6670 : }
6671 : else
6672 0 : gcc_unreachable ();
6673 : }
6674 :
6675 : return false;
6676 : }
6677 :
6678 : /* Canonicalize MEM_REFs invariant address operand after propagation. */
6679 :
6680 : static bool
6681 196132263 : maybe_canonicalize_mem_ref_addr (tree *t, bool is_debug = false)
6682 : {
6683 196132263 : bool res = false;
6684 196132263 : tree *orig_t = t;
6685 :
6686 196132263 : if (TREE_CODE (*t) == ADDR_EXPR)
6687 66412841 : t = &TREE_OPERAND (*t, 0);
6688 :
6689 : /* The C and C++ frontends use an ARRAY_REF for indexing with their
6690 : generic vector extension. The actual vector referenced is
6691 : view-converted to an array type for this purpose. If the index
6692 : is constant the canonical representation in the middle-end is a
6693 : BIT_FIELD_REF so re-write the former to the latter here. */
6694 196132263 : if (TREE_CODE (*t) == ARRAY_REF
6695 11010102 : && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
6696 174870 : && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
6697 196186189 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
6698 : {
6699 24365 : tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
6700 24365 : if (VECTOR_TYPE_P (vtype))
6701 : {
6702 24365 : tree low = array_ref_low_bound (*t);
6703 24365 : if (TREE_CODE (low) == INTEGER_CST)
6704 : {
6705 24365 : if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
6706 : {
6707 48676 : widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
6708 48676 : wi::to_widest (low));
6709 24338 : idx = wi::mul (idx, wi::to_widest
6710 48676 : (TYPE_SIZE (TREE_TYPE (*t))));
6711 24338 : widest_int ext
6712 24338 : = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
6713 24338 : if (maybe_le (ext, wi::to_poly_widest (TYPE_SIZE (vtype))))
6714 : {
6715 47524 : *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
6716 23762 : TREE_TYPE (*t),
6717 23762 : TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
6718 23762 : TYPE_SIZE (TREE_TYPE (*t)),
6719 23762 : wide_int_to_tree (bitsizetype, idx));
6720 23762 : res = true;
6721 : }
6722 24338 : }
6723 : }
6724 : }
6725 : }
6726 :
6727 369620222 : while (handled_component_p (*t))
6728 173487959 : t = &TREE_OPERAND (*t, 0);
6729 :
6730 : /* Canonicalize MEM [&foo.bar, 0] which appears after propagating
6731 : of invariant addresses into a SSA name MEM_REF address. */
6732 196132263 : if (TREE_CODE (*t) == MEM_REF
6733 196132263 : || TREE_CODE (*t) == TARGET_MEM_REF)
6734 : {
6735 103235655 : tree addr = TREE_OPERAND (*t, 0);
6736 103235655 : if (TREE_CODE (addr) == ADDR_EXPR
6737 103235655 : && (TREE_CODE (TREE_OPERAND (addr, 0)) == MEM_REF
6738 31428358 : || handled_component_p (TREE_OPERAND (addr, 0))))
6739 : {
6740 548181 : tree base;
6741 548181 : poly_int64 coffset;
6742 548181 : base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
6743 : &coffset);
6744 548181 : if (!base)
6745 : {
6746 18 : if (is_debug)
6747 18 : return false;
6748 0 : gcc_unreachable ();
6749 : }
6750 :
6751 548163 : TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
6752 548163 : TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
6753 548163 : TREE_OPERAND (*t, 1),
6754 548163 : size_int (coffset));
6755 548163 : res = true;
6756 : }
6757 103235637 : gcc_checking_assert (TREE_CODE (TREE_OPERAND (*t, 0)) == DEBUG_EXPR_DECL
6758 : || is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)));
6759 : }
6760 :
6761 : /* Canonicalize back MEM_REFs to plain reference trees if the object
6762 : accessed is a decl that has the same access semantics as the MEM_REF. */
6763 196132245 : if (TREE_CODE (*t) == MEM_REF
6764 101280026 : && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
6765 31118223 : && integer_zerop (TREE_OPERAND (*t, 1))
6766 213117315 : && MR_DEPENDENCE_CLIQUE (*t) == 0)
6767 : {
6768 12007723 : tree decl = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6769 12007723 : tree alias_type = TREE_TYPE (TREE_OPERAND (*t, 1));
6770 12007723 : if (/* Same volatile qualification. */
6771 12007723 : TREE_THIS_VOLATILE (*t) == TREE_THIS_VOLATILE (decl)
6772 : /* Same TBAA behavior with -fstrict-aliasing. */
6773 12004703 : && !TYPE_REF_CAN_ALIAS_ALL (alias_type)
6774 11655292 : && (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
6775 11655292 : == TYPE_MAIN_VARIANT (TREE_TYPE (alias_type)))
6776 : /* Same alignment. */
6777 4792346 : && TYPE_ALIGN (TREE_TYPE (decl)) == TYPE_ALIGN (TREE_TYPE (*t))
6778 : /* We have to look out here to not drop a required conversion
6779 : from the rhs to the lhs if *t appears on the lhs or vice-versa
6780 : if it appears on the rhs. Thus require strict type
6781 : compatibility. */
6782 16513729 : && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (decl)))
6783 : {
6784 2474061 : *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
6785 2474061 : res = true;
6786 : }
6787 : }
6788 :
6789 184124522 : else if (TREE_CODE (*orig_t) == ADDR_EXPR
6790 63655449 : && TREE_CODE (*t) == MEM_REF
6791 206095603 : && TREE_CODE (TREE_OPERAND (*t, 0)) == INTEGER_CST)
6792 : {
6793 854 : tree base;
6794 854 : poly_int64 coffset;
6795 854 : base = get_addr_base_and_unit_offset (TREE_OPERAND (*orig_t, 0),
6796 : &coffset);
6797 854 : if (base)
6798 : {
6799 760 : gcc_assert (TREE_CODE (base) == MEM_REF);
6800 760 : poly_int64 moffset;
6801 760 : if (mem_ref_offset (base).to_shwi (&moffset))
6802 : {
6803 760 : coffset += moffset;
6804 760 : if (wi::to_poly_wide (TREE_OPERAND (base, 0)).to_shwi (&moffset))
6805 : {
6806 760 : coffset += moffset;
6807 760 : *orig_t = build_int_cst (TREE_TYPE (*orig_t), coffset);
6808 760 : return true;
6809 : }
6810 : }
6811 : }
6812 : }
6813 :
6814 : /* Canonicalize TARGET_MEM_REF in particular with respect to
6815 : the indexes becoming constant. */
6816 184123668 : else if (TREE_CODE (*t) == TARGET_MEM_REF)
6817 : {
6818 1955611 : tree tem = maybe_fold_tmr (*t);
6819 1955611 : if (tem)
6820 : {
6821 1614 : *t = tem;
6822 1614 : if (TREE_CODE (*orig_t) == ADDR_EXPR)
6823 0 : recompute_tree_invariant_for_addr_expr (*orig_t);
6824 : res = true;
6825 : }
6826 : }
6827 :
6828 : return res;
6829 : }
6830 :
6831 : /* Worker for both fold_stmt and fold_stmt_inplace. The INPLACE argument
6832 : distinguishes both cases. */
6833 :
6834 : static bool
6835 787693016 : fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree),
6836 : bitmap dce_worklist = nullptr)
6837 : {
6838 787693016 : bool changed = false;
6839 787693016 : gimple *stmt = gsi_stmt (*gsi);
6840 787693016 : unsigned i;
6841 :
6842 : /* First do required canonicalization of [TARGET_]MEM_REF addresses
6843 : after propagation.
6844 : ??? This shouldn't be done in generic folding but in the
6845 : propagation helpers which also know whether an address was
6846 : propagated.
6847 : Also canonicalize operand order. */
6848 787693016 : switch (gimple_code (stmt))
6849 : {
6850 259944861 : case GIMPLE_ASSIGN:
6851 259944861 : if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
6852 : {
6853 171456229 : tree *rhs = gimple_assign_rhs1_ptr (stmt);
6854 171456229 : if ((REFERENCE_CLASS_P (*rhs)
6855 108424868 : || TREE_CODE (*rhs) == ADDR_EXPR)
6856 186615848 : && maybe_canonicalize_mem_ref_addr (rhs))
6857 : changed = true;
6858 171456229 : tree *lhs = gimple_assign_lhs_ptr (stmt);
6859 171456229 : if (REFERENCE_CLASS_P (*lhs)
6860 171456229 : && maybe_canonicalize_mem_ref_addr (lhs))
6861 : changed = true;
6862 : /* Canonicalize &MEM[ssa_n, CST] to ssa_n p+ CST.
6863 : This cannot be done in maybe_canonicalize_mem_ref_addr
6864 : as the gimple now has two operands rather than one.
6865 : The same reason why this can't be done in
6866 : maybe_canonicalize_mem_ref_addr is the same reason why
6867 : this can't be done inplace. */
6868 171456229 : if (!inplace && TREE_CODE (*rhs) == ADDR_EXPR)
6869 : {
6870 14959934 : tree inner = TREE_OPERAND (*rhs, 0);
6871 14959934 : if (TREE_CODE (inner) == MEM_REF
6872 1044726 : && TREE_CODE (TREE_OPERAND (inner, 0)) == SSA_NAME
6873 15024262 : && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6874 : {
6875 64328 : tree ptr = TREE_OPERAND (inner, 0);
6876 64328 : tree addon = TREE_OPERAND (inner, 1);
6877 64328 : addon = fold_convert (sizetype, addon);
6878 64328 : gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR,
6879 : ptr, addon);
6880 64328 : changed = true;
6881 64328 : stmt = gsi_stmt (*gsi);
6882 : }
6883 : }
6884 : }
6885 : else
6886 : {
6887 : /* Canonicalize operand order. */
6888 88488632 : enum tree_code code = gimple_assign_rhs_code (stmt);
6889 88488632 : if (TREE_CODE_CLASS (code) == tcc_comparison
6890 82169486 : || commutative_tree_code (code)
6891 132991440 : || commutative_ternary_tree_code (code))
6892 : {
6893 43986808 : tree rhs1 = gimple_assign_rhs1 (stmt);
6894 43986808 : tree rhs2 = gimple_assign_rhs2 (stmt);
6895 43986808 : if (tree_swap_operands_p (rhs1, rhs2))
6896 : {
6897 2631918 : gimple_assign_set_rhs1 (stmt, rhs2);
6898 2631918 : gimple_assign_set_rhs2 (stmt, rhs1);
6899 2631918 : if (TREE_CODE_CLASS (code) == tcc_comparison)
6900 319072 : gimple_assign_set_rhs_code (stmt,
6901 : swap_tree_comparison (code));
6902 : changed = true;
6903 : }
6904 : }
6905 : }
6906 : break;
6907 57231738 : case GIMPLE_CALL:
6908 57231738 : {
6909 57231738 : gcall *call = as_a<gcall *> (stmt);
6910 171944196 : for (i = 0; i < gimple_call_num_args (call); ++i)
6911 : {
6912 114712458 : tree *arg = gimple_call_arg_ptr (call, i);
6913 114712458 : if (REFERENCE_CLASS_P (*arg)
6914 114712458 : && maybe_canonicalize_mem_ref_addr (arg))
6915 : changed = true;
6916 : }
6917 57231738 : tree *lhs = gimple_call_lhs_ptr (call);
6918 57231738 : if (*lhs
6919 23208379 : && REFERENCE_CLASS_P (*lhs)
6920 57352369 : && maybe_canonicalize_mem_ref_addr (lhs))
6921 : changed = true;
6922 57231738 : if (*lhs)
6923 : {
6924 23208379 : combined_fn cfn = gimple_call_combined_fn (call);
6925 23208379 : internal_fn ifn = associated_internal_fn (cfn, TREE_TYPE (*lhs));
6926 23208379 : int opno = first_commutative_argument (ifn);
6927 23208379 : if (opno >= 0)
6928 : {
6929 355758 : tree arg1 = gimple_call_arg (call, opno);
6930 355758 : tree arg2 = gimple_call_arg (call, opno + 1);
6931 355758 : if (tree_swap_operands_p (arg1, arg2))
6932 : {
6933 22473 : gimple_call_set_arg (call, opno, arg2);
6934 22473 : gimple_call_set_arg (call, opno + 1, arg1);
6935 22473 : changed = true;
6936 : }
6937 : }
6938 : }
6939 : break;
6940 : }
6941 601337 : case GIMPLE_ASM:
6942 601337 : {
6943 601337 : gasm *asm_stmt = as_a <gasm *> (stmt);
6944 1277802 : for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
6945 : {
6946 676465 : tree link = gimple_asm_output_op (asm_stmt, i);
6947 676465 : tree op = TREE_VALUE (link);
6948 676465 : if (REFERENCE_CLASS_P (op)
6949 676465 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
6950 : changed = true;
6951 : }
6952 1031291 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
6953 : {
6954 429954 : tree link = gimple_asm_input_op (asm_stmt, i);
6955 429954 : tree op = TREE_VALUE (link);
6956 429954 : if ((REFERENCE_CLASS_P (op)
6957 401711 : || TREE_CODE (op) == ADDR_EXPR)
6958 465472 : && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
6959 : changed = true;
6960 : }
6961 : }
6962 : break;
6963 403849685 : case GIMPLE_DEBUG:
6964 403849685 : if (gimple_debug_bind_p (stmt))
6965 : {
6966 311313857 : tree *val = gimple_debug_bind_get_value_ptr (stmt);
6967 311313857 : if (*val
6968 177280150 : && (REFERENCE_CLASS_P (*val)
6969 174586403 : || TREE_CODE (*val) == ADDR_EXPR)
6970 365225308 : && maybe_canonicalize_mem_ref_addr (val, true))
6971 : changed = true;
6972 : }
6973 : break;
6974 45500278 : case GIMPLE_COND:
6975 45500278 : {
6976 : /* Canonicalize operand order. */
6977 45500278 : tree lhs = gimple_cond_lhs (stmt);
6978 45500278 : tree rhs = gimple_cond_rhs (stmt);
6979 45500278 : if (tree_swap_operands_p (lhs, rhs))
6980 : {
6981 1424788 : gcond *gc = as_a <gcond *> (stmt);
6982 1424788 : gimple_cond_set_lhs (gc, rhs);
6983 1424788 : gimple_cond_set_rhs (gc, lhs);
6984 1424788 : gimple_cond_set_code (gc,
6985 : swap_tree_comparison (gimple_cond_code (gc)));
6986 1424788 : changed = true;
6987 : }
6988 : }
6989 786162994 : default:;
6990 : }
6991 :
6992 : /* Dispatch to pattern-based folding. */
6993 786162994 : if (!inplace
6994 3218083 : || is_gimple_assign (stmt)
6995 787075383 : || gimple_code (stmt) == GIMPLE_COND)
6996 : {
6997 786780627 : gimple_seq seq = NULL;
6998 786780627 : gimple_match_op res_op;
6999 1571255560 : if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
7000 : valueize, valueize)
7001 786780627 : && replace_stmt_with_simplification (gsi, &res_op, &seq, inplace,
7002 : dce_worklist))
7003 : changed = true;
7004 : else
7005 782078489 : gimple_seq_discard (seq);
7006 : }
7007 :
7008 787693016 : stmt = gsi_stmt (*gsi);
7009 :
7010 : /* Fold the main computation performed by the statement. */
7011 787693016 : switch (gimple_code (stmt))
7012 : {
7013 260000164 : case GIMPLE_ASSIGN:
7014 260000164 : {
7015 : /* Try to canonicalize for boolean-typed X the comparisons
7016 : X == 0, X == 1, X != 0, and X != 1. */
7017 260000164 : if (gimple_assign_rhs_code (stmt) == EQ_EXPR
7018 260000164 : || gimple_assign_rhs_code (stmt) == NE_EXPR)
7019 : {
7020 3507103 : tree lhs = gimple_assign_lhs (stmt);
7021 3507103 : tree op1 = gimple_assign_rhs1 (stmt);
7022 3507103 : tree op2 = gimple_assign_rhs2 (stmt);
7023 3507103 : tree type = TREE_TYPE (op1);
7024 :
7025 : /* Check whether the comparison operands are of the same boolean
7026 : type as the result type is.
7027 : Check that second operand is an integer-constant with value
7028 : one or zero. */
7029 3507103 : if (TREE_CODE (op2) == INTEGER_CST
7030 2407562 : && (integer_zerop (op2) || integer_onep (op2))
7031 5294768 : && useless_type_conversion_p (TREE_TYPE (lhs), type))
7032 : {
7033 4762 : enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
7034 4762 : bool is_logical_not = false;
7035 :
7036 : /* X == 0 and X != 1 is a logical-not.of X
7037 : X == 1 and X != 0 is X */
7038 3959 : if ((cmp_code == EQ_EXPR && integer_zerop (op2))
7039 4762 : || (cmp_code == NE_EXPR && integer_onep (op2)))
7040 4705 : is_logical_not = true;
7041 :
7042 4762 : if (is_logical_not == false)
7043 57 : gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1);
7044 : /* Only for one-bit precision typed X the transformation
7045 : !X -> ~X is valid. */
7046 4705 : else if (TYPE_PRECISION (type) == 1)
7047 4705 : gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1);
7048 : /* Otherwise we use !X -> X ^ 1. */
7049 : else
7050 0 : gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1,
7051 : build_int_cst (type, 1));
7052 : changed = true;
7053 : break;
7054 : }
7055 : }
7056 :
7057 259995402 : unsigned old_num_ops = gimple_num_ops (stmt);
7058 259995402 : tree lhs = gimple_assign_lhs (stmt);
7059 259995402 : tree new_rhs = fold_gimple_assign (gsi);
7060 259995402 : if (new_rhs
7061 260113221 : && !useless_type_conversion_p (TREE_TYPE (lhs),
7062 117819 : TREE_TYPE (new_rhs)))
7063 0 : new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
7064 259995402 : if (new_rhs
7065 259995402 : && (!inplace
7066 1036 : || get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
7067 : {
7068 117819 : gimple_assign_set_rhs_from_tree (gsi, new_rhs);
7069 117819 : changed = true;
7070 : }
7071 : break;
7072 : }
7073 :
7074 57176435 : case GIMPLE_CALL:
7075 57176435 : changed |= gimple_fold_call (gsi, inplace);
7076 57176435 : break;
7077 :
7078 403849685 : case GIMPLE_DEBUG:
7079 403849685 : if (gimple_debug_bind_p (stmt))
7080 : {
7081 311313857 : tree val = gimple_debug_bind_get_value (stmt);
7082 311313857 : if (val && REFERENCE_CLASS_P (val))
7083 : {
7084 2691780 : tree tem = maybe_fold_reference (val);
7085 2691780 : if (tem)
7086 : {
7087 4387 : gimple_debug_bind_set_value (stmt, tem);
7088 4387 : changed = true;
7089 : }
7090 : }
7091 : }
7092 : break;
7093 :
7094 10881741 : case GIMPLE_RETURN:
7095 10881741 : {
7096 10881741 : greturn *ret_stmt = as_a<greturn *> (stmt);
7097 10881741 : tree ret = gimple_return_retval(ret_stmt);
7098 :
7099 10881741 : if (ret && TREE_CODE (ret) == SSA_NAME && valueize)
7100 : {
7101 4568292 : tree val = valueize (ret);
7102 4568292 : if (val && val != ret
7103 4568292 : && may_propagate_copy (ret, val))
7104 : {
7105 0 : gimple_return_set_retval (ret_stmt, val);
7106 0 : changed = true;
7107 : }
7108 : }
7109 : }
7110 : break;
7111 :
7112 787693016 : default:;
7113 : }
7114 :
7115 787693016 : return changed;
7116 : }
7117 :
7118 : /* Valueziation callback that ends up not following SSA edges. */
7119 :
7120 : tree
7121 5892839843 : no_follow_ssa_edges (tree)
7122 : {
7123 5892839843 : return NULL_TREE;
7124 : }
7125 :
7126 : /* Valueization callback that ends up following single-use SSA edges only. */
7127 :
7128 : tree
7129 921584983 : follow_single_use_edges (tree val)
7130 : {
7131 921584983 : if (TREE_CODE (val) == SSA_NAME
7132 921584983 : && !has_single_use (val))
7133 472248593 : return NULL_TREE;
7134 : return val;
7135 : }
7136 :
7137 : /* Valueization callback that follows all SSA edges. */
7138 :
7139 : tree
7140 213681064 : follow_all_ssa_edges (tree val)
7141 : {
7142 213681064 : return val;
7143 : }
7144 :
7145 : /* Fold the statement pointed to by GSI. In some cases, this function may
7146 : replace the whole statement with a new one. Returns true iff folding
7147 : makes any changes.
7148 : The statement pointed to by GSI should be in valid gimple form but may
7149 : be in unfolded state as resulting from for example constant propagation
7150 : which can produce *&x = 0. */
7151 :
7152 : bool
7153 158057841 : fold_stmt (gimple_stmt_iterator *gsi, bitmap dce_bitmap)
7154 : {
7155 158057841 : return fold_stmt_1 (gsi, false, no_follow_ssa_edges, dce_bitmap);
7156 : }
7157 :
7158 : bool
7159 626417092 : fold_stmt (gimple_stmt_iterator *gsi, tree (*valueize) (tree), bitmap dce_bitmap)
7160 : {
7161 626417092 : return fold_stmt_1 (gsi, false, valueize, dce_bitmap);
7162 : }
7163 :
7164 : /* Perform the minimal folding on statement *GSI. Only operations like
7165 : *&x created by constant propagation are handled. The statement cannot
7166 : be replaced with a new one. Return true if the statement was
7167 : changed, false otherwise.
7168 : The statement *GSI should be in valid gimple form but may
7169 : be in unfolded state as resulting from for example constant propagation
7170 : which can produce *&x = 0. */
7171 :
7172 : bool
7173 3218083 : fold_stmt_inplace (gimple_stmt_iterator *gsi, tree (*valueize) (tree))
7174 : {
7175 3218083 : gimple *stmt = gsi_stmt (*gsi);
7176 3218083 : bool changed = fold_stmt_1 (gsi, true, valueize);
7177 3218083 : gcc_assert (gsi_stmt (*gsi) == stmt);
7178 3218083 : return changed;
7179 : }
7180 :
7181 : /* Canonicalize and possibly invert the boolean EXPR; return NULL_TREE
7182 : if EXPR is null or we don't know how.
7183 : If non-null, the result always has boolean type. */
7184 :
7185 : static tree
7186 428342 : canonicalize_bool (tree expr, bool invert)
7187 : {
7188 428342 : if (!expr)
7189 : return NULL_TREE;
7190 60 : else if (invert)
7191 : {
7192 41 : if (integer_nonzerop (expr))
7193 0 : return boolean_false_node;
7194 41 : else if (integer_zerop (expr))
7195 0 : return boolean_true_node;
7196 41 : else if (TREE_CODE (expr) == SSA_NAME)
7197 0 : return fold_build2 (EQ_EXPR, boolean_type_node, expr,
7198 : build_int_cst (TREE_TYPE (expr), 0));
7199 41 : else if (COMPARISON_CLASS_P (expr))
7200 41 : return fold_build2 (invert_tree_comparison (TREE_CODE (expr), false),
7201 : boolean_type_node,
7202 : TREE_OPERAND (expr, 0),
7203 : TREE_OPERAND (expr, 1));
7204 : else
7205 : return NULL_TREE;
7206 : }
7207 : else
7208 : {
7209 19 : if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
7210 : return expr;
7211 0 : if (integer_nonzerop (expr))
7212 0 : return boolean_true_node;
7213 0 : else if (integer_zerop (expr))
7214 0 : return boolean_false_node;
7215 0 : else if (TREE_CODE (expr) == SSA_NAME)
7216 0 : return fold_build2 (NE_EXPR, boolean_type_node, expr,
7217 : build_int_cst (TREE_TYPE (expr), 0));
7218 0 : else if (COMPARISON_CLASS_P (expr))
7219 0 : return fold_build2 (TREE_CODE (expr),
7220 : boolean_type_node,
7221 : TREE_OPERAND (expr, 0),
7222 : TREE_OPERAND (expr, 1));
7223 : else
7224 : return NULL_TREE;
7225 : }
7226 : }
7227 :
7228 : /* Check to see if a boolean expression EXPR is logically equivalent to the
7229 : comparison (OP1 CODE OP2). Check for various identities involving
7230 : SSA_NAMEs. */
7231 :
7232 : static bool
7233 1348 : same_bool_comparison_p (const_tree expr, enum tree_code code,
7234 : const_tree op1, const_tree op2)
7235 : {
7236 1348 : gimple *s;
7237 :
7238 : /* The obvious case. */
7239 1348 : if (TREE_CODE (expr) == code
7240 33 : && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
7241 1381 : && operand_equal_p (TREE_OPERAND (expr, 1), op2, 0))
7242 : return true;
7243 :
7244 : /* Check for comparing (name, name != 0) and the case where expr
7245 : is an SSA_NAME with a definition matching the comparison. */
7246 1331 : if (TREE_CODE (expr) == SSA_NAME
7247 1331 : && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
7248 : {
7249 0 : if (operand_equal_p (expr, op1, 0))
7250 0 : return ((code == NE_EXPR && integer_zerop (op2))
7251 0 : || (code == EQ_EXPR && integer_nonzerop (op2)));
7252 0 : s = SSA_NAME_DEF_STMT (expr);
7253 0 : if (is_gimple_assign (s)
7254 0 : && gimple_assign_rhs_code (s) == code
7255 0 : && operand_equal_p (gimple_assign_rhs1 (s), op1, 0)
7256 0 : && operand_equal_p (gimple_assign_rhs2 (s), op2, 0))
7257 : return true;
7258 : }
7259 :
7260 : /* If op1 is of the form (name != 0) or (name == 0), and the definition
7261 : of name is a comparison, recurse. */
7262 1331 : if (TREE_CODE (op1) == SSA_NAME
7263 1331 : && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
7264 : {
7265 460 : s = SSA_NAME_DEF_STMT (op1);
7266 460 : if (is_gimple_assign (s)
7267 460 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
7268 : {
7269 0 : enum tree_code c = gimple_assign_rhs_code (s);
7270 0 : if ((c == NE_EXPR && integer_zerop (op2))
7271 0 : || (c == EQ_EXPR && integer_nonzerop (op2)))
7272 0 : return same_bool_comparison_p (expr, c,
7273 0 : gimple_assign_rhs1 (s),
7274 0 : gimple_assign_rhs2 (s));
7275 0 : if ((c == EQ_EXPR && integer_zerop (op2))
7276 0 : || (c == NE_EXPR && integer_nonzerop (op2)))
7277 0 : return same_bool_comparison_p (expr,
7278 : invert_tree_comparison (c, false),
7279 0 : gimple_assign_rhs1 (s),
7280 0 : gimple_assign_rhs2 (s));
7281 : }
7282 : }
7283 : return false;
7284 : }
7285 :
7286 : /* Check to see if two boolean expressions OP1 and OP2 are logically
7287 : equivalent. */
7288 :
7289 : static bool
7290 15 : same_bool_result_p (const_tree op1, const_tree op2)
7291 : {
7292 : /* Simple cases first. */
7293 15 : if (operand_equal_p (op1, op2, 0))
7294 : return true;
7295 :
7296 : /* Check the cases where at least one of the operands is a comparison.
7297 : These are a bit smarter than operand_equal_p in that they apply some
7298 : identifies on SSA_NAMEs. */
7299 8 : if (COMPARISON_CLASS_P (op2)
7300 16 : && same_bool_comparison_p (op1, TREE_CODE (op2),
7301 8 : TREE_OPERAND (op2, 0),
7302 8 : TREE_OPERAND (op2, 1)))
7303 : return true;
7304 8 : if (COMPARISON_CLASS_P (op1)
7305 16 : && same_bool_comparison_p (op2, TREE_CODE (op1),
7306 8 : TREE_OPERAND (op1, 0),
7307 8 : TREE_OPERAND (op1, 1)))
7308 : return true;
7309 :
7310 : /* Default case. */
7311 : return false;
7312 : }
7313 :
7314 : /* Forward declarations for some mutually recursive functions. */
7315 :
7316 : static tree
7317 : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
7318 : enum tree_code code2, tree op2a, tree op2b, basic_block);
7319 : static tree
7320 : and_var_with_comparison (tree type, tree var, bool invert,
7321 : enum tree_code code2, tree op2a, tree op2b,
7322 : basic_block);
7323 : static tree
7324 : and_var_with_comparison_1 (tree type, gimple *stmt,
7325 : enum tree_code code2, tree op2a, tree op2b,
7326 : basic_block);
7327 : static tree
7328 : or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
7329 : enum tree_code code2, tree op2a, tree op2b,
7330 : basic_block);
7331 : static tree
7332 : or_var_with_comparison (tree, tree var, bool invert,
7333 : enum tree_code code2, tree op2a, tree op2b,
7334 : basic_block);
7335 : static tree
7336 : or_var_with_comparison_1 (tree, gimple *stmt,
7337 : enum tree_code code2, tree op2a, tree op2b,
7338 : basic_block);
7339 :
7340 : /* Helper function for and_comparisons_1: try to simplify the AND of the
7341 : ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
7342 : If INVERT is true, invert the value of the VAR before doing the AND.
7343 : Return NULL_EXPR if we can't simplify this to a single expression. */
7344 :
7345 : static tree
7346 365805 : and_var_with_comparison (tree type, tree var, bool invert,
7347 : enum tree_code code2, tree op2a, tree op2b,
7348 : basic_block outer_cond_bb)
7349 : {
7350 365805 : tree t;
7351 365805 : gimple *stmt = SSA_NAME_DEF_STMT (var);
7352 :
7353 : /* We can only deal with variables whose definitions are assignments. */
7354 365805 : if (!is_gimple_assign (stmt))
7355 : return NULL_TREE;
7356 :
7357 : /* If we have an inverted comparison, apply DeMorgan's law and rewrite
7358 : !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
7359 : Then we only have to consider the simpler non-inverted cases. */
7360 365251 : if (invert)
7361 124384 : t = or_var_with_comparison_1 (type, stmt,
7362 : invert_tree_comparison (code2, false),
7363 : op2a, op2b, outer_cond_bb);
7364 : else
7365 240867 : t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
7366 : outer_cond_bb);
7367 365251 : return canonicalize_bool (t, invert);
7368 : }
7369 :
7370 : /* Try to simplify the AND of the ssa variable defined by the assignment
7371 : STMT with the comparison specified by (OP2A CODE2 OP2B).
7372 : Return NULL_EXPR if we can't simplify this to a single expression. */
7373 :
7374 : static tree
7375 264869 : and_var_with_comparison_1 (tree type, gimple *stmt,
7376 : enum tree_code code2, tree op2a, tree op2b,
7377 : basic_block outer_cond_bb)
7378 : {
7379 264869 : tree var = gimple_assign_lhs (stmt);
7380 264869 : tree true_test_var = NULL_TREE;
7381 264869 : tree false_test_var = NULL_TREE;
7382 264869 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
7383 :
7384 : /* Check for identities like (var AND (var == 0)) => false. */
7385 264869 : if (TREE_CODE (op2a) == SSA_NAME
7386 264869 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
7387 : {
7388 14065 : if ((code2 == NE_EXPR && integer_zerop (op2b))
7389 37616 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
7390 : {
7391 14340 : true_test_var = op2a;
7392 14340 : if (var == true_test_var)
7393 : return var;
7394 : }
7395 6021 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
7396 24092 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
7397 : {
7398 4038 : false_test_var = op2a;
7399 4038 : if (var == false_test_var)
7400 0 : return boolean_false_node;
7401 : }
7402 : }
7403 :
7404 : /* If the definition is a comparison, recurse on it. */
7405 264869 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
7406 : {
7407 1960 : tree t = and_comparisons_1 (type, innercode,
7408 : gimple_assign_rhs1 (stmt),
7409 : gimple_assign_rhs2 (stmt),
7410 : code2,
7411 : op2a,
7412 : op2b, outer_cond_bb);
7413 1960 : if (t)
7414 : return t;
7415 : }
7416 :
7417 : /* If the definition is an AND or OR expression, we may be able to
7418 : simplify by reassociating. */
7419 264863 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
7420 264863 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
7421 : {
7422 26725 : tree inner1 = gimple_assign_rhs1 (stmt);
7423 26725 : tree inner2 = gimple_assign_rhs2 (stmt);
7424 26725 : gimple *s;
7425 26725 : tree t;
7426 26725 : tree partial = NULL_TREE;
7427 26725 : bool is_and = (innercode == BIT_AND_EXPR);
7428 :
7429 : /* Check for boolean identities that don't require recursive examination
7430 : of inner1/inner2:
7431 : inner1 AND (inner1 AND inner2) => inner1 AND inner2 => var
7432 : inner1 AND (inner1 OR inner2) => inner1
7433 : !inner1 AND (inner1 AND inner2) => false
7434 : !inner1 AND (inner1 OR inner2) => !inner1 AND inner2
7435 : Likewise for similar cases involving inner2. */
7436 26725 : if (inner1 == true_test_var)
7437 0 : return (is_and ? var : inner1);
7438 26725 : else if (inner2 == true_test_var)
7439 0 : return (is_and ? var : inner2);
7440 26725 : else if (inner1 == false_test_var)
7441 0 : return (is_and
7442 0 : ? boolean_false_node
7443 0 : : and_var_with_comparison (type, inner2, false, code2, op2a,
7444 0 : op2b, outer_cond_bb));
7445 26725 : else if (inner2 == false_test_var)
7446 0 : return (is_and
7447 0 : ? boolean_false_node
7448 0 : : and_var_with_comparison (type, inner1, false, code2, op2a,
7449 0 : op2b, outer_cond_bb));
7450 :
7451 : /* Next, redistribute/reassociate the AND across the inner tests.
7452 : Compute the first partial result, (inner1 AND (op2a code op2b)) */
7453 26725 : if (TREE_CODE (inner1) == SSA_NAME
7454 26725 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
7455 25751 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7456 50741 : && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
7457 : gimple_assign_rhs1 (s),
7458 : gimple_assign_rhs2 (s),
7459 : code2, op2a, op2b,
7460 : outer_cond_bb)))
7461 : {
7462 : /* Handle the AND case, where we are reassociating:
7463 : (inner1 AND inner2) AND (op2a code2 op2b)
7464 : => (t AND inner2)
7465 : If the partial result t is a constant, we win. Otherwise
7466 : continue on to try reassociating with the other inner test. */
7467 31 : if (is_and)
7468 : {
7469 1 : if (integer_onep (t))
7470 : return inner2;
7471 1 : else if (integer_zerop (t))
7472 0 : return boolean_false_node;
7473 : }
7474 :
7475 : /* Handle the OR case, where we are redistributing:
7476 : (inner1 OR inner2) AND (op2a code2 op2b)
7477 : => (t OR (inner2 AND (op2a code2 op2b))) */
7478 30 : else if (integer_onep (t))
7479 0 : return boolean_true_node;
7480 :
7481 : /* Save partial result for later. */
7482 : partial = t;
7483 : }
7484 :
7485 : /* Compute the second partial result, (inner2 AND (op2a code op2b)) */
7486 26725 : if (TREE_CODE (inner2) == SSA_NAME
7487 26725 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
7488 26265 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
7489 51069 : && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
7490 : gimple_assign_rhs1 (s),
7491 : gimple_assign_rhs2 (s),
7492 : code2, op2a, op2b,
7493 : outer_cond_bb)))
7494 : {
7495 : /* Handle the AND case, where we are reassociating:
7496 : (inner1 AND inner2) AND (op2a code2 op2b)
7497 : => (inner1 AND t) */
7498 879 : if (is_and)
7499 : {
7500 27 : if (integer_onep (t))
7501 : return inner1;
7502 27 : else if (integer_zerop (t))
7503 1 : return boolean_false_node;
7504 : /* If both are the same, we can apply the identity
7505 : (x AND x) == x. */
7506 26 : else if (partial && same_bool_result_p (t, partial))
7507 : return t;
7508 : }
7509 :
7510 : /* Handle the OR case. where we are redistributing:
7511 : (inner1 OR inner2) AND (op2a code2 op2b)
7512 : => (t OR (inner1 AND (op2a code2 op2b)))
7513 : => (t OR partial) */
7514 : else
7515 : {
7516 852 : if (integer_onep (t))
7517 0 : return boolean_true_node;
7518 852 : else if (partial)
7519 : {
7520 : /* We already got a simplification for the other
7521 : operand to the redistributed OR expression. The
7522 : interesting case is when at least one is false.
7523 : Or, if both are the same, we can apply the identity
7524 : (x OR x) == x. */
7525 11 : if (integer_zerop (partial))
7526 : return t;
7527 6 : else if (integer_zerop (t))
7528 : return partial;
7529 4 : else if (same_bool_result_p (t, partial))
7530 : return t;
7531 : }
7532 : }
7533 : }
7534 : }
7535 : return NULL_TREE;
7536 : }
7537 :
7538 : /* Try to simplify the AND of two comparisons defined by
7539 : (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
7540 : If this can be done without constructing an intermediate value,
7541 : return the resulting tree; otherwise NULL_TREE is returned.
7542 : This function is deliberately asymmetric as it recurses on SSA_DEFs
7543 : in the first comparison but not the second. */
7544 :
7545 : static tree
7546 1266713 : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
7547 : enum tree_code code2, tree op2a, tree op2b,
7548 : basic_block outer_cond_bb)
7549 : {
7550 1266713 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
7551 :
7552 : /* First check for ((x CODE1 y) AND (x CODE2 y)). */
7553 1266713 : if (operand_equal_p (op1a, op2a, 0)
7554 1266713 : && operand_equal_p (op1b, op2b, 0))
7555 : {
7556 : /* Result will be either NULL_TREE, or a combined comparison. */
7557 4495 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7558 : TRUTH_ANDIF_EXPR, code1, code2,
7559 : truth_type, op1a, op1b);
7560 4495 : if (t)
7561 : return t;
7562 : }
7563 :
7564 : /* Likewise the swapped case of the above. */
7565 1265098 : if (operand_equal_p (op1a, op2b, 0)
7566 1265098 : && operand_equal_p (op1b, op2a, 0))
7567 : {
7568 : /* Result will be either NULL_TREE, or a combined comparison. */
7569 65 : tree t = combine_comparisons (UNKNOWN_LOCATION,
7570 : TRUTH_ANDIF_EXPR, code1,
7571 : swap_tree_comparison (code2),
7572 : truth_type, op1a, op1b);
7573 65 : if (t)
7574 : return t;
7575 : }
7576 :
7577 : /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
7578 : NAME's definition is a truth value. See if there are any simplifications
7579 : that can be done against the NAME's definition. */
7580 1265097 : if (TREE_CODE (op1a) == SSA_NAME
7581 1265046 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
7582 2232437 : && (integer_zerop (op1b) || integer_onep (op1b)))
7583 : {
7584 177338 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
7585 468188 : || (code1 == NE_EXPR && integer_onep (op1b)));
7586 428032 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
7587 428032 : switch (gimple_code (stmt))
7588 : {
7589 362966 : case GIMPLE_ASSIGN:
7590 : /* Try to simplify by copy-propagating the definition. */
7591 362966 : return and_var_with_comparison (type, op1a, invert, code2, op2a,
7592 362966 : op2b, outer_cond_bb);
7593 :
7594 30882 : case GIMPLE_PHI:
7595 : /* If every argument to the PHI produces the same result when
7596 : ANDed with the second comparison, we win.
7597 : Do not do this unless the type is bool since we need a bool
7598 : result here anyway. */
7599 30882 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
7600 : {
7601 : tree result = NULL_TREE;
7602 : unsigned i;
7603 10838 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
7604 : {
7605 10838 : tree arg = gimple_phi_arg_def (stmt, i);
7606 :
7607 : /* If this PHI has itself as an argument, ignore it.
7608 : If all the other args produce the same result,
7609 : we're still OK. */
7610 10838 : if (arg == gimple_phi_result (stmt))
7611 0 : continue;
7612 10838 : else if (TREE_CODE (arg) == INTEGER_CST)
7613 : {
7614 7095 : if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
7615 : {
7616 4113 : if (!result)
7617 1689 : result = boolean_false_node;
7618 2424 : else if (!integer_zerop (result))
7619 : return NULL_TREE;
7620 : }
7621 2982 : else if (!result)
7622 1872 : result = fold_build2 (code2, boolean_type_node,
7623 : op2a, op2b);
7624 1110 : else if (!same_bool_comparison_p (result,
7625 : code2, op2a, op2b))
7626 : return NULL_TREE;
7627 : }
7628 3743 : else if (TREE_CODE (arg) == SSA_NAME
7629 3743 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
7630 : {
7631 3740 : tree temp;
7632 3740 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
7633 : /* In simple cases we can look through PHI nodes,
7634 : but we have to be careful with loops.
7635 : See PR49073. */
7636 3740 : if (! dom_info_available_p (CDI_DOMINATORS)
7637 3740 : || gimple_bb (def_stmt) == gimple_bb (stmt)
7638 7480 : || dominated_by_p (CDI_DOMINATORS,
7639 3740 : gimple_bb (def_stmt),
7640 3740 : gimple_bb (stmt)))
7641 901 : return NULL_TREE;
7642 2839 : temp = and_var_with_comparison (type, arg, invert, code2,
7643 : op2a, op2b,
7644 : outer_cond_bb);
7645 2839 : if (!temp)
7646 : return NULL_TREE;
7647 0 : else if (!result)
7648 : result = temp;
7649 0 : else if (!same_bool_result_p (result, temp))
7650 : return NULL_TREE;
7651 : }
7652 : else
7653 : return NULL_TREE;
7654 : }
7655 : return result;
7656 : }
7657 :
7658 : default:
7659 : break;
7660 : }
7661 : }
7662 : return NULL_TREE;
7663 : }
7664 :
7665 : static basic_block fosa_bb;
7666 : static vec<std::pair<tree, flow_sensitive_info_storage> > *fosa_unwind;
7667 : static tree
7668 60298296 : follow_outer_ssa_edges (tree val)
7669 : {
7670 60298296 : if (TREE_CODE (val) == SSA_NAME
7671 60298296 : && !SSA_NAME_IS_DEFAULT_DEF (val))
7672 : {
7673 59158741 : basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (val));
7674 59158741 : if (!def_bb
7675 19534882 : || def_bb == fosa_bb
7676 69634903 : || (dom_info_available_p (CDI_DOMINATORS)
7677 10476162 : && (def_bb == fosa_bb
7678 10476162 : || dominated_by_p (CDI_DOMINATORS, fosa_bb, def_bb))))
7679 52712538 : return val;
7680 6446203 : flow_sensitive_info_storage storage;
7681 6446203 : storage.save_and_clear (val);
7682 : /* If the definition does not dominate fosa_bb temporarily reset
7683 : flow-sensitive info. */
7684 6446203 : fosa_unwind->safe_push (std::make_pair (val, storage));
7685 : /* We cannot temporarily rewrite stmts with undefined overflow
7686 : behavior, so avoid expanding them. But still save off the
7687 : flow-sensitive info as we might be using the ssa name as the leaf. */
7688 12850299 : if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val))
7689 700490 : || POINTER_TYPE_P (TREE_TYPE (val)))
7690 12481641 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val)))
7691 : return NULL_TREE;
7692 : return val;
7693 : }
7694 : return val;
7695 : }
7696 :
7697 : /* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
7698 : : try to simplify the AND/OR of the ssa variable VAR with the comparison
7699 : specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't
7700 : simplify this to a single expression. As we are going to lower the cost
7701 : of building SSA names / gimple stmts significantly, we need to allocate
7702 : them ont the stack. This will cause the code to be a bit ugly. */
7703 :
7704 : static tree
7705 1200411 : maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
7706 : enum tree_code code1,
7707 : tree op1a, tree op1b,
7708 : enum tree_code code2, tree op2a,
7709 : tree op2b,
7710 : basic_block outer_cond_bb)
7711 : {
7712 : /* Allocate gimple stmt1 on the stack. */
7713 1200411 : gassign *stmt1
7714 1200411 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7715 1200411 : gimple_init (stmt1, GIMPLE_ASSIGN, 3);
7716 1200411 : gimple_assign_set_rhs_code (stmt1, code1);
7717 1200411 : gimple_assign_set_rhs1 (stmt1, op1a);
7718 1200411 : gimple_assign_set_rhs2 (stmt1, op1b);
7719 1200411 : gimple_set_bb (stmt1, NULL);
7720 :
7721 : /* Allocate gimple stmt2 on the stack. */
7722 1200411 : gassign *stmt2
7723 1200411 : = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
7724 1200411 : gimple_init (stmt2, GIMPLE_ASSIGN, 3);
7725 1200411 : gimple_assign_set_rhs_code (stmt2, code2);
7726 1200411 : gimple_assign_set_rhs1 (stmt2, op2a);
7727 1200411 : gimple_assign_set_rhs2 (stmt2, op2b);
7728 1200411 : gimple_set_bb (stmt2, NULL);
7729 :
7730 : /* Allocate SSA names(lhs1) on the stack. */
7731 1200411 : alignas (tree_node) unsigned char lhs1buf[sizeof (tree_ssa_name)];
7732 1200411 : tree lhs1 = (tree) &lhs1buf[0];
7733 1200411 : memset (lhs1, 0, sizeof (tree_ssa_name));
7734 1200411 : TREE_SET_CODE (lhs1, SSA_NAME);
7735 1200411 : TREE_TYPE (lhs1) = type;
7736 1200411 : init_ssa_name_imm_use (lhs1);
7737 :
7738 : /* Allocate SSA names(lhs2) on the stack. */
7739 1200411 : alignas (tree_node) unsigned char lhs2buf[sizeof (tree_ssa_name)];
7740 1200411 : tree lhs2 = (tree) &lhs2buf[0];
7741 1200411 : memset (lhs2, 0, sizeof (tree_ssa_name));
7742 1200411 : TREE_SET_CODE (lhs2, SSA_NAME);
7743 1200411 : TREE_TYPE (lhs2) = type;
7744 1200411 : init_ssa_name_imm_use (lhs2);
7745 :
7746 1200411 : gimple_assign_set_lhs (stmt1, lhs1);
7747 1200411 : gimple_assign_set_lhs (stmt2, lhs2);
7748 :
7749 1200411 : gimple_match_op op (gimple_match_cond::UNCOND, code,
7750 : type, gimple_assign_lhs (stmt1),
7751 1200411 : gimple_assign_lhs (stmt2));
7752 1200411 : fosa_bb = outer_cond_bb;
7753 1200411 : auto_vec<std::pair<tree, flow_sensitive_info_storage>, 8> unwind_stack;
7754 1200411 : fosa_unwind = &unwind_stack;
7755 1800573 : if (op.resimplify (NULL, (!outer_cond_bb
7756 : ? follow_all_ssa_edges : follow_outer_ssa_edges)))
7757 : {
7758 3236 : fosa_unwind = NULL;
7759 13971 : for (auto p : unwind_stack)
7760 4263 : p.second.restore (p.first);
7761 3236 : if (gimple_simplified_result_is_gimple_val (&op))
7762 : {
7763 2602 : tree res = op.ops[0];
7764 2602 : if (res == lhs1)
7765 2099 : return build2 (code1, type, op1a, op1b);
7766 503 : else if (res == lhs2)
7767 432 : return build2 (code2, type, op2a, op2b);
7768 : else
7769 : return res;
7770 : }
7771 634 : else if (op.code.is_tree_code ()
7772 634 : && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
7773 : {
7774 634 : tree op0 = op.ops[0];
7775 634 : tree op1 = op.ops[1];
7776 634 : if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
7777 : return NULL_TREE; /* not simple */
7778 :
7779 634 : return build2 ((enum tree_code)op.code, op.type, op0, op1);
7780 : }
7781 : }
7782 1197175 : fosa_unwind = NULL;
7783 10033465 : for (auto p : unwind_stack)
7784 6441940 : p.second.restore (p.first);
7785 :
7786 1197175 : return NULL_TREE;
7787 1200411 : }
7788 :
7789 : /* Return TRUE and set op[0] if T, following all SSA edges, is a type
7790 : conversion. Reject loads if LOAD is NULL, otherwise set *LOAD if a
7791 : converting load is found. */
7792 :
7793 : static bool
7794 3293994 : gimple_convert_def_p (tree t, tree op[1], gimple **load = NULL)
7795 : {
7796 3293994 : bool ret = false;
7797 :
7798 3293994 : if (TREE_CODE (t) == SSA_NAME
7799 3293994 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7800 1819755 : if (gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7801 : {
7802 1726700 : bool load_p = gimple_assign_load_p (def);
7803 1726700 : if (load_p && !load)
7804 : return false;
7805 1742037 : switch (gimple_assign_rhs_code (def))
7806 : {
7807 13806 : CASE_CONVERT:
7808 13806 : op[0] = gimple_assign_rhs1 (def);
7809 13806 : ret = true;
7810 13806 : break;
7811 :
7812 3950 : case VIEW_CONVERT_EXPR:
7813 3950 : op[0] = TREE_OPERAND (gimple_assign_rhs1 (def), 0);
7814 3950 : ret = true;
7815 3950 : break;
7816 :
7817 : default:
7818 : break;
7819 : }
7820 :
7821 17756 : if (ret && load_p)
7822 0 : *load = def;
7823 : }
7824 :
7825 : return ret;
7826 : }
7827 :
7828 : /* Return TRUE and set op[*] if T, following all SSA edges, resolves to a
7829 : binary expression with code CODE. */
7830 :
7831 : static bool
7832 3328185 : gimple_binop_def_p (enum tree_code code, tree t, tree op[2])
7833 : {
7834 3328185 : if (TREE_CODE (t) == SSA_NAME
7835 3328185 : && !SSA_NAME_IS_DEFAULT_DEF (t))
7836 1851679 : if (gimple *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t)))
7837 1756209 : if (gimple_assign_rhs_code (def) == code)
7838 : {
7839 57214 : op[0] = gimple_assign_rhs1 (def);
7840 57214 : op[1] = gimple_assign_rhs2 (def);
7841 57214 : return true;
7842 : }
7843 : return false;
7844 : }
7845 : /* Subroutine for fold_truth_andor_1: decode a field reference.
7846 :
7847 : If *PEXP is a comparison reference, we return the innermost reference.
7848 :
7849 : *PBITSIZE is set to the number of bits in the reference, *PBITPOS is
7850 : set to the starting bit number.
7851 :
7852 : *PVOLATILEP is set to 1 if the any expression encountered is volatile;
7853 : otherwise it is not changed.
7854 :
7855 : *PUNSIGNEDP is set to the signedness of the field.
7856 :
7857 : *PREVERSEP is set to the storage order of the field.
7858 :
7859 : *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If
7860 : *PAND_MASK is initially set to a mask with nonzero precision, that mask is
7861 : combined with the found mask, or adjusted in precision to match.
7862 :
7863 : *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask
7864 : encompassed bits that corresponded to extensions of the sign bit.
7865 :
7866 : *PXORP is to be FALSE if EXP might be a XOR used in a compare, in which
7867 : case, if PXOR_CMP_OP is a zero constant, it will be overridden with *PEXP,
7868 : *PXORP will be set to TRUE, *PXOR_AND_MASK will be copied from *PAND_MASK,
7869 : and the left-hand operand of the XOR will be decoded. If *PXORP is TRUE,
7870 : PXOR_CMP_OP and PXOR_AND_MASK are supposed to be NULL, and then the
7871 : right-hand operand of the XOR will be decoded.
7872 :
7873 : *LOAD is set to the load stmt of the innermost reference, if any,
7874 : *and NULL otherwise.
7875 :
7876 : LOC[0..3] are filled in as conversion, masking, shifting and loading
7877 : operations are located.
7878 :
7879 : Return 0 if this is not a component reference or is one that we can't
7880 : do anything with. */
7881 :
7882 : static tree
7883 1174928 : decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize,
7884 : HOST_WIDE_INT *pbitpos,
7885 : bool *punsignedp, bool *preversep, bool *pvolatilep,
7886 : wide_int *pand_mask, bool *psignbit,
7887 : bool *pxorp, tree *pxor_cmp_op, wide_int *pxor_and_mask,
7888 : gimple **pload, location_t loc[4])
7889 : {
7890 1174928 : tree exp = *pexp;
7891 1174928 : tree outer_type = 0;
7892 1174928 : wide_int and_mask;
7893 1174928 : tree inner, offset;
7894 1174928 : int shiftrt = 0;
7895 1174928 : tree res_ops[2];
7896 1174928 : machine_mode mode;
7897 1174928 : bool convert_before_shift = false;
7898 1174928 : bool signbit = false;
7899 1174928 : bool xorp = false;
7900 1174928 : tree xor_cmp_op;
7901 1174928 : wide_int xor_and_mask;
7902 1174928 : gimple *load = NULL;
7903 :
7904 : /* All the optimizations using this function assume integer fields.
7905 : There are problems with FP fields since the type_for_size call
7906 : below can fail for, e.g., XFmode. */
7907 1174928 : if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
7908 : return NULL_TREE;
7909 :
7910 : /* Drop casts, saving only the outermost type, effectively used in
7911 : the compare. We can deal with at most one conversion, and it may
7912 : appear at various points in the chain of recognized preparation
7913 : statements. Earlier optimizers will often have already dropped
7914 : unneeded extensions, but they may survive, as in PR118046. ???
7915 : Can we do better and allow multiple conversions, perhaps taking
7916 : note of the narrowest intermediate type, sign extensions and
7917 : whatnot? */
7918 1109413 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
7919 : {
7920 16401 : outer_type = TREE_TYPE (exp);
7921 16401 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
7922 16401 : exp = res_ops[0];
7923 : }
7924 :
7925 : /* Recognize and save a masking operation. Combine it with an
7926 : incoming mask. */
7927 1109413 : if (gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops)
7928 1109413 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
7929 : {
7930 33534 : loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp));
7931 33534 : exp = res_ops[0];
7932 33534 : and_mask = wi::to_wide (res_ops[1]);
7933 33534 : unsigned prec_in = pand_mask->get_precision ();
7934 33534 : if (prec_in)
7935 : {
7936 52 : unsigned prec_op = and_mask.get_precision ();
7937 52 : if (prec_in >= prec_op)
7938 : {
7939 52 : if (prec_in > prec_op)
7940 0 : and_mask = wide_int::from (and_mask, prec_in, UNSIGNED);
7941 52 : and_mask &= *pand_mask;
7942 : }
7943 : else
7944 0 : and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED);
7945 : }
7946 : }
7947 : else
7948 1075879 : and_mask = *pand_mask;
7949 :
7950 : /* Turn (a ^ b) [!]= 0 into a [!]= b. */
7951 1109413 : if (pxorp && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops))
7952 : {
7953 : /* No location recorded for this one, it's entirely subsumed by the
7954 : compare. */
7955 11002 : if (*pxorp)
7956 : {
7957 5473 : exp = res_ops[1];
7958 5473 : gcc_checking_assert (!pxor_cmp_op && !pxor_and_mask);
7959 : }
7960 5529 : else if (!pxor_cmp_op)
7961 : /* Not much we can do when xor appears in the right-hand compare
7962 : operand. */
7963 : return NULL_TREE;
7964 5475 : else if (integer_zerop (*pxor_cmp_op))
7965 : {
7966 5473 : xorp = true;
7967 5473 : exp = res_ops[0];
7968 5473 : xor_cmp_op = *pexp;
7969 5473 : xor_and_mask = *pand_mask;
7970 : }
7971 : }
7972 :
7973 : /* Another chance to drop conversions. */
7974 1109359 : if (!outer_type && gimple_convert_def_p (exp, res_ops))
7975 : {
7976 1335 : outer_type = TREE_TYPE (exp);
7977 1335 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
7978 1335 : exp = res_ops[0];
7979 : }
7980 :
7981 : /* Take note of shifts. */
7982 1109359 : if (gimple_binop_def_p (RSHIFT_EXPR, exp, res_ops)
7983 1109359 : && TREE_CODE (res_ops[1]) == INTEGER_CST)
7984 : {
7985 571 : loc[2] = gimple_location (SSA_NAME_DEF_STMT (exp));
7986 571 : exp = res_ops[0];
7987 571 : if (!tree_fits_shwi_p (res_ops[1]))
7988 : return NULL_TREE;
7989 571 : shiftrt = tree_to_shwi (res_ops[1]);
7990 571 : if (shiftrt <= 0)
7991 : return NULL_TREE;
7992 : }
7993 :
7994 : /* Yet another chance to drop conversions. This one is allowed to
7995 : match a converting load, subsuming the load identification block
7996 : below. */
7997 1109359 : if (!outer_type && gimple_convert_def_p (exp, res_ops, &load))
7998 : {
7999 20 : outer_type = TREE_TYPE (exp);
8000 20 : loc[0] = gimple_location (SSA_NAME_DEF_STMT (exp));
8001 20 : if (load)
8002 0 : loc[3] = gimple_location (load);
8003 20 : exp = res_ops[0];
8004 : /* This looks backwards, but we're going back the def chain, so if we
8005 : find the conversion here, after finding a shift, that's because the
8006 : convert appears before the shift, and we should thus adjust the bit
8007 : pos and size because of the shift after adjusting it due to type
8008 : conversion. */
8009 20 : convert_before_shift = true;
8010 : }
8011 :
8012 : /* Identify the load, if there is one. */
8013 1109359 : if (!load && TREE_CODE (exp) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (exp))
8014 : {
8015 616406 : gimple *def = SSA_NAME_DEF_STMT (exp);
8016 616406 : if (gimple_assign_load_p (def))
8017 : {
8018 389654 : loc[3] = gimple_location (def);
8019 389654 : load = def;
8020 389654 : exp = gimple_assign_rhs1 (def);
8021 : }
8022 : }
8023 :
8024 : /* Identify the relevant bits. */
8025 1109359 : poly_int64 poly_bitsize, poly_bitpos;
8026 1109359 : int unsignedp, reversep = *preversep, volatilep = *pvolatilep;
8027 1109359 : inner = get_inner_reference (exp, &poly_bitsize, &poly_bitpos, &offset,
8028 : &mode, &unsignedp, &reversep, &volatilep);
8029 :
8030 1109359 : HOST_WIDE_INT bs, bp;
8031 1109359 : if (!poly_bitsize.is_constant (&bs)
8032 1109359 : || !poly_bitpos.is_constant (&bp)
8033 1109359 : || bs <= shiftrt
8034 1109359 : || offset != 0
8035 1108123 : || TREE_CODE (inner) == PLACEHOLDER_EXPR
8036 : /* Reject out-of-bound accesses (PR79731, PR118514). */
8037 1108123 : || !access_in_bounds_of_type_p (TREE_TYPE (inner), bs, bp)
8038 1108089 : || (INTEGRAL_TYPE_P (TREE_TYPE (inner))
8039 760750 : && !type_has_mode_precision_p (TREE_TYPE (inner))))
8040 48844 : return NULL_TREE;
8041 :
8042 : /* Adjust shifts... */
8043 1060515 : if (convert_before_shift
8044 1060515 : && outer_type && bs > TYPE_PRECISION (outer_type))
8045 : {
8046 2 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8047 2 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8048 0 : bp += excess;
8049 : bs -= excess;
8050 : }
8051 :
8052 1060515 : if (shiftrt)
8053 : {
8054 : /* Punt if we're shifting by more than the loaded bitfield (after
8055 : adjustment), or if there's a shift after a change of signedness, punt.
8056 : When comparing this field with a constant, we'll check that the
8057 : constant is a proper sign- or zero-extension (depending on signedness)
8058 : of a value that would fit in the selected portion of the bitfield. A
8059 : shift after a change of signedness would make the extension
8060 : non-uniform, and we can't deal with that (yet ???). See
8061 : gcc.dg/field-merge-22.c for a test that would go wrong. */
8062 571 : if (bs <= shiftrt
8063 571 : || (convert_before_shift
8064 20 : && outer_type && unsignedp != TYPE_UNSIGNED (outer_type)))
8065 : return NULL_TREE;
8066 552 : if (!reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8067 552 : bp += shiftrt;
8068 552 : bs -= shiftrt;
8069 : }
8070 :
8071 : /* ... and bit position. */
8072 1060496 : if (!convert_before_shift
8073 1060496 : && outer_type && bs > TYPE_PRECISION (outer_type))
8074 : {
8075 7736 : HOST_WIDE_INT excess = bs - TYPE_PRECISION (outer_type);
8076 7736 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8077 0 : bp += excess;
8078 : bs -= excess;
8079 : }
8080 :
8081 : /* If the number of bits in the reference is the same as the bitsize of
8082 : the outer type, then the outer type gives the signedness. Otherwise
8083 : (in case of a small bitfield) the signedness is unchanged. */
8084 1060496 : if (outer_type && bs == TYPE_PRECISION (outer_type))
8085 12919 : unsignedp = TYPE_UNSIGNED (outer_type);
8086 :
8087 : /* Make the mask the expected width. */
8088 1060496 : if (and_mask.get_precision () != 0)
8089 : {
8090 : /* If the AND_MASK encompasses bits that would be extensions of
8091 : the sign bit, set SIGNBIT. */
8092 38683 : if (!unsignedp
8093 2981 : && and_mask.get_precision () > bs
8094 41712 : && (and_mask & wi::mask (bs, true, and_mask.get_precision ())) != 0)
8095 : signbit = true;
8096 38683 : and_mask = wide_int::from (and_mask, bs, UNSIGNED);
8097 : }
8098 :
8099 1060496 : *pexp = exp;
8100 1060496 : *pload = load;
8101 1060496 : *pbitsize = bs;
8102 1060496 : *pbitpos = bp;
8103 1060496 : *punsignedp = unsignedp;
8104 1060496 : *preversep = reversep;
8105 1060496 : *pvolatilep = volatilep;
8106 1060496 : *psignbit = signbit;
8107 1060496 : *pand_mask = and_mask;
8108 1060496 : if (xorp)
8109 : {
8110 5473 : *pxorp = xorp;
8111 5473 : *pxor_cmp_op = xor_cmp_op;
8112 5473 : *pxor_and_mask = xor_and_mask;
8113 : }
8114 :
8115 : return inner;
8116 1174928 : }
8117 :
8118 : /* Return the one bitpos within bit extents L or R that is at an
8119 : ALIGN-bit alignment boundary, or -1 if there is more than one such
8120 : boundary, if there isn't any, or if there is any such boundary
8121 : between the extents. L and R are given by bitpos and bitsize. If
8122 : it doesn't return -1, there are two consecutive ALIGN-bit words
8123 : that contain both extents, and at least one of the extents
8124 : straddles across the returned alignment boundary. */
8125 :
8126 : static inline HOST_WIDE_INT
8127 48381 : compute_split_boundary_from_align (HOST_WIDE_INT align,
8128 : HOST_WIDE_INT l_bitpos,
8129 : HOST_WIDE_INT l_bitsize,
8130 : HOST_WIDE_INT r_bitpos,
8131 : HOST_WIDE_INT r_bitsize)
8132 : {
8133 48381 : HOST_WIDE_INT amask = ~(align - 1);
8134 :
8135 48381 : HOST_WIDE_INT first_bit = MIN (l_bitpos, r_bitpos);
8136 48381 : HOST_WIDE_INT end_bit = MAX (l_bitpos + l_bitsize, r_bitpos + r_bitsize);
8137 :
8138 48381 : HOST_WIDE_INT boundary = (end_bit - 1) & amask;
8139 :
8140 : /* Make sure we're crossing no more than one alignment boundary.
8141 :
8142 : ??? We don't have logic to recombine loads of two adjacent
8143 : fields that each crosses a different alignment boundary, so
8144 : as to load the middle word only once, if other words can't be
8145 : otherwise recombined. */
8146 48381 : if (boundary - first_bit > align)
8147 : return -1;
8148 :
8149 18753 : HOST_WIDE_INT l_start_word = l_bitpos & amask;
8150 18753 : HOST_WIDE_INT l_end_word = (l_bitpos + l_bitsize - 1) & amask;
8151 :
8152 18753 : HOST_WIDE_INT r_start_word = r_bitpos & amask;
8153 18753 : HOST_WIDE_INT r_end_word = (r_bitpos + r_bitsize - 1) & amask;
8154 :
8155 : /* If neither field straddles across an alignment boundary, it's no
8156 : use to even try to merge them. */
8157 18753 : if (l_start_word == l_end_word && r_start_word == r_end_word)
8158 18446 : return -1;
8159 :
8160 : return boundary;
8161 : }
8162 :
8163 : /* Make a bit_field_ref. If POINT is NULL, return the BIT_FIELD_REF.
8164 : Otherwise, build and insert a load stmt before POINT, and return
8165 : the SSA_NAME. ??? Rewrite LOAD in terms of the bitfield? */
8166 :
8167 : static tree
8168 4640 : make_bit_field_load (location_t loc, tree inner, tree orig_inner, tree type,
8169 : HOST_WIDE_INT bitsize, poly_int64 bitpos,
8170 : bool unsignedp, bool reversep, gimple *point)
8171 : {
8172 4640 : if (point && loc == UNKNOWN_LOCATION)
8173 18 : loc = gimple_location (point);
8174 :
8175 4640 : tree ref = make_bit_field_ref (loc, unshare_expr (inner),
8176 : unshare_expr (orig_inner),
8177 : type, bitsize, bitpos,
8178 : unsignedp, reversep);
8179 4640 : if (!point)
8180 : return ref;
8181 :
8182 : /* If we're remaking the same load, reuse the SSA NAME it is already loaded
8183 : into. */
8184 4485 : if (gimple_assign_load_p (point)
8185 4485 : && operand_equal_p (ref, gimple_assign_rhs1 (point)))
8186 : {
8187 1662 : gcc_checking_assert (TREE_CODE (gimple_assign_lhs (point)) == SSA_NAME);
8188 : return gimple_assign_lhs (point);
8189 : }
8190 :
8191 2823 : gimple_seq stmts = NULL;
8192 2823 : tree ret = force_gimple_operand (ref, &stmts, true, NULL_TREE);
8193 :
8194 : /* We know the vuse is supposed to end up being the same as that at the
8195 : original load at the insertion point, but if we don't set it, it will be a
8196 : generic placeholder that only the global SSA update at the end of the pass
8197 : would make equal, too late for us to use in further combinations. So go
8198 : ahead and copy the vuse. */
8199 :
8200 2823 : tree reaching_vuse = gimple_vuse (point);
8201 2823 : for (gimple_stmt_iterator i = gsi_start (stmts);
8202 6161 : !gsi_end_p (i); gsi_next (&i))
8203 : {
8204 3338 : gimple *new_stmt = gsi_stmt (i);
8205 6676 : if (gimple_has_mem_ops (new_stmt))
8206 3338 : gimple_set_vuse (new_stmt, reaching_vuse);
8207 : }
8208 :
8209 2823 : gimple_stmt_iterator gsi = gsi_for_stmt (point);
8210 2823 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
8211 2823 : return ret;
8212 : }
8213 :
8214 : /* Initialize ln_arg[0] and ln_arg[1] to a pair of newly-created (at
8215 : LOC) loads from INNER (from ORIG_INNER), of modes MODE and MODE2,
8216 : respectively, starting at BIT_POS, using reversed endianness if
8217 : REVERSEP. Also initialize BITPOS (the starting position of each
8218 : part into INNER), BITSIZ (the bit count starting at BITPOS),
8219 : TOSHIFT[1] (the amount by which the part and its mask are to be
8220 : shifted right to bring its least-significant bit to bit zero) and
8221 : SHIFTED (the amount by which the part, by separate loading, has
8222 : already been shifted right, but that the mask needs shifting to
8223 : match). */
8224 :
8225 : static inline void
8226 307 : build_split_load (tree /* out */ ln_arg[2],
8227 : HOST_WIDE_INT /* out */ bitpos[2],
8228 : HOST_WIDE_INT /* out */ bitsiz[2],
8229 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8230 : HOST_WIDE_INT /* out */ shifted[2],
8231 : location_t loc, tree inner, tree orig_inner,
8232 : scalar_int_mode mode, scalar_int_mode mode2,
8233 : HOST_WIDE_INT bit_pos, bool reversep,
8234 : gimple *point[2])
8235 : {
8236 307 : scalar_int_mode modes[2] = { mode, mode2 };
8237 307 : bitsiz[0] = GET_MODE_BITSIZE (mode);
8238 307 : bitsiz[1] = GET_MODE_BITSIZE (mode2);
8239 :
8240 921 : for (int i = 0; i < 2; i++)
8241 : {
8242 614 : tree type = lang_hooks.types.type_for_mode (modes[i], 1);
8243 614 : if (!type)
8244 : {
8245 0 : type = build_nonstandard_integer_type (bitsiz[0], 1);
8246 0 : gcc_assert (type);
8247 : }
8248 614 : bitpos[i] = bit_pos;
8249 1228 : ln_arg[i] = make_bit_field_load (loc, inner, orig_inner,
8250 614 : type, bitsiz[i],
8251 614 : bit_pos, 1, reversep, point[i]);
8252 614 : bit_pos += bitsiz[i];
8253 : }
8254 :
8255 307 : toshift[1] = toshift[0];
8256 307 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8257 : {
8258 3 : shifted[0] = bitsiz[1];
8259 3 : shifted[1] = 0;
8260 3 : toshift[0] = 0;
8261 : }
8262 : else
8263 : {
8264 304 : shifted[1] = bitsiz[0];
8265 304 : shifted[0] = 0;
8266 304 : toshift[1] = 0;
8267 : }
8268 307 : }
8269 :
8270 : /* Make arrangements to split at bit BOUNDARY a single loaded word
8271 : (with REVERSEP bit order) LN_ARG[0], to be shifted right by
8272 : TOSHIFT[0] to bring the field of interest to the least-significant
8273 : bit. The expectation is that the same loaded word will be
8274 : propagated from part 0 to part 1, with just different shifting and
8275 : masking to extract both parts. MASK is not expected to do more
8276 : than masking out the bits that belong to the other part. See
8277 : build_split_load for more information on the other fields. */
8278 :
8279 : static inline void
8280 51 : reuse_split_load (tree /* in[0] out[1] */ ln_arg[2],
8281 : HOST_WIDE_INT /* in[0] out[1] */ bitpos[2],
8282 : HOST_WIDE_INT /* in[0] out[1] */ bitsiz[2],
8283 : HOST_WIDE_INT /* in[0] out[0..1] */ toshift[2],
8284 : HOST_WIDE_INT /* out */ shifted[2],
8285 : wide_int /* out */ mask[2],
8286 : HOST_WIDE_INT boundary, bool reversep)
8287 : {
8288 51 : unsigned prec = TYPE_PRECISION (TREE_TYPE (ln_arg[0]));
8289 :
8290 51 : ln_arg[1] = ln_arg[0];
8291 51 : bitpos[1] = bitpos[0];
8292 51 : bitsiz[1] = bitsiz[0];
8293 51 : shifted[1] = shifted[0] = 0;
8294 :
8295 51 : if (reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8296 : {
8297 3 : toshift[1] = toshift[0];
8298 3 : toshift[0] = bitpos[0] + bitsiz[0] - boundary;
8299 3 : mask[0] = wi::mask (toshift[0], true, prec);
8300 3 : mask[1] = wi::mask (toshift[0], false, prec);
8301 : }
8302 : else
8303 : {
8304 48 : toshift[1] = boundary - bitpos[1];
8305 48 : mask[1] = wi::mask (toshift[1], true, prec);
8306 48 : mask[0] = wi::mask (toshift[1], false, prec);
8307 : }
8308 51 : }
8309 :
8310 : /* Find ways of folding logical expressions of LHS and RHS:
8311 :
8312 : Try to merge two comparisons to nearby fields.
8313 :
8314 : For example, if we have p->a == 2 && p->b == 4 and we can load both A and B
8315 : at once, we can do this with a comparison against the object ANDed with the
8316 : a mask.
8317 :
8318 : If we have p->a == q->a && p->b == q->b, we may be able to use bit masking
8319 : operations to do this with one comparison, loading both fields from P at
8320 : once, and likewise from Q.
8321 :
8322 : Herein, loading at once means loading from within the same alignment
8323 : boundary for the enclosing object. If (packed) fields cross such alignment
8324 : boundaries, we may still recombine the compares, so that loads do not cross
8325 : the boundaries.
8326 :
8327 : CODE is the logical operation being done. It can be TRUTH_ANDIF_EXPR,
8328 : TRUTH_AND_EXPR, TRUTH_ORIF_EXPR, or TRUTH_OR_EXPR.
8329 :
8330 : TRUTH_TYPE is the type of the logical operand.
8331 :
8332 : LHS is denoted as LL_ARG LCODE LR_ARG.
8333 :
8334 : RHS is denoted as RL_ARG RCODE RR_ARG.
8335 :
8336 : LHS is assumed to dominate RHS.
8337 :
8338 : Combined loads are inserted next to preexisting loads, once we determine
8339 : that the combination is viable, and the combined condition references new
8340 : SSA_NAMEs that hold the loaded values. Since the original loads are
8341 : verified to have the same gimple_vuse, the insertion point doesn't matter
8342 : for correctness. ??? The loads may be a lot earlier than the compares, and
8343 : it's conceivable that one or two loads for RHS appear before those for LHS.
8344 : It could be advantageous to try to place the loads optimally, taking
8345 : advantage of knowing whether RHS is accessed before LHS, or that both are
8346 : accessed before both compares, but we don't do that (yet?).
8347 :
8348 : SEPARATEP should be NULL if the combined condition must be returned as a
8349 : single expression, even if it is a compound condition. This must only be
8350 : done if LHS and RHS are adjacent, without intervening conditions, and the
8351 : combined condition is to replace RHS, while LHS is dropped altogether.
8352 :
8353 : Otherwise, SEPARATEP must be a non-NULL pointer to a NULL_TREE, that may be
8354 : replaced by a part of the compound condition that could replace RHS, while
8355 : the returned expression replaces LHS. This works whether or not LHS and RHS
8356 : are adjacent, as long as there aren't VDEFs or other side effects between
8357 : them.
8358 :
8359 : If the "words" accessed by RHS are already accessed by LHS, this won't
8360 : matter, but if RHS accesses "words" that LHS doesn't, then *SEPARATEP will
8361 : be set to the compares that should take RHS's place. By "words" we mean
8362 : contiguous bits that do not cross a an TYPE_ALIGN boundary of the accessed
8363 : object's type.
8364 :
8365 : We return the simplified tree or 0 if no optimization is possible. */
8366 :
8367 : tree
8368 438267 : fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type,
8369 : location_t lloc, enum tree_code lcode,
8370 : tree ll_arg, tree lr_arg,
8371 : location_t rloc, enum tree_code rcode,
8372 : tree rl_arg, tree rr_arg,
8373 : tree *separatep)
8374 : {
8375 : /* If this is the "or" of two comparisons, we can do something if
8376 : the comparisons are NE_EXPR. If this is the "and", we can do something
8377 : if the comparisons are EQ_EXPR. I.e.,
8378 : (a->b == 2 && a->c == 4) can become (a->new == NEW).
8379 :
8380 : WANTED_CODE is this operation code. For single bit fields, we can
8381 : convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
8382 : comparison for one-bit fields. */
8383 :
8384 438267 : enum tree_code orig_code = code;
8385 438267 : enum tree_code wanted_code;
8386 438267 : tree ll_inner, lr_inner, rl_inner, rr_inner;
8387 438267 : gimple *ll_load, *lr_load, *rl_load, *rr_load;
8388 438267 : HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
8389 438267 : HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
8390 438267 : HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
8391 438267 : HOST_WIDE_INT lnbitsize, lnbitpos, lnprec;
8392 438267 : HOST_WIDE_INT rnbitsize, rnbitpos, rnprec;
8393 438267 : bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
8394 438267 : bool ll_reversep, lr_reversep, rl_reversep, rr_reversep;
8395 438267 : bool ll_signbit, lr_signbit, rl_signbit, rr_signbit;
8396 438267 : scalar_int_mode lnmode, lnmode2, rnmode;
8397 438267 : wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
8398 438267 : wide_int l_const, r_const;
8399 438267 : tree lntype, rntype, result;
8400 438267 : HOST_WIDE_INT first_bit, end_bit;
8401 438267 : bool volatilep;
8402 438267 : bool l_split_load;
8403 :
8404 : /* These are indexed by: conv, mask, shft, load. */
8405 438267 : location_t ll_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8406 438267 : location_t lr_loc[4] = { lloc, lloc, lloc, UNKNOWN_LOCATION };
8407 438267 : location_t rl_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8408 438267 : location_t rr_loc[4] = { rloc, rloc, rloc, UNKNOWN_LOCATION };
8409 :
8410 438267 : gcc_checking_assert (!separatep || !*separatep);
8411 :
8412 : /* Start by getting the comparison codes. Fail if anything is volatile.
8413 : If one operand is a BIT_AND_EXPR with the constant one, treat it as if
8414 : it were surrounded with a NE_EXPR. */
8415 :
8416 438267 : if (TREE_CODE_CLASS (lcode) != tcc_comparison
8417 438267 : || TREE_CODE_CLASS (rcode) != tcc_comparison)
8418 : return 0;
8419 :
8420 : /* We don't normally find TRUTH_*IF_EXPR in gimple, but these codes may be
8421 : given by our caller to denote conditions from different blocks. */
8422 438267 : switch (code)
8423 : {
8424 : case TRUTH_AND_EXPR:
8425 : case TRUTH_ANDIF_EXPR:
8426 : code = TRUTH_AND_EXPR;
8427 : break;
8428 :
8429 0 : case TRUTH_OR_EXPR:
8430 0 : case TRUTH_ORIF_EXPR:
8431 0 : code = TRUTH_OR_EXPR;
8432 0 : break;
8433 :
8434 : default:
8435 : return 0;
8436 : }
8437 :
8438 : /* Prepare to turn compares of signed quantities with zero into sign-bit
8439 : tests. We need not worry about *_reversep here for these compare
8440 : rewrites: loads will have already been reversed before compares. Save the
8441 : precision, because [lr]l_arg may change and we won't be able to tell how
8442 : wide it was originally. */
8443 438267 : unsigned lsignbit = 0, rsignbit = 0;
8444 438267 : if ((lcode == LT_EXPR || lcode == GE_EXPR)
8445 15885 : && integer_zerop (lr_arg)
8446 3692 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8447 441959 : && !TYPE_UNSIGNED (TREE_TYPE (ll_arg)))
8448 : {
8449 3692 : lsignbit = TYPE_PRECISION (TREE_TYPE (ll_arg));
8450 3692 : lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8451 : }
8452 : /* Turn compares of unsigned quantities with powers of two into
8453 : equality tests of masks. */
8454 434575 : else if ((lcode == LT_EXPR || lcode == GE_EXPR)
8455 12193 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8456 11435 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8457 8301 : && TREE_CODE (lr_arg) == INTEGER_CST
8458 434575 : && wi::popcount (wi::to_wide (lr_arg)) == 1)
8459 : {
8460 0 : ll_and_mask = ~(wi::to_wide (lr_arg) - 1);
8461 0 : lcode = (lcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8462 0 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8463 : }
8464 : /* Turn compares of unsigned quantities with powers of two minus one
8465 : into equality tests of masks. */
8466 869150 : else if ((lcode == LE_EXPR || lcode == GT_EXPR)
8467 34025 : && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg))
8468 33794 : && TYPE_UNSIGNED (TREE_TYPE (ll_arg))
8469 27203 : && TREE_CODE (lr_arg) == INTEGER_CST
8470 903175 : && wi::popcount (wi::to_wide (lr_arg) + 1) == 1)
8471 : {
8472 4091 : ll_and_mask = ~wi::to_wide (lr_arg);
8473 4091 : lcode = (lcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8474 4091 : lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0);
8475 : }
8476 : /* Likewise for the second compare. */
8477 438267 : if ((rcode == LT_EXPR || rcode == GE_EXPR)
8478 22104 : && integer_zerop (rr_arg)
8479 2415 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8480 440682 : && !TYPE_UNSIGNED (TREE_TYPE (rl_arg)))
8481 : {
8482 2415 : rsignbit = TYPE_PRECISION (TREE_TYPE (rl_arg));
8483 2415 : rcode = (rcode == LT_EXPR ? NE_EXPR : EQ_EXPR);
8484 : }
8485 435852 : else if ((rcode == LT_EXPR || rcode == GE_EXPR)
8486 19689 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8487 18558 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8488 3755 : && TREE_CODE (rr_arg) == INTEGER_CST
8489 435852 : && wi::popcount (wi::to_wide (rr_arg)) == 1)
8490 : {
8491 0 : rl_and_mask = ~(wi::to_wide (rr_arg) - 1);
8492 0 : rcode = (rcode == GE_EXPR ? NE_EXPR : EQ_EXPR);
8493 0 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8494 : }
8495 871704 : else if ((rcode == LE_EXPR || rcode == GT_EXPR)
8496 43999 : && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg))
8497 43716 : && TYPE_UNSIGNED (TREE_TYPE (rl_arg))
8498 31875 : && TREE_CODE (rr_arg) == INTEGER_CST
8499 915703 : && wi::popcount (wi::to_wide (rr_arg) + 1) == 1)
8500 : {
8501 3391 : rl_and_mask = ~wi::to_wide (rr_arg);
8502 3391 : rcode = (rcode == GT_EXPR ? NE_EXPR : EQ_EXPR);
8503 3391 : rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0);
8504 : }
8505 :
8506 : /* See if the comparisons can be merged. Then get all the parameters for
8507 : each side. */
8508 :
8509 438267 : if ((lcode != EQ_EXPR && lcode != NE_EXPR)
8510 395020 : || (rcode != EQ_EXPR && rcode != NE_EXPR))
8511 : return 0;
8512 :
8513 367657 : ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
8514 367657 : volatilep = 0;
8515 367657 : bool l_xor = false, r_xor = false;
8516 367657 : ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos,
8517 : &ll_unsignedp, &ll_reversep, &volatilep,
8518 : &ll_and_mask, &ll_signbit,
8519 : &l_xor, &lr_arg, &lr_and_mask,
8520 : &ll_load, ll_loc);
8521 367657 : if (!ll_inner)
8522 : return 0;
8523 278009 : lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos,
8524 : &lr_unsignedp, &lr_reversep, &volatilep,
8525 : &lr_and_mask, &lr_signbit, &l_xor, 0, 0,
8526 : &lr_load, lr_loc);
8527 278009 : if (!lr_inner)
8528 : return 0;
8529 273676 : rl_inner = decode_field_reference (&rl_arg, &rl_bitsize, &rl_bitpos,
8530 : &rl_unsignedp, &rl_reversep, &volatilep,
8531 : &rl_and_mask, &rl_signbit,
8532 : &r_xor, &rr_arg, &rr_and_mask,
8533 : &rl_load, rl_loc);
8534 273676 : if (!rl_inner)
8535 : return 0;
8536 255586 : rr_inner = decode_field_reference (&rr_arg, &rr_bitsize, &rr_bitpos,
8537 : &rr_unsignedp, &rr_reversep, &volatilep,
8538 : &rr_and_mask, &rr_signbit, &r_xor, 0, 0,
8539 : &rr_load, rr_loc);
8540 255586 : if (!rr_inner)
8541 : return 0;
8542 :
8543 : /* It must be true that the inner operation on the lhs of each
8544 : comparison must be the same if we are to be able to do anything.
8545 : Then see if we have constants. If not, the same must be true for
8546 : the rhs's. If one is a load and the other isn't, we have to be
8547 : conservative and avoid the optimization, otherwise we could get
8548 : SRAed fields wrong. */
8549 253225 : if (volatilep)
8550 : return 0;
8551 :
8552 253224 : if (ll_reversep != rl_reversep
8553 253224 : || ! operand_equal_p (ll_inner, rl_inner, 0))
8554 : {
8555 : /* Try swapping the operands. */
8556 195905 : if (ll_reversep != rr_reversep || rsignbit
8557 391114 : || !operand_equal_p (ll_inner, rr_inner, 0))
8558 194069 : return 0;
8559 :
8560 1937 : rcode = swap_tree_comparison (rcode);
8561 1937 : std::swap (rl_arg, rr_arg);
8562 1937 : std::swap (rl_inner, rr_inner);
8563 1937 : std::swap (rl_bitsize, rr_bitsize);
8564 1937 : std::swap (rl_bitpos, rr_bitpos);
8565 1937 : std::swap (rl_unsignedp, rr_unsignedp);
8566 1937 : std::swap (rl_reversep, rr_reversep);
8567 1937 : std::swap (rl_and_mask, rr_and_mask);
8568 1937 : std::swap (rl_signbit, rr_signbit);
8569 1937 : std::swap (rl_load, rr_load);
8570 1937 : std::swap (rl_loc, rr_loc);
8571 : }
8572 :
8573 116092 : if ((ll_load && rl_load)
8574 229966 : ? gimple_vuse (ll_load) != gimple_vuse (rl_load)
8575 2218 : : (!ll_load != !rl_load))
8576 : return 0;
8577 :
8578 : /* ??? Can we do anything with these? */
8579 58395 : if (lr_signbit || rr_signbit)
8580 : return 0;
8581 :
8582 : /* If the mask encompassed extensions of the sign bit before
8583 : clipping, try to include the sign bit in the test. If we're not
8584 : comparing with zero, don't even try to deal with it (for now?).
8585 : If we've already committed to a sign test, the extended (before
8586 : clipping) mask could already be messing with it. */
8587 58395 : if (ll_signbit)
8588 : {
8589 4 : if (!integer_zerop (lr_arg) || lsignbit)
8590 0 : return 0;
8591 4 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8592 4 : if (!ll_and_mask.get_precision ())
8593 0 : ll_and_mask = sign;
8594 : else
8595 4 : ll_and_mask |= sign;
8596 4 : }
8597 :
8598 58395 : if (rl_signbit)
8599 : {
8600 4 : if (!integer_zerop (rr_arg) || rsignbit)
8601 1 : return 0;
8602 3 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8603 3 : if (!rl_and_mask.get_precision ())
8604 0 : rl_and_mask = sign;
8605 : else
8606 3 : rl_and_mask |= sign;
8607 3 : }
8608 :
8609 58394 : if (TREE_CODE (lr_arg) == INTEGER_CST
8610 46317 : && TREE_CODE (rr_arg) == INTEGER_CST)
8611 : {
8612 45745 : l_const = wi::to_wide (lr_arg);
8613 : /* We don't expect masks on constants, but if there are any, apply
8614 : them now. */
8615 45745 : if (lr_and_mask.get_precision ())
8616 0 : l_const &= wide_int::from (lr_and_mask,
8617 0 : l_const.get_precision (), UNSIGNED);
8618 45745 : r_const = wi::to_wide (rr_arg);
8619 45745 : if (rr_and_mask.get_precision ())
8620 0 : r_const &= wide_int::from (rr_and_mask,
8621 0 : r_const.get_precision (), UNSIGNED);
8622 45745 : lr_reversep = ll_reversep;
8623 : }
8624 12649 : else if (lr_reversep != rr_reversep
8625 12641 : || ! operand_equal_p (lr_inner, rr_inner, 0)
8626 22018 : || ((lr_load && rr_load)
8627 27933 : ? gimple_vuse (lr_load) != gimple_vuse (rr_load)
8628 58 : : (!lr_load != !rr_load)))
8629 3519 : return 0;
8630 :
8631 : /* If we found sign tests, finish turning them into bit tests. */
8632 :
8633 54875 : if (lsignbit)
8634 : {
8635 54 : wide_int sign = wi::mask (ll_bitsize - 1, true, ll_bitsize);
8636 : /* If ll_arg is zero-extended and we're testing the sign bit, we know
8637 : what the result should be. Shifting the sign bit out of sign will get
8638 : us to mask the entire field out, yielding zero, i.e., the sign bit of
8639 : the zero-extended value. We know the masked value is being compared
8640 : with zero, so the compare will get us the result we're looking
8641 : for: TRUE if EQ_EXPR, FALSE if NE_EXPR. */
8642 54 : if (lsignbit > ll_bitsize && ll_unsignedp)
8643 1 : sign <<= 1;
8644 54 : if (!ll_and_mask.get_precision ())
8645 53 : ll_and_mask = sign;
8646 : else
8647 1 : ll_and_mask &= sign;
8648 54 : if (l_xor)
8649 : {
8650 1 : if (ll_bitsize != lr_bitsize)
8651 1 : return 0;
8652 0 : if (!lr_and_mask.get_precision ())
8653 0 : lr_and_mask = sign;
8654 : else
8655 0 : lr_and_mask &= sign;
8656 0 : if (l_const.get_precision ())
8657 0 : l_const &= wide_int::from (lr_and_mask,
8658 0 : l_const.get_precision (), UNSIGNED);
8659 : }
8660 54 : }
8661 :
8662 54874 : if (rsignbit)
8663 : {
8664 171 : wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
8665 171 : if (rsignbit > rl_bitsize && rl_unsignedp)
8666 0 : sign <<= 1;
8667 171 : if (!rl_and_mask.get_precision ())
8668 171 : rl_and_mask = sign;
8669 : else
8670 0 : rl_and_mask &= sign;
8671 171 : if (r_xor)
8672 : {
8673 16 : if (rl_bitsize != rr_bitsize)
8674 0 : return 0;
8675 16 : if (!rr_and_mask.get_precision ())
8676 16 : rr_and_mask = sign;
8677 : else
8678 0 : rr_and_mask &= sign;
8679 16 : if (r_const.get_precision ())
8680 24 : r_const &= wide_int::from (rr_and_mask,
8681 12 : r_const.get_precision (), UNSIGNED);
8682 : }
8683 171 : }
8684 :
8685 : /* If either comparison code is not correct for our logical operation,
8686 : fail. However, we can convert a one-bit comparison against zero into
8687 : the opposite comparison against that bit being set in the field. */
8688 :
8689 54874 : wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
8690 54874 : if (lcode != wanted_code)
8691 : {
8692 5079 : if (l_const.get_precision ()
8693 4905 : && l_const == 0
8694 1663 : && ll_and_mask.get_precision ()
8695 5472 : && wi::popcount (ll_and_mask) == 1)
8696 : {
8697 : /* Make the left operand unsigned, since we are only interested
8698 : in the value of one bit. Otherwise we are doing the wrong
8699 : thing below. */
8700 235 : ll_unsignedp = 1;
8701 235 : l_const = ll_and_mask;
8702 : }
8703 : else
8704 4844 : return 0;
8705 : }
8706 :
8707 : /* This is analogous to the code for l_const above. */
8708 50030 : if (rcode != wanted_code)
8709 : {
8710 982 : if (r_const.get_precision ()
8711 982 : && r_const == 0
8712 943 : && rl_and_mask.get_precision ()
8713 1849 : && wi::popcount (rl_and_mask) == 1)
8714 : {
8715 534 : rl_unsignedp = 1;
8716 534 : r_const = rl_and_mask;
8717 : }
8718 : else
8719 448 : return 0;
8720 : }
8721 :
8722 : /* This will be bumped to 2 if any of the field pairs crosses an
8723 : alignment boundary, so the merged compare has to be done in two
8724 : parts. */
8725 148746 : int parts = 1;
8726 : /* Set to true if the second combined compare should come first,
8727 : e.g., because the second original compare accesses a word that
8728 : the first one doesn't, and the combined compares access those in
8729 : cmp[0]. */
8730 148746 : bool first1 = false;
8731 : /* Set to true if the first original compare is not the one being
8732 : split. */
8733 148746 : bool maybe_separate = false;
8734 :
8735 : /* The following 2-dimensional arrays use the first index to
8736 : identify left(0)- vs right(1)-hand compare operands, and the
8737 : second one to identify merged compare parts. */
8738 : /* The memory loads or constants to be compared. */
8739 : tree ld_arg[2][2];
8740 : /* The first bit of the corresponding inner object that the
8741 : corresponding LD_ARG covers. */
8742 : HOST_WIDE_INT bitpos[2][2];
8743 : /* The bit count starting at BITPOS that the corresponding LD_ARG
8744 : covers. */
8745 : HOST_WIDE_INT bitsiz[2][2];
8746 : /* The number of bits by which LD_ARG has already been shifted
8747 : right, WRT mask. */
8748 : HOST_WIDE_INT shifted[2][2];
8749 : /* The number of bits by which both LD_ARG and MASK need shifting to
8750 : bring its least-significant bit to bit zero. */
8751 : HOST_WIDE_INT toshift[2][2];
8752 : /* An additional mask to be applied to LD_ARG, to remove any bits
8753 : that may have been loaded for use in another compare, but that
8754 : don't belong in the corresponding compare. */
8755 594984 : wide_int xmask[2][2] = {};
8756 :
8757 : /* The combined compare or compares. */
8758 49582 : tree cmp[2];
8759 :
8760 : /* Consider we're comparing two non-contiguous fields of packed
8761 : structs, both aligned at 32-bit boundaries:
8762 :
8763 : ll_arg: an 8-bit field at offset 0
8764 : lr_arg: a 16-bit field at offset 2
8765 :
8766 : rl_arg: an 8-bit field at offset 1
8767 : rr_arg: a 16-bit field at offset 3
8768 :
8769 : We'll have r_split_load, because rr_arg straddles across an
8770 : alignment boundary.
8771 :
8772 : We'll want to have:
8773 :
8774 : bitpos = { { 0, 0 }, { 0, 32 } }
8775 : bitsiz = { { 32, 32 }, { 32, 8 } }
8776 :
8777 : And, for little-endian:
8778 :
8779 : shifted = { { 0, 0 }, { 0, 32 } }
8780 : toshift = { { 0, 24 }, { 0, 0 } }
8781 :
8782 : Or, for big-endian:
8783 :
8784 : shifted = { { 0, 0 }, { 8, 0 } }
8785 : toshift = { { 8, 0 }, { 0, 0 } }
8786 : */
8787 :
8788 : /* See if we can find a mode that contains both fields being compared on
8789 : the left. If we can't, fail. Otherwise, update all constants and masks
8790 : to be relative to a field of that size. */
8791 49582 : first_bit = MIN (ll_bitpos, rl_bitpos);
8792 49582 : end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
8793 49582 : HOST_WIDE_INT ll_align = TYPE_ALIGN (TREE_TYPE (ll_inner));
8794 49582 : poly_uint64 ll_end_region = 0;
8795 49582 : if (TYPE_SIZE (TREE_TYPE (ll_inner))
8796 49582 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (ll_inner))))
8797 49582 : ll_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (ll_inner)));
8798 49582 : if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region,
8799 49582 : ll_align, BITS_PER_WORD, volatilep, &lnmode))
8800 : l_split_load = false;
8801 : /* ??? If ll and rl share the same load, reuse that?
8802 : See PR 118206 -> gcc.dg/field-merge-18.c */
8803 : else
8804 : {
8805 : /* Consider the possibility of recombining loads if any of the
8806 : fields straddles across an alignment boundary, so that either
8807 : part can be loaded along with the other field. Since we
8808 : limit access modes to BITS_PER_WORD, don't exceed that,
8809 : otherwise on a 32-bit host and a 64-bit-aligned data
8810 : structure, we'll fail the above for a field that straddles
8811 : across two words, and would fail here for not even trying to
8812 : split it at between 32-bit words. */
8813 46384 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
8814 49234 : (MIN (ll_align, BITS_PER_WORD),
8815 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8816 :
8817 46384 : if (boundary < 0
8818 219 : || !get_best_mode (boundary - first_bit, first_bit, 0, ll_end_region,
8819 : ll_align, BITS_PER_WORD, volatilep, &lnmode)
8820 46561 : || !get_best_mode (end_bit - boundary, boundary, 0, ll_end_region,
8821 177 : ll_align, BITS_PER_WORD, volatilep, &lnmode2))
8822 : {
8823 49015 : if (ll_align <= BITS_PER_WORD)
8824 : return 0;
8825 :
8826 : /* As a last resort, try double-word access modes. This
8827 : enables us to deal with misaligned double-word fields
8828 : that straddle across 3 separate words. */
8829 1859 : boundary = compute_split_boundary_from_align
8830 1951 : (MIN (ll_align, 2 * BITS_PER_WORD),
8831 : ll_bitpos, ll_bitsize, rl_bitpos, rl_bitsize);
8832 1859 : if (boundary < 0
8833 0 : || !get_best_mode (boundary - first_bit, first_bit,
8834 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8835 : volatilep, &lnmode)
8836 1859 : || !get_best_mode (end_bit - boundary, boundary,
8837 0 : 0, ll_end_region, ll_align, 2 * BITS_PER_WORD,
8838 : volatilep, &lnmode2))
8839 1859 : return 0;
8840 : }
8841 :
8842 : /* If we can't have a single load, but can with two, figure out whether
8843 : the two compares can be separated, i.e., whether the entirety of the
8844 : first original compare is encompassed by the entirety of the first
8845 : combined compare. If the first original compare is past the alignment
8846 : boundary, arrange to compare that range first, by setting first1
8847 : (meaning make cmp[1] first, instead of cmp[0]). */
8848 177 : l_split_load = true;
8849 177 : parts = 2;
8850 177 : if (ll_bitpos >= boundary)
8851 : maybe_separate = first1 = true;
8852 132 : else if (ll_bitpos + ll_bitsize <= boundary)
8853 32 : maybe_separate = true;
8854 : }
8855 :
8856 3375 : lnbitsize = GET_MODE_BITSIZE (lnmode);
8857 3375 : lnbitpos = first_bit & ~ (lnbitsize - 1);
8858 : /* Avoid situations that the code below can't handle. */
8859 3375 : if (lnbitpos < 0)
8860 : return 0;
8861 :
8862 : /* Choose the type for the combined compare. Even if we're splitting loads,
8863 : make it wide enough to hold both. */
8864 3375 : if (l_split_load)
8865 354 : lnbitsize += GET_MODE_BITSIZE (lnmode2);
8866 3375 : lntype = build_nonstandard_integer_type (lnbitsize, 1);
8867 3375 : if (!lntype)
8868 : return NULL_TREE;
8869 3375 : lnprec = TYPE_PRECISION (lntype);
8870 3375 : xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
8871 :
8872 : /* Adjust bit ranges for reverse endianness. */
8873 3375 : if (ll_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
8874 : {
8875 6 : xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
8876 6 : xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
8877 : }
8878 :
8879 : /* Adjust masks to match the positions in the combined lntype. */
8880 6750 : wide_int ll_mask, rl_mask, r_mask;
8881 3375 : if (ll_and_mask.get_precision ())
8882 4300 : ll_mask = wi::lshift (wide_int::from (ll_and_mask, lnprec, UNSIGNED),
8883 2150 : xll_bitpos);
8884 : else
8885 1225 : ll_mask = wi::shifted_mask (xll_bitpos, ll_bitsize, false, lnprec);
8886 3375 : if (rl_and_mask.get_precision ())
8887 3968 : rl_mask = wi::lshift (wide_int::from (rl_and_mask, lnprec, UNSIGNED),
8888 1984 : xrl_bitpos);
8889 : else
8890 1391 : rl_mask = wi::shifted_mask (xrl_bitpos, rl_bitsize, false, lnprec);
8891 :
8892 : /* When we set l_const, we also set r_const. */
8893 3375 : gcc_checking_assert (!l_const.get_precision () == !r_const.get_precision ());
8894 :
8895 : /* Adjust right-hand constants in both original comparisons to match width
8896 : and bit position. */
8897 3375 : if (l_const.get_precision ())
8898 : {
8899 : /* Before clipping upper bits of the right-hand operand of the compare,
8900 : check that they're sign or zero extensions, depending on how the
8901 : left-hand operand would be extended. If it is unsigned, or if there's
8902 : a mask that zeroes out extension bits, whether because we've checked
8903 : for upper bits in the mask and did not set ll_signbit, or because the
8904 : sign bit itself is masked out, check that the right-hand operand is
8905 : zero-extended. */
8906 1983 : bool l_non_ext_bits = false;
8907 1983 : if (ll_bitsize < lr_bitsize)
8908 : {
8909 44 : wide_int zext = wi::zext (l_const, ll_bitsize);
8910 88 : if ((ll_unsignedp
8911 32 : || (ll_and_mask.get_precision ()
8912 4 : && (!ll_signbit
8913 52 : || ((ll_and_mask & wi::mask (ll_bitsize - 1, true, ll_bitsize))
8914 8 : == 0)))
8915 164 : ? zext : wi::sext (l_const, ll_bitsize)) == l_const)
8916 44 : l_const = zext;
8917 : else
8918 : l_non_ext_bits = true;
8919 44 : }
8920 : /* We're doing bitwise equality tests, so don't bother with sign
8921 : extensions. */
8922 1983 : l_const = wide_int::from (l_const, lnprec, UNSIGNED);
8923 1983 : if (ll_and_mask.get_precision ())
8924 1163 : l_const &= wide_int::from (ll_and_mask, lnprec, UNSIGNED);
8925 1983 : l_const <<= xll_bitpos;
8926 5949 : if (l_non_ext_bits || (l_const & ~ll_mask) != 0)
8927 : {
8928 0 : warning_at (lloc, OPT_Wtautological_compare,
8929 : "comparison is always %d", wanted_code == NE_EXPR);
8930 :
8931 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
8932 : }
8933 :
8934 : /* Before clipping upper bits of the right-hand operand of the compare,
8935 : check that they're sign or zero extensions, depending on how the
8936 : left-hand operand would be extended. */
8937 1983 : bool r_non_ext_bits = false;
8938 1983 : if (rl_bitsize < rr_bitsize)
8939 : {
8940 15 : wide_int zext = wi::zext (r_const, rl_bitsize);
8941 30 : if ((rl_unsignedp
8942 11 : || (rl_and_mask.get_precision ()
8943 4 : && (!rl_signbit
8944 21 : || ((rl_and_mask & wi::mask (rl_bitsize - 1, true, rl_bitsize))
8945 6 : == 0)))
8946 56 : ? zext : wi::sext (r_const, rl_bitsize)) == r_const)
8947 15 : r_const = zext;
8948 : else
8949 : r_non_ext_bits = true;
8950 15 : }
8951 1983 : r_const = wide_int::from (r_const, lnprec, UNSIGNED);
8952 1983 : if (rl_and_mask.get_precision ())
8953 1038 : r_const &= wide_int::from (rl_and_mask, lnprec, UNSIGNED);
8954 1983 : r_const <<= xrl_bitpos;
8955 5949 : if (r_non_ext_bits || (r_const & ~rl_mask) != 0)
8956 : {
8957 0 : warning_at (rloc, OPT_Wtautological_compare,
8958 : "comparison is always %d", wanted_code == NE_EXPR);
8959 :
8960 0 : return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
8961 : }
8962 :
8963 : /* If there is something in common between the masks, those bits of the
8964 : constants must be the same. If not, the combined condition cannot be
8965 : met, and the result is known. Test for this to avoid generating
8966 : incorrect code below. */
8967 1983 : wide_int mask = ll_mask & rl_mask;
8968 1983 : if (mask != 0
8969 2031 : && (l_const & mask) != (r_const & mask))
8970 : {
8971 0 : if (wanted_code == NE_EXPR)
8972 0 : return constant_boolean_node (true, truth_type);
8973 : else
8974 0 : return constant_boolean_node (false, truth_type);
8975 : }
8976 :
8977 : /* The constants are combined so as to line up with the loaded field, so
8978 : tentatively use the same parameters for the second combined
8979 : compare. */
8980 1983 : ld_arg[1][0] = wide_int_to_tree (lntype, l_const | r_const);
8981 1983 : toshift[1][0] = MIN (xll_bitpos, xrl_bitpos);
8982 1983 : shifted[1][0] = 0;
8983 1983 : bitpos[1][0] = lnbitpos;
8984 1983 : bitsiz[1][0] = lnbitsize;
8985 :
8986 1983 : if (parts > 1)
8987 49 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
8988 : shifted[1], xmask[1],
8989 49 : lnbitpos + GET_MODE_BITSIZE (lnmode),
8990 : lr_reversep);
8991 :
8992 : /* No masking needed, we know the full constants. */
8993 1983 : r_mask = wi::mask (0, true, lnprec);
8994 :
8995 : /* If the compiler thinks this is used uninitialized below, it's
8996 : because it can't realize that parts can only be 2 when
8997 : comparing with constants if l_split_load is also true. This
8998 : just silences the warning. */
8999 1983 : rnbitpos = 0;
9000 1983 : }
9001 :
9002 : /* Likewise, if the right sides are not constant, align them for the combined
9003 : compare. Also, disallow this optimization if a size, signedness or
9004 : storage order mismatch occurs between the left and right sides. */
9005 : else
9006 : {
9007 1392 : if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
9008 1306 : || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
9009 1306 : || ll_reversep != lr_reversep
9010 : /* Make sure the two fields on the right
9011 : correspond to the left without being swapped. */
9012 1306 : || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
9013 217 : return 0;
9014 :
9015 1183 : bool r_split_load;
9016 1183 : scalar_int_mode rnmode2;
9017 :
9018 : /* Figure out how to load the bits for the right-hand size of the
9019 : combined compare. As in the left-hand size, we may have to split it,
9020 : and then we use two separate compares. */
9021 1183 : first_bit = MIN (lr_bitpos, rr_bitpos);
9022 1183 : end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
9023 1183 : HOST_WIDE_INT lr_align = TYPE_ALIGN (TREE_TYPE (lr_inner));
9024 1183 : poly_uint64 lr_end_region = 0;
9025 1183 : if (TYPE_SIZE (TREE_TYPE (lr_inner))
9026 1183 : && tree_fits_poly_uint64_p (TYPE_SIZE (TREE_TYPE (lr_inner))))
9027 1183 : lr_end_region = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (lr_inner)));
9028 1183 : if (!get_best_mode (end_bit - first_bit, first_bit, 0, lr_end_region,
9029 1183 : lr_align, BITS_PER_WORD, volatilep, &rnmode))
9030 : {
9031 : /* Consider the possibility of recombining loads if any of the
9032 : fields straddles across an alignment boundary, so that either
9033 : part can be loaded along with the other field. */
9034 138 : HOST_WIDE_INT boundary = compute_split_boundary_from_align
9035 138 : (lr_align, lr_bitpos, lr_bitsize, rr_bitpos, rr_bitsize);
9036 :
9037 138 : if (boundary < 0
9038 : /* If we're to split both, make sure the split point is
9039 : the same. */
9040 130 : || (l_split_load
9041 128 : && (boundary - lr_bitpos
9042 128 : != (lnbitpos + GET_MODE_BITSIZE (lnmode)) - ll_bitpos))
9043 130 : || !get_best_mode (boundary - first_bit, first_bit,
9044 : 0, lr_end_region,
9045 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode)
9046 268 : || !get_best_mode (end_bit - boundary, boundary, 0, lr_end_region,
9047 130 : lr_align, BITS_PER_WORD, volatilep, &rnmode2))
9048 8 : return 0;
9049 :
9050 130 : r_split_load = true;
9051 130 : parts = 2;
9052 130 : if (lr_bitpos >= boundary)
9053 : maybe_separate = first1 = true;
9054 88 : else if (lr_bitpos + lr_bitsize <= boundary)
9055 29 : maybe_separate = true;
9056 : }
9057 : else
9058 : r_split_load = false;
9059 :
9060 : /* Find a type that can hold the entire right-hand operand. */
9061 1175 : rnbitsize = GET_MODE_BITSIZE (rnmode);
9062 1175 : rnbitpos = first_bit & ~ (rnbitsize - 1);
9063 1175 : if (r_split_load)
9064 260 : rnbitsize += GET_MODE_BITSIZE (rnmode2);
9065 1175 : rntype = build_nonstandard_integer_type (rnbitsize, 1);
9066 1175 : if (!rntype)
9067 : return 0;
9068 1175 : rnprec = TYPE_PRECISION (rntype);
9069 1175 : xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
9070 :
9071 : /* Adjust for reversed endianness. */
9072 1175 : if (lr_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
9073 : {
9074 0 : xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
9075 0 : xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
9076 : }
9077 :
9078 : /* Adjust the masks to match the combined type, and combine them. */
9079 1175 : wide_int lr_mask, rr_mask;
9080 1175 : if (lr_and_mask.get_precision ())
9081 1972 : lr_mask = wi::lshift (wide_int::from (lr_and_mask, rnprec, UNSIGNED),
9082 986 : xlr_bitpos);
9083 : else
9084 189 : lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec);
9085 1175 : if (rr_and_mask.get_precision ())
9086 1890 : rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED),
9087 945 : xrr_bitpos);
9088 : else
9089 230 : rr_mask = wi::shifted_mask (xrr_bitpos, rr_bitsize, false, rnprec);
9090 1175 : r_mask = lr_mask | rr_mask;
9091 :
9092 : /* Load the right-hand operand of the combined compare. */
9093 1175 : toshift[1][0] = MIN (xlr_bitpos, xrr_bitpos);
9094 1175 : shifted[1][0] = 0;
9095 :
9096 1175 : if (!r_split_load)
9097 : {
9098 1045 : bitpos[1][0] = rnbitpos;
9099 1045 : bitsiz[1][0] = rnbitsize;
9100 1045 : ld_arg[1][0] = make_bit_field_load (ll_loc[3], lr_inner, lr_arg,
9101 1045 : rntype, rnbitsize, rnbitpos,
9102 1045 : lr_unsignedp || rr_unsignedp,
9103 : lr_reversep, lr_load);
9104 : }
9105 :
9106 : /* ... and the second part of the right-hand operand if needed. */
9107 1175 : if (parts > 1)
9108 : {
9109 130 : if (r_split_load)
9110 : {
9111 130 : gimple *point[2];
9112 130 : point[0] = lr_load;
9113 130 : point[1] = rr_load;
9114 130 : build_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9115 : shifted[1], rl_loc[3], lr_inner, lr_arg,
9116 : rnmode, rnmode2, rnbitpos, lr_reversep, point);
9117 : }
9118 : else
9119 0 : reuse_split_load (ld_arg[1], bitpos[1], bitsiz[1], toshift[1],
9120 : shifted[1], xmask[1],
9121 0 : lnbitpos + GET_MODE_BITSIZE (lnmode)
9122 0 : - ll_bitpos + lr_bitpos, lr_reversep);
9123 : }
9124 1175 : }
9125 :
9126 : /* Now issue the loads for the left-hand combined operand/s. */
9127 6316 : wide_int l_mask = ll_mask | rl_mask;
9128 3158 : toshift[0][0] = MIN (xll_bitpos, xrl_bitpos);
9129 3158 : shifted[0][0] = 0;
9130 :
9131 3158 : if (!l_split_load)
9132 : {
9133 2981 : bitpos[0][0] = lnbitpos;
9134 2981 : bitsiz[0][0] = lnbitsize;
9135 2981 : ld_arg[0][0] = make_bit_field_load (ll_loc[3], ll_inner, ll_arg,
9136 2981 : lntype, lnbitsize, lnbitpos,
9137 2981 : ll_unsignedp || rl_unsignedp,
9138 : ll_reversep, ll_load);
9139 : }
9140 :
9141 3158 : if (parts > 1)
9142 : {
9143 179 : if (l_split_load)
9144 : {
9145 177 : gimple *point[2];
9146 177 : point[0] = ll_load;
9147 177 : point[1] = rl_load;
9148 177 : build_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9149 : shifted[0], rl_loc[3], ll_inner, ll_arg,
9150 : lnmode, lnmode2, lnbitpos, ll_reversep, point);
9151 : }
9152 : else
9153 2 : reuse_split_load (ld_arg[0], bitpos[0], bitsiz[0], toshift[0],
9154 : shifted[0], xmask[0],
9155 2 : rnbitpos + GET_MODE_BITSIZE (rnmode)
9156 2 : - lr_bitpos + ll_bitpos, ll_reversep);
9157 : }
9158 :
9159 : /* Compute the compares. */
9160 6495 : for (int i = 0; i < parts; i++)
9161 : {
9162 3337 : tree op[2] = { ld_arg[0][i], ld_arg[1][i] };
9163 10011 : wide_int mask[2] = { l_mask, r_mask };
9164 3337 : location_t *locs[2] = { i ? rl_loc : ll_loc, i ? rr_loc : lr_loc };
9165 :
9166 : /* Figure out the masks, and unshare the original operands. */
9167 10011 : for (int j = 0; j < 2; j++)
9168 : {
9169 6674 : unsigned prec = TYPE_PRECISION (TREE_TYPE (op[j]));
9170 6674 : op[j] = unshare_expr (op[j]);
9171 :
9172 : /* Mask out the bits belonging to the other part. */
9173 6674 : if (xmask[j][i].get_precision ())
9174 102 : mask[j] &= xmask[j][i];
9175 :
9176 6674 : if (shifted[j][i])
9177 : {
9178 307 : wide_int shift = wide_int::from (shifted[j][i], prec, UNSIGNED);
9179 307 : mask[j] = wi::lrshift (mask[j], shift);
9180 307 : }
9181 6674 : mask[j] = wide_int::from (mask[j], prec, UNSIGNED);
9182 : }
9183 :
9184 : /* Line up the operands for a compare. */
9185 3337 : HOST_WIDE_INT shift = (toshift[0][i] - toshift[1][i]);
9186 :
9187 3337 : if (shift)
9188 : {
9189 54 : int j;
9190 54 : if (shift > 0)
9191 : j = 0;
9192 : else
9193 : {
9194 52 : j = 1;
9195 52 : shift = -shift;
9196 : }
9197 :
9198 54 : tree shiftsz = bitsize_int (shift);
9199 54 : op[j] = fold_build2_loc (locs[j][1], RSHIFT_EXPR, TREE_TYPE (op[j]),
9200 : op[j], shiftsz);
9201 54 : mask[j] = wi::lrshift (mask[j], shift);
9202 : }
9203 :
9204 : /* Convert to the smaller type before masking out unwanted
9205 : bits. */
9206 3337 : tree type = TREE_TYPE (op[0]);
9207 3337 : if (type != TREE_TYPE (op[1]))
9208 : {
9209 188 : int j = (TYPE_PRECISION (type)
9210 188 : < TYPE_PRECISION (TREE_TYPE (op[1])));
9211 188 : if (!j)
9212 89 : type = TREE_TYPE (op[1]);
9213 188 : op[j] = fold_convert_loc (locs[j][0], type, op[j]);
9214 188 : mask[j] = wide_int::from (mask[j], TYPE_PRECISION (type), UNSIGNED);
9215 : }
9216 :
9217 : /* Apply masks. */
9218 10011 : for (int j = 0; j < 2; j++)
9219 6674 : if (mask[j] != wi::mask (0, true, mask[j].get_precision ()))
9220 2688 : op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type,
9221 5376 : op[j], wide_int_to_tree (type, mask[j]));
9222 :
9223 6495 : cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type,
9224 : op[0], op[1]);
9225 10011 : }
9226 :
9227 : /* Reorder the compares if needed. */
9228 3158 : if (first1)
9229 45 : std::swap (cmp[0], cmp[1]);
9230 :
9231 : /* Prepare to return the resulting compares. Combine two parts if
9232 : needed. */
9233 3158 : if (parts == 1)
9234 2979 : result = cmp[0];
9235 179 : else if (!separatep || !maybe_separate)
9236 : {
9237 : /* Only fold if any of the cmp is known, otherwise we may lose the
9238 : sequence point, and that may prevent further optimizations. */
9239 173 : if (TREE_CODE (cmp[0]) == INTEGER_CST
9240 137 : || TREE_CODE (cmp[1]) == INTEGER_CST)
9241 37 : result = fold_build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9242 : else
9243 136 : result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]);
9244 : }
9245 : else
9246 : {
9247 6 : result = cmp[0];
9248 6 : *separatep = cmp[1];
9249 : }
9250 :
9251 3158 : return result;
9252 438267 : }
9253 :
9254 : /* Try to simplify the AND of two comparisons, specified by
9255 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9256 : If this can be simplified to a single expression (without requiring
9257 : introducing more SSA variables to hold intermediate values),
9258 : return the resulting tree. Otherwise return NULL_TREE.
9259 : If the result expression is non-null, it has boolean type. */
9260 :
9261 : tree
9262 633196 : maybe_fold_and_comparisons (tree type,
9263 : enum tree_code code1, tree op1a, tree op1b,
9264 : enum tree_code code2, tree op2a, tree op2b,
9265 : basic_block outer_cond_bb)
9266 : {
9267 633196 : if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9268 : outer_cond_bb))
9269 : return t;
9270 :
9271 631557 : if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b,
9272 : outer_cond_bb))
9273 : return t;
9274 :
9275 631531 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1,
9276 : op1a, op1b, code2, op2a,
9277 : op2b, outer_cond_bb))
9278 : return t;
9279 :
9280 : return NULL_TREE;
9281 : }
9282 :
9283 : /* Helper function for or_comparisons_1: try to simplify the OR of the
9284 : ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
9285 : If INVERT is true, invert the value of VAR before doing the OR.
9286 : Return NULL_EXPR if we can't simplify this to a single expression. */
9287 :
9288 : static tree
9289 63271 : or_var_with_comparison (tree type, tree var, bool invert,
9290 : enum tree_code code2, tree op2a, tree op2b,
9291 : basic_block outer_cond_bb)
9292 : {
9293 63271 : tree t;
9294 63271 : gimple *stmt = SSA_NAME_DEF_STMT (var);
9295 :
9296 : /* We can only deal with variables whose definitions are assignments. */
9297 63271 : if (!is_gimple_assign (stmt))
9298 : return NULL_TREE;
9299 :
9300 : /* If we have an inverted comparison, apply DeMorgan's law and rewrite
9301 : !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
9302 : Then we only have to consider the simpler non-inverted cases. */
9303 63091 : if (invert)
9304 24002 : t = and_var_with_comparison_1 (type, stmt,
9305 : invert_tree_comparison (code2, false),
9306 : op2a, op2b, outer_cond_bb);
9307 : else
9308 39089 : t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b,
9309 : outer_cond_bb);
9310 63091 : return canonicalize_bool (t, invert);
9311 : }
9312 :
9313 : /* Try to simplify the OR of the ssa variable defined by the assignment
9314 : STMT with the comparison specified by (OP2A CODE2 OP2B).
9315 : Return NULL_EXPR if we can't simplify this to a single expression. */
9316 :
9317 : static tree
9318 163473 : or_var_with_comparison_1 (tree type, gimple *stmt,
9319 : enum tree_code code2, tree op2a, tree op2b,
9320 : basic_block outer_cond_bb)
9321 : {
9322 163473 : tree var = gimple_assign_lhs (stmt);
9323 163473 : tree true_test_var = NULL_TREE;
9324 163473 : tree false_test_var = NULL_TREE;
9325 163473 : enum tree_code innercode = gimple_assign_rhs_code (stmt);
9326 :
9327 : /* Check for identities like (var OR (var != 0)) => true . */
9328 163473 : if (TREE_CODE (op2a) == SSA_NAME
9329 163473 : && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
9330 : {
9331 34935 : if ((code2 == NE_EXPR && integer_zerop (op2b))
9332 93096 : || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
9333 : {
9334 28458 : true_test_var = op2a;
9335 28458 : if (var == true_test_var)
9336 : return var;
9337 : }
9338 6428 : else if ((code2 == EQ_EXPR && integer_zerop (op2b))
9339 52748 : || (code2 == NE_EXPR && integer_nonzerop (op2b)))
9340 : {
9341 13070 : false_test_var = op2a;
9342 13070 : if (var == false_test_var)
9343 0 : return boolean_true_node;
9344 : }
9345 : }
9346 :
9347 : /* If the definition is a comparison, recurse on it. */
9348 163473 : if (TREE_CODE_CLASS (innercode) == tcc_comparison)
9349 : {
9350 973 : tree t = or_comparisons_1 (type, innercode,
9351 : gimple_assign_rhs1 (stmt),
9352 : gimple_assign_rhs2 (stmt),
9353 : code2, op2a, op2b, outer_cond_bb);
9354 973 : if (t)
9355 : return t;
9356 : }
9357 :
9358 : /* If the definition is an AND or OR expression, we may be able to
9359 : simplify by reassociating. */
9360 163450 : if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
9361 163450 : && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
9362 : {
9363 73669 : tree inner1 = gimple_assign_rhs1 (stmt);
9364 73669 : tree inner2 = gimple_assign_rhs2 (stmt);
9365 73669 : gimple *s;
9366 73669 : tree t;
9367 73669 : tree partial = NULL_TREE;
9368 73669 : bool is_or = (innercode == BIT_IOR_EXPR);
9369 :
9370 : /* Check for boolean identities that don't require recursive examination
9371 : of inner1/inner2:
9372 : inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
9373 : inner1 OR (inner1 AND inner2) => inner1
9374 : !inner1 OR (inner1 OR inner2) => true
9375 : !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
9376 : */
9377 73669 : if (inner1 == true_test_var)
9378 0 : return (is_or ? var : inner1);
9379 73669 : else if (inner2 == true_test_var)
9380 0 : return (is_or ? var : inner2);
9381 73669 : else if (inner1 == false_test_var)
9382 0 : return (is_or
9383 0 : ? boolean_true_node
9384 0 : : or_var_with_comparison (type, inner2, false, code2, op2a,
9385 0 : op2b, outer_cond_bb));
9386 73669 : else if (inner2 == false_test_var)
9387 0 : return (is_or
9388 0 : ? boolean_true_node
9389 0 : : or_var_with_comparison (type, inner1, false, code2, op2a,
9390 0 : op2b, outer_cond_bb));
9391 :
9392 : /* Next, redistribute/reassociate the OR across the inner tests.
9393 : Compute the first partial result, (inner1 OR (op2a code op2b)) */
9394 73669 : if (TREE_CODE (inner1) == SSA_NAME
9395 73669 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
9396 72398 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9397 127841 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9398 : gimple_assign_rhs1 (s),
9399 : gimple_assign_rhs2 (s),
9400 : code2, op2a, op2b,
9401 : outer_cond_bb)))
9402 : {
9403 : /* Handle the OR case, where we are reassociating:
9404 : (inner1 OR inner2) OR (op2a code2 op2b)
9405 : => (t OR inner2)
9406 : If the partial result t is a constant, we win. Otherwise
9407 : continue on to try reassociating with the other inner test. */
9408 5993 : if (is_or)
9409 : {
9410 98 : if (integer_onep (t))
9411 0 : return boolean_true_node;
9412 98 : else if (integer_zerop (t))
9413 : return inner2;
9414 : }
9415 :
9416 : /* Handle the AND case, where we are redistributing:
9417 : (inner1 AND inner2) OR (op2a code2 op2b)
9418 : => (t AND (inner2 OR (op2a code op2b))) */
9419 5895 : else if (integer_zerop (t))
9420 0 : return boolean_false_node;
9421 :
9422 : /* Save partial result for later. */
9423 : partial = t;
9424 : }
9425 :
9426 : /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
9427 73669 : if (TREE_CODE (inner2) == SSA_NAME
9428 73669 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
9429 72770 : && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
9430 142918 : && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
9431 : gimple_assign_rhs1 (s),
9432 : gimple_assign_rhs2 (s),
9433 : code2, op2a, op2b,
9434 : outer_cond_bb)))
9435 : {
9436 : /* Handle the OR case, where we are reassociating:
9437 : (inner1 OR inner2) OR (op2a code2 op2b)
9438 : => (inner1 OR t)
9439 : => (t OR partial) */
9440 5564 : if (is_or)
9441 : {
9442 71 : if (integer_zerop (t))
9443 : return inner1;
9444 71 : else if (integer_onep (t))
9445 1 : return boolean_true_node;
9446 : /* If both are the same, we can apply the identity
9447 : (x OR x) == x. */
9448 70 : else if (partial && same_bool_result_p (t, partial))
9449 : return t;
9450 : }
9451 :
9452 : /* Handle the AND case, where we are redistributing:
9453 : (inner1 AND inner2) OR (op2a code2 op2b)
9454 : => (t AND (inner1 OR (op2a code2 op2b)))
9455 : => (t AND partial) */
9456 : else
9457 : {
9458 5493 : if (integer_zerop (t))
9459 0 : return boolean_false_node;
9460 5493 : else if (partial)
9461 : {
9462 : /* We already got a simplification for the other
9463 : operand to the redistributed AND expression. The
9464 : interesting case is when at least one is true.
9465 : Or, if both are the same, we can apply the identity
9466 : (x AND x) == x. */
9467 19 : if (integer_onep (partial))
9468 : return t;
9469 18 : else if (integer_onep (t))
9470 : return partial;
9471 4 : else if (same_bool_result_p (t, partial))
9472 : return t;
9473 : }
9474 : }
9475 : }
9476 : }
9477 : return NULL_TREE;
9478 : }
9479 :
9480 : /* Try to simplify the OR of two comparisons defined by
9481 : (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
9482 : If this can be done without constructing an intermediate value,
9483 : return the resulting tree; otherwise NULL_TREE is returned.
9484 : This function is deliberately asymmetric as it recurses on SSA_DEFs
9485 : in the first comparison but not the second. */
9486 :
9487 : static tree
9488 1151826 : or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
9489 : enum tree_code code2, tree op2a, tree op2b,
9490 : basic_block outer_cond_bb)
9491 : {
9492 1151826 : tree truth_type = truth_type_for (TREE_TYPE (op1a));
9493 :
9494 : /* First check for ((x CODE1 y) OR (x CODE2 y)). */
9495 1151826 : if (operand_equal_p (op1a, op2a, 0)
9496 1151826 : && operand_equal_p (op1b, op2b, 0))
9497 : {
9498 : /* Result will be either NULL_TREE, or a combined comparison. */
9499 13138 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9500 : TRUTH_ORIF_EXPR, code1, code2,
9501 : truth_type, op1a, op1b);
9502 13138 : if (t)
9503 : return t;
9504 : }
9505 :
9506 : /* Likewise the swapped case of the above. */
9507 1138720 : if (operand_equal_p (op1a, op2b, 0)
9508 1138720 : && operand_equal_p (op1b, op2a, 0))
9509 : {
9510 : /* Result will be either NULL_TREE, or a combined comparison. */
9511 0 : tree t = combine_comparisons (UNKNOWN_LOCATION,
9512 : TRUTH_ORIF_EXPR, code1,
9513 : swap_tree_comparison (code2),
9514 : truth_type, op1a, op1b);
9515 0 : if (t)
9516 : return t;
9517 : }
9518 :
9519 : /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
9520 : NAME's definition is a truth value. See if there are any simplifications
9521 : that can be done against the NAME's definition. */
9522 1138720 : if (TREE_CODE (op1a) == SSA_NAME
9523 1138301 : && (code1 == NE_EXPR || code1 == EQ_EXPR)
9524 1485642 : && (integer_zerop (op1b) || integer_onep (op1b)))
9525 : {
9526 45768 : bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
9527 107002 : || (code1 == NE_EXPR && integer_onep (op1b)));
9528 102807 : gimple *stmt = SSA_NAME_DEF_STMT (op1a);
9529 102807 : switch (gimple_code (stmt))
9530 : {
9531 63064 : case GIMPLE_ASSIGN:
9532 : /* Try to simplify by copy-propagating the definition. */
9533 63064 : return or_var_with_comparison (type, op1a, invert, code2, op2a,
9534 63064 : op2b, outer_cond_bb);
9535 :
9536 15298 : case GIMPLE_PHI:
9537 : /* If every argument to the PHI produces the same result when
9538 : ORed with the second comparison, we win.
9539 : Do not do this unless the type is bool since we need a bool
9540 : result here anyway. */
9541 15298 : if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
9542 : {
9543 : tree result = NULL_TREE;
9544 : unsigned i;
9545 1003 : for (i = 0; i < gimple_phi_num_args (stmt); i++)
9546 : {
9547 1003 : tree arg = gimple_phi_arg_def (stmt, i);
9548 :
9549 : /* If this PHI has itself as an argument, ignore it.
9550 : If all the other args produce the same result,
9551 : we're still OK. */
9552 1003 : if (arg == gimple_phi_result (stmt))
9553 0 : continue;
9554 1003 : else if (TREE_CODE (arg) == INTEGER_CST)
9555 : {
9556 773 : if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
9557 : {
9558 355 : if (!result)
9559 215 : result = boolean_true_node;
9560 140 : else if (!integer_onep (result))
9561 : return NULL_TREE;
9562 : }
9563 418 : else if (!result)
9564 196 : result = fold_build2 (code2, boolean_type_node,
9565 : op2a, op2b);
9566 222 : else if (!same_bool_comparison_p (result,
9567 : code2, op2a, op2b))
9568 : return NULL_TREE;
9569 : }
9570 230 : else if (TREE_CODE (arg) == SSA_NAME
9571 230 : && !SSA_NAME_IS_DEFAULT_DEF (arg))
9572 : {
9573 230 : tree temp;
9574 230 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
9575 : /* In simple cases we can look through PHI nodes,
9576 : but we have to be careful with loops.
9577 : See PR49073. */
9578 230 : if (! dom_info_available_p (CDI_DOMINATORS)
9579 230 : || gimple_bb (def_stmt) == gimple_bb (stmt)
9580 460 : || dominated_by_p (CDI_DOMINATORS,
9581 230 : gimple_bb (def_stmt),
9582 230 : gimple_bb (stmt)))
9583 23 : return NULL_TREE;
9584 207 : temp = or_var_with_comparison (type, arg, invert, code2,
9585 : op2a, op2b, outer_cond_bb);
9586 207 : if (!temp)
9587 : return NULL_TREE;
9588 0 : else if (!result)
9589 : result = temp;
9590 0 : else if (!same_bool_result_p (result, temp))
9591 : return NULL_TREE;
9592 : }
9593 : else
9594 : return NULL_TREE;
9595 : }
9596 : return result;
9597 : }
9598 :
9599 : default:
9600 : break;
9601 : }
9602 : }
9603 : return NULL_TREE;
9604 : }
9605 :
9606 : /* Try to simplify the OR of two comparisons, specified by
9607 : (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
9608 : If this can be simplified to a single expression (without requiring
9609 : introducing more SSA variables to hold intermediate values),
9610 : return the resulting tree. Otherwise return NULL_TREE.
9611 : If the result expression is non-null, it has boolean type. */
9612 :
9613 : tree
9614 581968 : maybe_fold_or_comparisons (tree type,
9615 : enum tree_code code1, tree op1a, tree op1b,
9616 : enum tree_code code2, tree op2a, tree op2b,
9617 : basic_block outer_cond_bb)
9618 : {
9619 581968 : if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b,
9620 : outer_cond_bb))
9621 : return t;
9622 :
9623 568885 : if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b,
9624 : outer_cond_bb))
9625 : return t;
9626 :
9627 568880 : if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1,
9628 : op1a, op1b, code2, op2a,
9629 : op2b, outer_cond_bb))
9630 : return t;
9631 :
9632 : return NULL_TREE;
9633 : }
9634 :
9635 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
9636 :
9637 : Either NULL_TREE, a simplified but non-constant or a constant
9638 : is returned.
9639 :
9640 : ??? This should go into a gimple-fold-inline.h file to be eventually
9641 : privatized with the single valueize function used in the various TUs
9642 : to avoid the indirect function call overhead. */
9643 :
9644 : tree
9645 423309582 : gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
9646 : tree (*gvalueize) (tree))
9647 : {
9648 423309582 : gimple_match_op res_op;
9649 : /* ??? The SSA propagators do not correctly deal with following SSA use-def
9650 : edges if there are intermediate VARYING defs. For this reason
9651 : do not follow SSA edges here even though SCCVN can technically
9652 : just deal fine with that. */
9653 423309582 : if (gimple_simplify (stmt, &res_op, NULL, gvalueize, valueize))
9654 : {
9655 56477635 : tree res = NULL_TREE;
9656 56477635 : if (gimple_simplified_result_is_gimple_val (&res_op))
9657 34556533 : res = res_op.ops[0];
9658 21921102 : else if (mprts_hook)
9659 7694291 : res = mprts_hook (&res_op);
9660 42250824 : if (res)
9661 : {
9662 36450683 : if (dump_file && dump_flags & TDF_DETAILS)
9663 : {
9664 9456 : fprintf (dump_file, "Match-and-simplified ");
9665 9456 : print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
9666 9456 : fprintf (dump_file, " to ");
9667 9456 : print_generic_expr (dump_file, res);
9668 9456 : fprintf (dump_file, "\n");
9669 : }
9670 36450683 : return res;
9671 : }
9672 : }
9673 :
9674 386858899 : location_t loc = gimple_location (stmt);
9675 386858899 : switch (gimple_code (stmt))
9676 : {
9677 334015997 : case GIMPLE_ASSIGN:
9678 334015997 : {
9679 334015997 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
9680 :
9681 334015997 : switch (get_gimple_rhs_class (subcode))
9682 : {
9683 114381366 : case GIMPLE_SINGLE_RHS:
9684 114381366 : {
9685 114381366 : tree rhs = gimple_assign_rhs1 (stmt);
9686 114381366 : enum tree_code_class kind = TREE_CODE_CLASS (subcode);
9687 :
9688 114381366 : if (TREE_CODE (rhs) == SSA_NAME)
9689 : {
9690 : /* If the RHS is an SSA_NAME, return its known constant value,
9691 : if any. */
9692 9812477 : return (*valueize) (rhs);
9693 : }
9694 : /* Handle propagating invariant addresses into address
9695 : operations. */
9696 104568889 : else if (TREE_CODE (rhs) == ADDR_EXPR
9697 104568889 : && !is_gimple_min_invariant (rhs))
9698 : {
9699 6218376 : poly_int64 offset = 0;
9700 6218376 : tree base;
9701 6218376 : base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (rhs, 0),
9702 : &offset,
9703 : valueize);
9704 6218376 : if (base
9705 6218376 : && (CONSTANT_CLASS_P (base)
9706 5556403 : || decl_address_invariant_p (base)))
9707 199065 : return build_invariant_address (TREE_TYPE (rhs),
9708 199065 : base, offset);
9709 : }
9710 98350513 : else if (TREE_CODE (rhs) == CONSTRUCTOR
9711 1109261 : && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
9712 99916008 : && known_eq (CONSTRUCTOR_NELTS (rhs),
9713 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
9714 : {
9715 433234 : unsigned i, nelts;
9716 433234 : tree val;
9717 :
9718 433234 : nelts = CONSTRUCTOR_NELTS (rhs);
9719 433234 : tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
9720 964019 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
9721 : {
9722 518644 : val = (*valueize) (val);
9723 518644 : if (TREE_CODE (val) == INTEGER_CST
9724 441987 : || TREE_CODE (val) == REAL_CST
9725 421093 : || TREE_CODE (val) == FIXED_CST)
9726 97551 : vec.quick_push (val);
9727 : else
9728 : return NULL_TREE;
9729 : }
9730 :
9731 12141 : return vec.build ();
9732 433234 : }
9733 103936590 : if (subcode == OBJ_TYPE_REF)
9734 : {
9735 348513 : tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
9736 : /* If callee is constant, we can fold away the wrapper. */
9737 348513 : if (is_gimple_min_invariant (val))
9738 : return val;
9739 : }
9740 :
9741 103936340 : if (kind == tcc_reference)
9742 : {
9743 69035506 : if ((TREE_CODE (rhs) == VIEW_CONVERT_EXPR
9744 66753053 : || TREE_CODE (rhs) == REALPART_EXPR
9745 65739893 : || TREE_CODE (rhs) == IMAGPART_EXPR)
9746 71219440 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9747 : {
9748 3529346 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9749 3529346 : return fold_unary_loc (EXPR_LOCATION (rhs),
9750 3529346 : TREE_CODE (rhs),
9751 7058692 : TREE_TYPE (rhs), val);
9752 : }
9753 65506160 : else if (TREE_CODE (rhs) == BIT_FIELD_REF
9754 65506160 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9755 : {
9756 717477 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9757 717477 : return fold_ternary_loc (EXPR_LOCATION (rhs),
9758 717477 : TREE_CODE (rhs),
9759 717477 : TREE_TYPE (rhs), val,
9760 717477 : TREE_OPERAND (rhs, 1),
9761 1434954 : TREE_OPERAND (rhs, 2));
9762 : }
9763 64788683 : else if (TREE_CODE (rhs) == MEM_REF
9764 64788683 : && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
9765 : {
9766 13443419 : tree val = (*valueize) (TREE_OPERAND (rhs, 0));
9767 13443419 : if (TREE_CODE (val) == ADDR_EXPR
9768 13443419 : && is_gimple_min_invariant (val))
9769 : {
9770 971204 : tree tem = fold_build2 (MEM_REF, TREE_TYPE (rhs),
9771 : unshare_expr (val),
9772 : TREE_OPERAND (rhs, 1));
9773 971204 : if (tem)
9774 64788683 : rhs = tem;
9775 : }
9776 : }
9777 64788683 : return fold_const_aggregate_ref_1 (rhs, valueize);
9778 : }
9779 34900834 : else if (kind == tcc_declaration)
9780 7822743 : return get_symbol_constant_value (rhs);
9781 : return rhs;
9782 : }
9783 :
9784 : case GIMPLE_UNARY_RHS:
9785 : return NULL_TREE;
9786 :
9787 164269468 : case GIMPLE_BINARY_RHS:
9788 : /* Translate &x + CST into an invariant form suitable for
9789 : further propagation. */
9790 164269468 : if (subcode == POINTER_PLUS_EXPR)
9791 : {
9792 21641438 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9793 21641438 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9794 21641438 : if (TREE_CODE (op0) == ADDR_EXPR
9795 5607648 : && TREE_CODE (op1) == INTEGER_CST)
9796 : {
9797 562109 : tree off = fold_convert (ptr_type_node, op1);
9798 562109 : return build1_loc
9799 1124218 : (loc, ADDR_EXPR, TREE_TYPE (op0),
9800 562109 : fold_build2 (MEM_REF,
9801 : TREE_TYPE (TREE_TYPE (op0)),
9802 562109 : unshare_expr (op0), off));
9803 : }
9804 : }
9805 : /* Canonicalize bool != 0 and bool == 0 appearing after
9806 : valueization. While gimple_simplify handles this
9807 : it can get confused by the ~X == 1 -> X == 0 transform
9808 : which we cant reduce to a SSA name or a constant
9809 : (and we have no way to tell gimple_simplify to not
9810 : consider those transforms in the first place). */
9811 142628030 : else if (subcode == EQ_EXPR
9812 142628030 : || subcode == NE_EXPR)
9813 : {
9814 3434619 : tree lhs = gimple_assign_lhs (stmt);
9815 3434619 : tree op0 = gimple_assign_rhs1 (stmt);
9816 3434619 : if (useless_type_conversion_p (TREE_TYPE (lhs),
9817 3434619 : TREE_TYPE (op0)))
9818 : {
9819 26560 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9820 26560 : op0 = (*valueize) (op0);
9821 26560 : if (TREE_CODE (op0) == INTEGER_CST)
9822 704 : std::swap (op0, op1);
9823 26560 : if (TREE_CODE (op1) == INTEGER_CST
9824 26560 : && ((subcode == NE_EXPR && integer_zerop (op1))
9825 2344 : || (subcode == EQ_EXPR && integer_onep (op1))))
9826 323 : return op0;
9827 : }
9828 : }
9829 : return NULL_TREE;
9830 :
9831 760538 : case GIMPLE_TERNARY_RHS:
9832 760538 : {
9833 : /* Handle ternary operators that can appear in GIMPLE form. */
9834 760538 : tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
9835 760538 : tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
9836 760538 : tree op2 = (*valueize) (gimple_assign_rhs3 (stmt));
9837 760538 : return fold_ternary_loc (loc, subcode,
9838 760538 : TREE_TYPE (gimple_assign_lhs (stmt)),
9839 760538 : op0, op1, op2);
9840 : }
9841 :
9842 0 : default:
9843 0 : gcc_unreachable ();
9844 : }
9845 : }
9846 :
9847 14573824 : case GIMPLE_CALL:
9848 14573824 : {
9849 14573824 : tree fn;
9850 14573824 : gcall *call_stmt = as_a <gcall *> (stmt);
9851 :
9852 14573824 : if (gimple_call_internal_p (stmt))
9853 : {
9854 1342859 : enum tree_code subcode = ERROR_MARK;
9855 1342859 : switch (gimple_call_internal_fn (stmt))
9856 : {
9857 : case IFN_UBSAN_CHECK_ADD:
9858 : subcode = PLUS_EXPR;
9859 : break;
9860 8008 : case IFN_UBSAN_CHECK_SUB:
9861 8008 : subcode = MINUS_EXPR;
9862 8008 : break;
9863 6831 : case IFN_UBSAN_CHECK_MUL:
9864 6831 : subcode = MULT_EXPR;
9865 6831 : break;
9866 143374 : case IFN_BUILTIN_EXPECT:
9867 143374 : {
9868 143374 : tree arg0 = gimple_call_arg (stmt, 0);
9869 143374 : tree op0 = (*valueize) (arg0);
9870 143374 : if (TREE_CODE (op0) == INTEGER_CST)
9871 : return op0;
9872 : return NULL_TREE;
9873 : }
9874 : default:
9875 : return NULL_TREE;
9876 : }
9877 22982 : tree arg0 = gimple_call_arg (stmt, 0);
9878 22982 : tree arg1 = gimple_call_arg (stmt, 1);
9879 22982 : tree op0 = (*valueize) (arg0);
9880 22982 : tree op1 = (*valueize) (arg1);
9881 :
9882 22982 : if (TREE_CODE (op0) != INTEGER_CST
9883 2505 : || TREE_CODE (op1) != INTEGER_CST)
9884 : {
9885 22460 : switch (subcode)
9886 : {
9887 6731 : case MULT_EXPR:
9888 : /* x * 0 = 0 * x = 0 without overflow. */
9889 6731 : if (integer_zerop (op0) || integer_zerop (op1))
9890 20 : return build_zero_cst (TREE_TYPE (arg0));
9891 : break;
9892 7666 : case MINUS_EXPR:
9893 : /* y - y = 0 without overflow. */
9894 7666 : if (operand_equal_p (op0, op1, 0))
9895 0 : return build_zero_cst (TREE_TYPE (arg0));
9896 : break;
9897 : default:
9898 : break;
9899 : }
9900 : }
9901 22962 : tree res
9902 22962 : = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1);
9903 22962 : if (res
9904 2870 : && TREE_CODE (res) == INTEGER_CST
9905 23484 : && !TREE_OVERFLOW (res))
9906 : return res;
9907 : return NULL_TREE;
9908 : }
9909 :
9910 13230965 : fn = (*valueize) (gimple_call_fn (stmt));
9911 13230965 : if (TREE_CODE (fn) == ADDR_EXPR
9912 12595783 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
9913 12595719 : && fndecl_built_in_p (TREE_OPERAND (fn, 0))
9914 19390312 : && gimple_builtin_call_types_compatible_p (stmt,
9915 6159347 : TREE_OPERAND (fn, 0)))
9916 : {
9917 6057274 : tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
9918 6057274 : tree retval;
9919 6057274 : unsigned i;
9920 18770836 : for (i = 0; i < gimple_call_num_args (stmt); ++i)
9921 12713562 : args[i] = (*valueize) (gimple_call_arg (stmt, i));
9922 6057274 : retval = fold_builtin_call_array (loc,
9923 : gimple_call_return_type (call_stmt),
9924 : fn, gimple_call_num_args (stmt), args);
9925 6057274 : if (retval)
9926 : {
9927 : /* fold_call_expr wraps the result inside a NOP_EXPR. */
9928 61496 : STRIP_NOPS (retval);
9929 61496 : retval = fold_convert (gimple_call_return_type (call_stmt),
9930 : retval);
9931 : }
9932 6057274 : return retval;
9933 : }
9934 : return NULL_TREE;
9935 : }
9936 :
9937 : default:
9938 : return NULL_TREE;
9939 : }
9940 : }
9941 :
9942 : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
9943 : Returns NULL_TREE if folding to a constant is not possible, otherwise
9944 : returns a constant according to is_gimple_min_invariant. */
9945 :
9946 : tree
9947 4371 : gimple_fold_stmt_to_constant (gimple *stmt, tree (*valueize) (tree))
9948 : {
9949 4371 : tree res = gimple_fold_stmt_to_constant_1 (stmt, valueize);
9950 4371 : if (res && is_gimple_min_invariant (res))
9951 : return res;
9952 : return NULL_TREE;
9953 : }
9954 :
9955 :
9956 : /* The following set of functions are supposed to fold references using
9957 : their constant initializers. */
9958 :
9959 : /* See if we can find constructor defining value of BASE.
9960 : When we know the constructor with constant offset (such as
9961 : base is array[40] and we do know constructor of array), then
9962 : BIT_OFFSET is adjusted accordingly.
9963 :
9964 : As a special case, return error_mark_node when constructor
9965 : is not explicitly available, but it is known to be zero
9966 : such as 'static const int a;'. */
9967 : static tree
9968 123552392 : get_base_constructor (tree base, poly_int64 *bit_offset,
9969 : tree (*valueize)(tree))
9970 : {
9971 123651701 : poly_int64 bit_offset2, size, max_size;
9972 123651701 : bool reverse;
9973 :
9974 123651701 : if (TREE_CODE (base) == MEM_REF)
9975 : {
9976 131184072 : poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
9977 65592036 : if (!boff.to_shwi (bit_offset))
9978 65231099 : return NULL_TREE;
9979 :
9980 65591689 : if (valueize
9981 65591689 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
9982 34342698 : base = valueize (TREE_OPERAND (base, 0));
9983 65591689 : if (!base || TREE_CODE (base) != ADDR_EXPR)
9984 : return NULL_TREE;
9985 360937 : base = TREE_OPERAND (base, 0);
9986 : }
9987 58059665 : else if (valueize
9988 30072489 : && TREE_CODE (base) == SSA_NAME)
9989 0 : base = valueize (base);
9990 :
9991 : /* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its
9992 : DECL_INITIAL. If BASE is a nested reference into another
9993 : ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
9994 : the inner reference. */
9995 58420602 : switch (TREE_CODE (base))
9996 : {
9997 50809645 : case VAR_DECL:
9998 50809645 : case CONST_DECL:
9999 50809645 : {
10000 50809645 : tree init = ctor_for_folding (base);
10001 :
10002 : /* Our semantic is exact opposite of ctor_for_folding;
10003 : NULL means unknown, while error_mark_node is 0. */
10004 50809645 : if (init == error_mark_node)
10005 : return NULL_TREE;
10006 1259938 : if (!init)
10007 1174 : return error_mark_node;
10008 : return init;
10009 : }
10010 :
10011 99309 : case VIEW_CONVERT_EXPR:
10012 99309 : return get_base_constructor (TREE_OPERAND (base, 0),
10013 99309 : bit_offset, valueize);
10014 :
10015 353112 : case ARRAY_REF:
10016 353112 : case COMPONENT_REF:
10017 353112 : base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
10018 : &reverse);
10019 353112 : if (!known_size_p (max_size) || maybe_ne (size, max_size))
10020 : return NULL_TREE;
10021 292619 : *bit_offset += bit_offset2;
10022 292619 : return get_base_constructor (base, bit_offset, valueize);
10023 :
10024 : case CONSTRUCTOR:
10025 : return base;
10026 :
10027 7158536 : default:
10028 7158536 : if (CONSTANT_CLASS_P (base))
10029 : return base;
10030 :
10031 : return NULL_TREE;
10032 : }
10033 : }
10034 :
10035 : /* CTOR is a CONSTRUCTOR of an array or vector type. Fold a reference of SIZE
10036 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10037 : the reference; otherwise the type of the referenced element is used instead.
10038 : When SIZE is zero, attempt to fold a reference to the entire element OFFSET
10039 : refers to. Increment *SUBOFF by the bit offset of the accessed element. */
10040 :
10041 : static tree
10042 673298 : fold_array_ctor_reference (tree type, tree ctor,
10043 : unsigned HOST_WIDE_INT offset,
10044 : unsigned HOST_WIDE_INT size,
10045 : tree from_decl,
10046 : unsigned HOST_WIDE_INT *suboff)
10047 : {
10048 673298 : offset_int low_bound;
10049 673298 : offset_int elt_size;
10050 673298 : offset_int access_index;
10051 673298 : tree domain_type = NULL_TREE;
10052 673298 : HOST_WIDE_INT inner_offset;
10053 :
10054 : /* Compute low bound and elt size. */
10055 673298 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
10056 673298 : domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
10057 673298 : if (domain_type && TYPE_MIN_VALUE (domain_type))
10058 : {
10059 : /* Static constructors for variably sized objects make no sense. */
10060 673298 : if (TREE_CODE (TYPE_MIN_VALUE (domain_type)) != INTEGER_CST)
10061 : return NULL_TREE;
10062 673298 : low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
10063 : }
10064 : else
10065 0 : low_bound = 0;
10066 : /* Static constructors for variably sized objects make no sense. */
10067 673298 : if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))) != INTEGER_CST)
10068 : return NULL_TREE;
10069 673298 : elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
10070 :
10071 : /* When TYPE is non-null, verify that it specifies a constant-sized
10072 : access of a multiple of the array element size. Avoid division
10073 : by zero below when ELT_SIZE is zero, such as with the result of
10074 : an initializer for a zero-length array or an empty struct. */
10075 673298 : if (elt_size == 0
10076 673298 : || (type
10077 673262 : && (!TYPE_SIZE_UNIT (type)
10078 673262 : || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
10079 36 : return NULL_TREE;
10080 :
10081 : /* Compute the array index we look for. */
10082 673262 : access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
10083 : elt_size);
10084 673262 : access_index += low_bound;
10085 :
10086 : /* And offset within the access. */
10087 673262 : inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
10088 :
10089 673262 : unsigned HOST_WIDE_INT elt_sz = elt_size.to_uhwi ();
10090 673262 : if (size > elt_sz * BITS_PER_UNIT)
10091 : {
10092 : /* native_encode_expr constraints. */
10093 21486 : if (size > MAX_BITSIZE_MODE_ANY_MODE
10094 17513 : || size % BITS_PER_UNIT != 0
10095 17513 : || inner_offset % BITS_PER_UNIT != 0
10096 17513 : || elt_sz > MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT)
10097 : return NULL_TREE;
10098 :
10099 17513 : unsigned ctor_idx;
10100 17513 : tree val = get_array_ctor_element_at_index (ctor, access_index,
10101 : &ctor_idx);
10102 17537 : if (!val && ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10103 23 : return build_zero_cst (type);
10104 :
10105 : /* native-encode adjacent ctor elements. */
10106 17490 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10107 17490 : unsigned bufoff = 0;
10108 17490 : offset_int index = 0;
10109 17490 : offset_int max_index = access_index;
10110 17490 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10111 17490 : if (!val)
10112 1 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10113 17489 : else if (!CONSTANT_CLASS_P (val))
10114 : return NULL_TREE;
10115 17316 : if (!elt->index)
10116 : ;
10117 17181 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10118 : {
10119 18 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10120 18 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10121 : }
10122 : else
10123 17163 : index = max_index = wi::to_offset (elt->index);
10124 17316 : index = wi::umax (index, access_index);
10125 112484 : do
10126 : {
10127 112484 : if (bufoff + elt_sz > sizeof (buf))
10128 0 : elt_sz = sizeof (buf) - bufoff;
10129 112484 : int len;
10130 112484 : if (TREE_CODE (val) == RAW_DATA_CST)
10131 : {
10132 20 : gcc_assert (inner_offset == 0);
10133 20 : if (!elt->index || TREE_CODE (elt->index) != INTEGER_CST)
10134 : return NULL_TREE;
10135 40 : inner_offset = (access_index
10136 20 : - wi::to_offset (elt->index)).to_uhwi ();
10137 20 : len = MIN (sizeof (buf) - bufoff,
10138 : (unsigned) (RAW_DATA_LENGTH (val) - inner_offset));
10139 20 : memcpy (buf + bufoff, RAW_DATA_POINTER (val) + inner_offset,
10140 : len);
10141 20 : access_index += len - 1;
10142 : }
10143 : else
10144 : {
10145 224928 : len = native_encode_expr (val, buf + bufoff, elt_sz,
10146 112464 : inner_offset / BITS_PER_UNIT);
10147 112464 : if (len != (int) elt_sz - inner_offset / BITS_PER_UNIT)
10148 : return NULL_TREE;
10149 : }
10150 112484 : inner_offset = 0;
10151 112484 : bufoff += len;
10152 :
10153 112484 : access_index += 1;
10154 112484 : if (wi::cmpu (access_index, index) == 0)
10155 2 : val = elt->value;
10156 112482 : else if (wi::cmpu (access_index, max_index) > 0)
10157 : {
10158 112260 : ctor_idx++;
10159 112260 : if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
10160 : {
10161 15388 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10162 15388 : ++max_index;
10163 : }
10164 : else
10165 : {
10166 96872 : elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10167 96872 : index = 0;
10168 96872 : max_index = access_index;
10169 96872 : if (!elt->index)
10170 : ;
10171 96064 : else if (TREE_CODE (elt->index) == RANGE_EXPR)
10172 : {
10173 0 : index = wi::to_offset (TREE_OPERAND (elt->index, 0));
10174 0 : max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
10175 : }
10176 : else
10177 96064 : index = max_index = wi::to_offset (elt->index);
10178 96872 : index = wi::umax (index, access_index);
10179 96872 : if (wi::cmpu (access_index, index) == 0)
10180 96867 : val = elt->value;
10181 : else
10182 5 : val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
10183 : }
10184 : }
10185 : }
10186 112484 : while (bufoff < size / BITS_PER_UNIT);
10187 17316 : *suboff += size;
10188 17316 : return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
10189 : }
10190 :
10191 651776 : unsigned ctor_idx;
10192 651776 : if (tree val = get_array_ctor_element_at_index (ctor, access_index,
10193 : &ctor_idx))
10194 : {
10195 650649 : if (TREE_CODE (val) == RAW_DATA_CST)
10196 : {
10197 2590 : if (size != BITS_PER_UNIT || elt_sz != 1 || inner_offset != 0)
10198 : return NULL_TREE;
10199 2582 : constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
10200 2582 : if (elt->index == NULL_TREE || TREE_CODE (elt->index) != INTEGER_CST)
10201 : return NULL_TREE;
10202 2582 : unsigned o = (access_index - wi::to_offset (elt->index)).to_uhwi ();
10203 2582 : val = build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
10204 : }
10205 650641 : if (!size && TREE_CODE (val) != CONSTRUCTOR)
10206 : {
10207 : /* For the final reference to the entire accessed element
10208 : (SIZE is zero), reset INNER_OFFSET, disegard TYPE (which
10209 : may be null) in favor of the type of the element, and set
10210 : SIZE to the size of the accessed element. */
10211 22915 : inner_offset = 0;
10212 22915 : type = TREE_TYPE (val);
10213 22915 : size = elt_sz * BITS_PER_UNIT;
10214 : }
10215 1671809 : else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
10216 454477 : && TREE_CODE (val) == CONSTRUCTOR
10217 15669 : && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
10218 : /* If this isn't the last element in the CTOR and a CTOR itself
10219 : and it does not cover the whole object we are requesting give up
10220 : since we're not set up for combining from multiple CTORs. */
10221 26 : return NULL_TREE;
10222 :
10223 650615 : *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
10224 650615 : return fold_ctor_reference (type, val, inner_offset, size, from_decl,
10225 : suboff);
10226 : }
10227 :
10228 : /* Memory not explicitly mentioned in constructor is 0 (or
10229 : the reference is out of range). */
10230 1127 : return type ? build_zero_cst (type) : NULL_TREE;
10231 : }
10232 :
10233 : /* CTOR is a CONSTRUCTOR of a record or union type. Fold a reference of SIZE
10234 : bits to the memory at bit OFFSET. If non-null, TYPE is the expected type of
10235 : the reference; otherwise the type of the referenced member is used instead.
10236 : When SIZE is zero, attempt to fold a reference to the entire member OFFSET
10237 : refers to. Increment *SUBOFF by the bit offset of the accessed member. */
10238 :
10239 : static tree
10240 79669 : fold_nonarray_ctor_reference (tree type, tree ctor,
10241 : unsigned HOST_WIDE_INT offset,
10242 : unsigned HOST_WIDE_INT size,
10243 : tree from_decl,
10244 : unsigned HOST_WIDE_INT *suboff)
10245 : {
10246 79669 : unsigned HOST_WIDE_INT cnt;
10247 79669 : tree cfield, cval;
10248 :
10249 120425 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
10250 : {
10251 111466 : tree byte_offset = DECL_FIELD_OFFSET (cfield);
10252 111466 : tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
10253 111466 : tree field_size = DECL_SIZE (cfield);
10254 :
10255 111466 : if (!field_size)
10256 : {
10257 : /* Determine the size of the flexible array member from
10258 : the size of the initializer provided for it. */
10259 847 : field_size = TYPE_SIZE (TREE_TYPE (cval));
10260 : }
10261 :
10262 : /* Variable sized objects in static constructors makes no sense,
10263 : but field_size can be NULL for flexible array members. */
10264 111466 : gcc_assert (TREE_CODE (field_offset) == INTEGER_CST
10265 : && TREE_CODE (byte_offset) == INTEGER_CST
10266 : && (field_size != NULL_TREE
10267 : ? TREE_CODE (field_size) == INTEGER_CST
10268 : : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
10269 :
10270 : /* Compute bit offset of the field. */
10271 111466 : offset_int bitoffset
10272 111466 : = (wi::to_offset (field_offset)
10273 111466 : + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
10274 : /* Compute bit offset where the field ends. */
10275 111466 : offset_int bitoffset_end;
10276 111466 : if (field_size != NULL_TREE)
10277 111466 : bitoffset_end = bitoffset + wi::to_offset (field_size);
10278 : else
10279 0 : bitoffset_end = 0;
10280 :
10281 : /* Compute the bit offset of the end of the desired access.
10282 : As a special case, if the size of the desired access is
10283 : zero, assume the access is to the entire field (and let
10284 : the caller make any necessary adjustments by storing
10285 : the actual bounds of the field in FIELDBOUNDS). */
10286 111466 : offset_int access_end = offset_int (offset);
10287 111466 : if (size)
10288 69641 : access_end += size;
10289 : else
10290 41825 : access_end = bitoffset_end;
10291 :
10292 : /* Is there any overlap between the desired access at
10293 : [OFFSET, OFFSET+SIZE) and the offset of the field within
10294 : the object at [BITOFFSET, BITOFFSET_END)? */
10295 111466 : if (wi::cmps (access_end, bitoffset) > 0
10296 111466 : && (field_size == NULL_TREE
10297 108761 : || wi::lts_p (offset, bitoffset_end)))
10298 : {
10299 70710 : *suboff += bitoffset.to_uhwi ();
10300 :
10301 70710 : if (!size && TREE_CODE (cval) != CONSTRUCTOR)
10302 : {
10303 : /* For the final reference to the entire accessed member
10304 : (SIZE is zero), reset OFFSET, disegard TYPE (which may
10305 : be null) in favor of the type of the member, and set
10306 : SIZE to the size of the accessed member. */
10307 19310 : offset = bitoffset.to_uhwi ();
10308 19310 : type = TREE_TYPE (cval);
10309 19310 : size = (bitoffset_end - bitoffset).to_uhwi ();
10310 : }
10311 :
10312 : /* We do have overlap. Now see if the field is large enough
10313 : to cover the access. Give up for accesses that extend
10314 : beyond the end of the object or that span multiple fields. */
10315 70710 : if (wi::cmps (access_end, bitoffset_end) > 0)
10316 : return NULL_TREE;
10317 70083 : if (offset < bitoffset)
10318 : return NULL_TREE;
10319 :
10320 70083 : offset_int inner_offset = offset_int (offset) - bitoffset;
10321 :
10322 : /* Integral bit-fields are left-justified on big-endian targets, so
10323 : we must arrange for native_encode_int to start at their MSB. */
10324 70083 : if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
10325 : {
10326 70083 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
10327 : return NULL_TREE;
10328 70083 : if (BYTES_BIG_ENDIAN)
10329 : {
10330 : tree ctype = TREE_TYPE (cfield);
10331 : unsigned int encoding_size;
10332 : if (TYPE_MODE (ctype) != BLKmode)
10333 : encoding_size
10334 : = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (ctype));
10335 : else
10336 : encoding_size = TREE_INT_CST_LOW (TYPE_SIZE (ctype));
10337 : inner_offset += encoding_size - wi::to_offset (field_size);
10338 : }
10339 : }
10340 :
10341 70083 : return fold_ctor_reference (type, cval,
10342 70083 : inner_offset.to_uhwi (), size,
10343 : from_decl, suboff);
10344 : }
10345 : }
10346 :
10347 8959 : if (!type)
10348 : return NULL_TREE;
10349 :
10350 8959 : return build_zero_cst (type);
10351 : }
10352 :
10353 : /* CTOR is a value initializing memory. Fold a reference of TYPE and
10354 : bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE
10355 : is zero, attempt to fold a reference to the entire subobject
10356 : which OFFSET refers to. This is used when folding accesses to
10357 : string members of aggregates. When non-null, set *SUBOFF to
10358 : the bit offset of the accessed subobject. */
10359 :
10360 : tree
10361 1564956 : fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
10362 : const poly_uint64 &poly_size, tree from_decl,
10363 : unsigned HOST_WIDE_INT *suboff /* = NULL */)
10364 : {
10365 1564956 : tree ret;
10366 :
10367 : /* We found the field with exact match. */
10368 1564956 : if (type
10369 1564956 : && useless_type_conversion_p (type, TREE_TYPE (ctor))
10370 2238817 : && known_eq (poly_offset, 0U))
10371 672597 : return canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10372 :
10373 : /* The remaining optimizations need a constant size and offset. */
10374 892359 : unsigned HOST_WIDE_INT size, offset;
10375 892359 : if (!poly_size.is_constant (&size) || !poly_offset.is_constant (&offset))
10376 : return NULL_TREE;
10377 :
10378 : /* We are at the end of walk, see if we can view convert the
10379 : result. */
10380 892359 : if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset
10381 : /* VIEW_CONVERT_EXPR is defined only for matching sizes. */
10382 23268 : && known_eq (wi::to_poly_widest (TYPE_SIZE (type)), size)
10383 23161 : && known_eq (wi::to_poly_widest (TYPE_SIZE (TREE_TYPE (ctor))), size))
10384 : {
10385 14441 : ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl);
10386 14441 : if (ret)
10387 : {
10388 14441 : ret = fold_unary (VIEW_CONVERT_EXPR, type, ret);
10389 14441 : if (ret)
10390 14421 : STRIP_USELESS_TYPE_CONVERSION (ret);
10391 : }
10392 14441 : return ret;
10393 : }
10394 :
10395 : /* For constants and byte-aligned/sized reads, try to go through
10396 : native_encode/interpret. */
10397 877918 : if (CONSTANT_CLASS_P (ctor)
10398 : && BITS_PER_UNIT == 8
10399 116687 : && offset % BITS_PER_UNIT == 0
10400 116683 : && offset / BITS_PER_UNIT <= INT_MAX
10401 116651 : && size % BITS_PER_UNIT == 0
10402 116642 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10403 994262 : && can_native_interpret_type_p (type))
10404 : {
10405 101272 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10406 202544 : int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
10407 101272 : offset / BITS_PER_UNIT);
10408 101272 : if (len > 0)
10409 100554 : return native_interpret_expr (type, buf, len);
10410 : }
10411 :
10412 : /* For constructors, try first a recursive local processing, but in any case
10413 : this requires the native storage order. */
10414 777364 : if (TREE_CODE (ctor) == CONSTRUCTOR
10415 777364 : && !(AGGREGATE_TYPE_P (TREE_TYPE (ctor))
10416 753197 : && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (ctor))))
10417 : {
10418 752967 : unsigned HOST_WIDE_INT dummy = 0;
10419 752967 : if (!suboff)
10420 625141 : suboff = &dummy;
10421 :
10422 752967 : tree ret;
10423 752967 : if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE
10424 752967 : || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE)
10425 673298 : ret = fold_array_ctor_reference (type, ctor, offset, size,
10426 : from_decl, suboff);
10427 : else
10428 79669 : ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
10429 : from_decl, suboff);
10430 :
10431 : /* Otherwise fall back to native_encode_initializer. This may be done
10432 : only from the outermost fold_ctor_reference call (because it itself
10433 : recurses into CONSTRUCTORs and doesn't update suboff). */
10434 752967 : if (ret == NULL_TREE
10435 204246 : && suboff == &dummy
10436 : && BITS_PER_UNIT == 8
10437 195891 : && offset % BITS_PER_UNIT == 0
10438 195889 : && offset / BITS_PER_UNIT <= INT_MAX
10439 195889 : && size % BITS_PER_UNIT == 0
10440 195880 : && size <= MAX_BITSIZE_MODE_ANY_MODE
10441 944874 : && can_native_interpret_type_p (type))
10442 : {
10443 178304 : unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
10444 356608 : int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT,
10445 178304 : offset / BITS_PER_UNIT);
10446 178304 : if (len > 0)
10447 1310 : return native_interpret_expr (type, buf, len);
10448 : }
10449 :
10450 751657 : return ret;
10451 : }
10452 :
10453 : return NULL_TREE;
10454 : }
10455 :
10456 : /* Return the tree representing the element referenced by T if T is an
10457 : ARRAY_REF or COMPONENT_REF into constant aggregates valuezing SSA
10458 : names using VALUEIZE. Return NULL_TREE otherwise. */
10459 :
10460 : tree
10461 128808131 : fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
10462 : {
10463 128808131 : tree ctor, idx, base;
10464 128808131 : poly_int64 offset, size, max_size;
10465 128808131 : tree tem;
10466 128808131 : bool reverse;
10467 :
10468 128808131 : if (TREE_THIS_VOLATILE (t))
10469 : return NULL_TREE;
10470 :
10471 128491574 : if (DECL_P (t))
10472 299781 : return get_symbol_constant_value (t);
10473 :
10474 128191793 : tem = fold_read_from_constant_string (t);
10475 128191793 : if (tem)
10476 : return tem;
10477 :
10478 128189937 : switch (TREE_CODE (t))
10479 : {
10480 10644251 : case ARRAY_REF:
10481 10644251 : case ARRAY_RANGE_REF:
10482 : /* Constant indexes are handled well by get_base_constructor.
10483 : Only special case variable offsets.
10484 : FIXME: This code can't handle nested references with variable indexes
10485 : (they will be handled only by iteration of ccp). Perhaps we can bring
10486 : get_ref_base_and_extent here and make it use a valueize callback. */
10487 10644251 : if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
10488 6211183 : && valueize
10489 4166958 : && (idx = (*valueize) (TREE_OPERAND (t, 1)))
10490 14811209 : && poly_int_tree_p (idx))
10491 : {
10492 1682833 : tree low_bound, unit_size;
10493 :
10494 : /* If the resulting bit-offset is constant, track it. */
10495 1682833 : if ((low_bound = array_ref_low_bound (t),
10496 1682833 : poly_int_tree_p (low_bound))
10497 1682833 : && (unit_size = array_ref_element_size (t),
10498 1682833 : tree_fits_uhwi_p (unit_size)))
10499 : {
10500 1682833 : poly_offset_int woffset
10501 1682833 : = wi::sext (wi::to_poly_offset (idx)
10502 3365666 : - wi::to_poly_offset (low_bound),
10503 1682833 : TYPE_PRECISION (sizetype));
10504 1682833 : woffset *= tree_to_uhwi (unit_size);
10505 1682833 : woffset *= BITS_PER_UNIT;
10506 1682833 : if (woffset.to_shwi (&offset))
10507 : {
10508 1682702 : base = TREE_OPERAND (t, 0);
10509 1682702 : ctor = get_base_constructor (base, &offset, valueize);
10510 : /* Empty constructor. Always fold to 0. */
10511 1682702 : if (ctor == error_mark_node)
10512 1682702 : return build_zero_cst (TREE_TYPE (t));
10513 : /* Out of bound array access. Value is undefined,
10514 : but don't fold. */
10515 1682624 : if (maybe_lt (offset, 0))
10516 : return NULL_TREE;
10517 : /* We cannot determine ctor. */
10518 1682150 : if (!ctor)
10519 : return NULL_TREE;
10520 173527 : return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
10521 173527 : tree_to_uhwi (unit_size)
10522 347054 : * BITS_PER_UNIT,
10523 : base);
10524 : }
10525 : }
10526 : }
10527 : /* Fallthru. */
10528 :
10529 121577071 : case COMPONENT_REF:
10530 121577071 : case BIT_FIELD_REF:
10531 121577071 : case TARGET_MEM_REF:
10532 121577071 : case MEM_REF:
10533 121577071 : base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
10534 121577071 : ctor = get_base_constructor (base, &offset, valueize);
10535 :
10536 : /* We cannot determine ctor. */
10537 121577071 : if (!ctor)
10538 : return NULL_TREE;
10539 : /* Empty constructor. Always fold to 0. */
10540 1180076 : if (ctor == error_mark_node)
10541 1096 : return build_zero_cst (TREE_TYPE (t));
10542 : /* We do not know precise access. */
10543 1178980 : if (!known_size_p (max_size) || maybe_ne (max_size, size))
10544 : return NULL_TREE;
10545 : /* Out of bound array access. Value is undefined, but don't fold. */
10546 489630 : if (maybe_lt (offset, 0))
10547 : return NULL_TREE;
10548 : /* Access with reverse storage order. */
10549 489249 : if (reverse)
10550 : return NULL_TREE;
10551 :
10552 489249 : tem = fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, base);
10553 489249 : if (tem)
10554 : return tem;
10555 :
10556 : /* For bit field reads try to read the representative and
10557 : adjust. */
10558 169374 : if (TREE_CODE (t) == COMPONENT_REF
10559 5149 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1))
10560 169458 : && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)))
10561 : {
10562 84 : HOST_WIDE_INT csize, coffset;
10563 84 : tree field = TREE_OPERAND (t, 1);
10564 84 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
10565 168 : if (INTEGRAL_TYPE_P (TREE_TYPE (repr))
10566 83 : && size.is_constant (&csize)
10567 83 : && offset.is_constant (&coffset)
10568 83 : && (coffset % BITS_PER_UNIT != 0
10569 81 : || csize % BITS_PER_UNIT != 0)
10570 84 : && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
10571 : {
10572 10 : poly_int64 bitoffset;
10573 10 : poly_uint64 field_offset, repr_offset;
10574 10 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
10575 20 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
10576 10 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
10577 : else
10578 : bitoffset = 0;
10579 10 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
10580 10 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
10581 10 : HOST_WIDE_INT bitoff;
10582 10 : int diff = (TYPE_PRECISION (TREE_TYPE (repr))
10583 10 : - TYPE_PRECISION (TREE_TYPE (field)));
10584 10 : if (bitoffset.is_constant (&bitoff)
10585 10 : && bitoff >= 0
10586 10 : && bitoff <= diff)
10587 : {
10588 10 : offset -= bitoff;
10589 10 : size = tree_to_uhwi (DECL_SIZE (repr));
10590 :
10591 10 : tem = fold_ctor_reference (TREE_TYPE (repr), ctor, offset,
10592 10 : size, base);
10593 10 : if (tem && TREE_CODE (tem) == INTEGER_CST)
10594 : {
10595 10 : if (!BYTES_BIG_ENDIAN)
10596 10 : tem = wide_int_to_tree (TREE_TYPE (field),
10597 10 : wi::lrshift (wi::to_wide (tem),
10598 : bitoff));
10599 : else
10600 : tem = wide_int_to_tree (TREE_TYPE (field),
10601 : wi::lrshift (wi::to_wide (tem),
10602 : diff - bitoff));
10603 10 : return tem;
10604 : }
10605 : }
10606 : }
10607 : }
10608 : break;
10609 :
10610 1809702 : case REALPART_EXPR:
10611 1809702 : case IMAGPART_EXPR:
10612 1809702 : {
10613 1809702 : tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize);
10614 1809702 : if (c && TREE_CODE (c) == COMPLEX_CST)
10615 2774 : return fold_build1_loc (EXPR_LOCATION (t),
10616 5548 : TREE_CODE (t), TREE_TYPE (t), c);
10617 : break;
10618 : }
10619 :
10620 : default:
10621 : break;
10622 : }
10623 :
10624 : return NULL_TREE;
10625 : }
10626 :
10627 : tree
10628 62209746 : fold_const_aggregate_ref (tree t)
10629 : {
10630 62209746 : return fold_const_aggregate_ref_1 (t, NULL);
10631 : }
10632 :
10633 : /* Lookup virtual method with index TOKEN in a virtual table V
10634 : at OFFSET.
10635 : Set CAN_REFER if non-NULL to false if method
10636 : is not referable or if the virtual table is ill-formed (such as rewritten
10637 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10638 :
10639 : tree
10640 276287 : gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
10641 : tree v,
10642 : unsigned HOST_WIDE_INT offset,
10643 : bool *can_refer)
10644 : {
10645 276287 : tree vtable = v, init, fn;
10646 276287 : unsigned HOST_WIDE_INT size;
10647 276287 : unsigned HOST_WIDE_INT elt_size, access_index;
10648 276287 : tree domain_type;
10649 :
10650 276287 : if (can_refer)
10651 276287 : *can_refer = true;
10652 :
10653 : /* First of all double check we have virtual table. */
10654 276287 : if (!VAR_P (v) || !DECL_VIRTUAL_P (v))
10655 : {
10656 : /* Pass down that we lost track of the target. */
10657 0 : if (can_refer)
10658 0 : *can_refer = false;
10659 0 : return NULL_TREE;
10660 : }
10661 :
10662 276287 : init = ctor_for_folding (v);
10663 :
10664 : /* The virtual tables should always be born with constructors
10665 : and we always should assume that they are available for
10666 : folding. At the moment we do not stream them in all cases,
10667 : but it should never happen that ctor seem unreachable. */
10668 276287 : gcc_assert (init);
10669 276287 : if (init == error_mark_node)
10670 : {
10671 : /* Pass down that we lost track of the target. */
10672 213 : if (can_refer)
10673 213 : *can_refer = false;
10674 213 : return NULL_TREE;
10675 : }
10676 276074 : gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
10677 276074 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))));
10678 276074 : offset *= BITS_PER_UNIT;
10679 276074 : offset += token * size;
10680 :
10681 : /* Lookup the value in the constructor that is assumed to be array.
10682 : This is equivalent to
10683 : fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
10684 : offset, size, NULL);
10685 : but in a constant time. We expect that frontend produced a simple
10686 : array without indexed initializers. */
10687 :
10688 276074 : gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
10689 276074 : domain_type = TYPE_DOMAIN (TREE_TYPE (init));
10690 276074 : gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
10691 276074 : elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
10692 :
10693 276074 : access_index = offset / BITS_PER_UNIT / elt_size;
10694 276074 : gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);
10695 :
10696 : /* This code makes an assumption that there are no
10697 : indexed fields produced by C++ FE, so we can directly index the array. */
10698 276074 : if (access_index < CONSTRUCTOR_NELTS (init))
10699 : {
10700 276073 : fn = CONSTRUCTOR_ELT (init, access_index)->value;
10701 276073 : gcc_checking_assert (!CONSTRUCTOR_ELT (init, access_index)->index);
10702 276073 : STRIP_NOPS (fn);
10703 : }
10704 : else
10705 : fn = NULL;
10706 :
10707 : /* For type inconsistent program we may end up looking up virtual method
10708 : in virtual table that does not contain TOKEN entries. We may overrun
10709 : the virtual table and pick up a constant or RTTI info pointer.
10710 : In any case the call is undefined. */
10711 276073 : if (!fn
10712 276073 : || (TREE_CODE (fn) != ADDR_EXPR && TREE_CODE (fn) != FDESC_EXPR)
10713 546362 : || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
10714 5785 : fn = builtin_decl_unreachable ();
10715 : else
10716 : {
10717 270289 : fn = TREE_OPERAND (fn, 0);
10718 :
10719 : /* When cgraph node is missing and function is not public, we cannot
10720 : devirtualize. This can happen in WHOPR when the actual method
10721 : ends up in other partition, because we found devirtualization
10722 : possibility too late. */
10723 270289 : if (!can_refer_decl_in_current_unit_p (fn, vtable))
10724 : {
10725 36557 : if (can_refer)
10726 : {
10727 36557 : *can_refer = false;
10728 36557 : return fn;
10729 : }
10730 : return NULL_TREE;
10731 : }
10732 : }
10733 :
10734 : /* Make sure we create a cgraph node for functions we'll reference.
10735 : They can be non-existent if the reference comes from an entry
10736 : of an external vtable for example. */
10737 239517 : cgraph_node::get_create (fn);
10738 :
10739 239517 : return fn;
10740 : }
10741 :
10742 : /* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
10743 : is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
10744 : KNOWN_BINFO carries the binfo describing the true type of
10745 : OBJ_TYPE_REF_OBJECT(REF).
10746 : Set CAN_REFER if non-NULL to false if method
10747 : is not referable or if the virtual table is ill-formed (such as rewritten
10748 : by non-C++ produced symbol). Otherwise just return NULL in that calse. */
10749 :
10750 : tree
10751 267573 : gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
10752 : bool *can_refer)
10753 : {
10754 267573 : unsigned HOST_WIDE_INT offset;
10755 267573 : tree v;
10756 :
10757 267573 : v = BINFO_VTABLE (known_binfo);
10758 : /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone. */
10759 267573 : if (!v)
10760 : return NULL_TREE;
10761 :
10762 267573 : if (!vtable_pointer_value_to_vtable (v, &v, &offset))
10763 : {
10764 0 : if (can_refer)
10765 0 : *can_refer = false;
10766 0 : return NULL_TREE;
10767 : }
10768 267573 : return gimple_get_virt_method_for_vtable (token, v, offset, can_refer);
10769 : }
10770 :
10771 : /* Given a pointer value T, return a simplified version of an
10772 : indirection through T, or NULL_TREE if no simplification is
10773 : possible. Note that the resulting type may be different from
10774 : the type pointed to in the sense that it is still compatible
10775 : from the langhooks point of view. */
10776 :
10777 : tree
10778 2513209 : gimple_fold_indirect_ref (tree t)
10779 : {
10780 2513209 : tree ptype = TREE_TYPE (t), type = TREE_TYPE (ptype);
10781 2513209 : tree sub = t;
10782 2513209 : tree subtype;
10783 :
10784 2513209 : STRIP_NOPS (sub);
10785 2513209 : subtype = TREE_TYPE (sub);
10786 2513209 : if (!POINTER_TYPE_P (subtype)
10787 2513209 : || TYPE_REF_CAN_ALIAS_ALL (ptype))
10788 : return NULL_TREE;
10789 :
10790 2511500 : if (TREE_CODE (sub) == ADDR_EXPR)
10791 : {
10792 94305 : tree op = TREE_OPERAND (sub, 0);
10793 94305 : tree optype = TREE_TYPE (op);
10794 : /* *&p => p */
10795 94305 : if (useless_type_conversion_p (type, optype))
10796 : return op;
10797 :
10798 : /* *(foo *)&fooarray => fooarray[0] */
10799 993 : if (TREE_CODE (optype) == ARRAY_TYPE
10800 307 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
10801 1300 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10802 : {
10803 54 : tree type_domain = TYPE_DOMAIN (optype);
10804 54 : tree min_val = size_zero_node;
10805 54 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10806 54 : min_val = TYPE_MIN_VALUE (type_domain);
10807 54 : if (TREE_CODE (min_val) == INTEGER_CST)
10808 54 : return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
10809 : }
10810 : /* *(foo *)&complexfoo => __real__ complexfoo */
10811 939 : else if (TREE_CODE (optype) == COMPLEX_TYPE
10812 939 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10813 4 : return fold_build1 (REALPART_EXPR, type, op);
10814 : /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
10815 935 : else if (TREE_CODE (optype) == VECTOR_TYPE
10816 935 : && useless_type_conversion_p (type, TREE_TYPE (optype)))
10817 : {
10818 26 : tree part_width = TYPE_SIZE (type);
10819 26 : tree index = bitsize_int (0);
10820 26 : return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
10821 : }
10822 : }
10823 :
10824 : /* *(p + CST) -> ... */
10825 2418104 : if (TREE_CODE (sub) == POINTER_PLUS_EXPR
10826 2418104 : && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
10827 : {
10828 33815 : tree addr = TREE_OPERAND (sub, 0);
10829 33815 : tree off = TREE_OPERAND (sub, 1);
10830 33815 : tree addrtype;
10831 :
10832 33815 : STRIP_NOPS (addr);
10833 33815 : addrtype = TREE_TYPE (addr);
10834 :
10835 : /* ((foo*)&vectorfoo)[1] -> BIT_FIELD_REF<vectorfoo,...> */
10836 33815 : if (TREE_CODE (addr) == ADDR_EXPR
10837 92 : && TREE_CODE (TREE_TYPE (addrtype)) == VECTOR_TYPE
10838 39 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype)))
10839 33843 : && tree_fits_uhwi_p (off))
10840 : {
10841 28 : unsigned HOST_WIDE_INT offset = tree_to_uhwi (off);
10842 28 : tree part_width = TYPE_SIZE (type);
10843 28 : unsigned HOST_WIDE_INT part_widthi
10844 28 : = tree_to_shwi (part_width) / BITS_PER_UNIT;
10845 28 : unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
10846 28 : tree index = bitsize_int (indexi);
10847 28 : if (known_lt (offset / part_widthi,
10848 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
10849 28 : return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
10850 : part_width, index);
10851 : }
10852 :
10853 : /* ((foo*)&complexfoo)[1] -> __imag__ complexfoo */
10854 33787 : if (TREE_CODE (addr) == ADDR_EXPR
10855 64 : && TREE_CODE (TREE_TYPE (addrtype)) == COMPLEX_TYPE
10856 33788 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype))))
10857 : {
10858 1 : tree size = TYPE_SIZE_UNIT (type);
10859 1 : if (tree_int_cst_equal (size, off))
10860 1 : return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (addr, 0));
10861 : }
10862 :
10863 : /* *(p + CST) -> MEM_REF <p, CST>. */
10864 33786 : if (TREE_CODE (addr) != ADDR_EXPR
10865 33786 : || DECL_P (TREE_OPERAND (addr, 0)))
10866 33768 : return fold_build2 (MEM_REF, type,
10867 : addr,
10868 : wide_int_to_tree (ptype, wi::to_wide (off)));
10869 : }
10870 :
10871 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
10872 2384307 : if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
10873 2507 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
10874 2386784 : && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
10875 : {
10876 1 : tree type_domain;
10877 1 : tree min_val = size_zero_node;
10878 1 : tree osub = sub;
10879 1 : sub = gimple_fold_indirect_ref (sub);
10880 1 : if (! sub)
10881 1 : sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
10882 1 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
10883 1 : if (type_domain && TYPE_MIN_VALUE (type_domain))
10884 1 : min_val = TYPE_MIN_VALUE (type_domain);
10885 1 : if (TREE_CODE (min_val) == INTEGER_CST)
10886 1 : return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
10887 : }
10888 :
10889 : return NULL_TREE;
10890 : }
10891 :
10892 : /* Return true if CODE is an operation that when operating on signed
10893 : integer types involves undefined behavior on overflow and the
10894 : operation can be expressed with unsigned arithmetic. */
10895 :
10896 : bool
10897 510147 : arith_code_with_undefined_signed_overflow (tree_code code)
10898 : {
10899 510147 : switch (code)
10900 : {
10901 : case ABS_EXPR:
10902 : case PLUS_EXPR:
10903 : case MINUS_EXPR:
10904 : case MULT_EXPR:
10905 : case NEGATE_EXPR:
10906 : case POINTER_PLUS_EXPR:
10907 : return true;
10908 201538 : default:
10909 201538 : return false;
10910 : }
10911 : }
10912 :
10913 : /* Return true if STMT has an operation that operates on a signed
10914 : integer types involves undefined behavior on overflow and the
10915 : operation can be expressed with unsigned arithmetic.
10916 : Also returns true if STMT is a VCE that needs to be rewritten
10917 : if moved to be executed unconditionally. */
10918 :
10919 : bool
10920 1309422 : gimple_needing_rewrite_undefined (gimple *stmt)
10921 : {
10922 1309422 : if (!is_gimple_assign (stmt))
10923 : return false;
10924 1112833 : tree lhs = gimple_assign_lhs (stmt);
10925 1112833 : if (!lhs)
10926 : return false;
10927 1112833 : tree lhs_type = TREE_TYPE (lhs);
10928 1112833 : if (!INTEGRAL_TYPE_P (lhs_type)
10929 121714 : && !POINTER_TYPE_P (lhs_type))
10930 : return false;
10931 1075587 : tree rhs = gimple_assign_rhs1 (stmt);
10932 : /* Boolean loads need special handling as they are treated as a full MODE load
10933 : and don't mask off the bits for the precision. */
10934 1075587 : if (gimple_assign_load_p (stmt)
10935 : /* Booleans are the integral type which has this non-masking issue. */
10936 95246 : && TREE_CODE (lhs_type) == BOOLEAN_TYPE
10937 : /* Only non mode precision booleans are need the masking. */
10938 428 : && !type_has_mode_precision_p (lhs_type)
10939 : /* BFR should be the correct thing and just grab the precision. */
10940 428 : && TREE_CODE (rhs) != BIT_FIELD_REF
10941 : /* Bit-fields loads don't need a rewrite as the masking
10942 : happens for them. */
10943 1076015 : && (TREE_CODE (rhs) != COMPONENT_REF
10944 139 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1))))
10945 : return true;
10946 : /* VCE from integral types to a integral types but with
10947 : a smaller precision need to be changed into casts
10948 : to be well defined. */
10949 1075159 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
10950 199 : && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
10951 172 : && is_gimple_val (TREE_OPERAND (rhs, 0))
10952 1075331 : && TYPE_PRECISION (lhs_type)
10953 172 : < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
10954 : return true;
10955 1074991 : if (!TYPE_OVERFLOW_UNDEFINED (lhs_type))
10956 : return false;
10957 388065 : if (!arith_code_with_undefined_signed_overflow
10958 388065 : (gimple_assign_rhs_code (stmt)))
10959 : return false;
10960 : return true;
10961 : }
10962 :
10963 : /* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
10964 : operation that can be transformed to unsigned arithmetic by converting
10965 : its operand, carrying out the operation in the corresponding unsigned
10966 : type and converting the result back to the original type.
10967 :
10968 : If IN_PLACE is true, *GSI points to STMT, adjust the stmt in place and
10969 : return NULL.
10970 : Otherwise returns a sequence of statements that replace STMT and also
10971 : contain a modified form of STMT itself. */
10972 :
10973 : static gimple_seq
10974 65183 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi, gimple *stmt,
10975 : bool in_place)
10976 : {
10977 65183 : gcc_assert (gimple_needing_rewrite_undefined (stmt));
10978 65183 : if (dump_file && (dump_flags & TDF_DETAILS))
10979 : {
10980 21 : fprintf (dump_file, "rewriting stmt for being unconditional defined");
10981 21 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
10982 : }
10983 65183 : gimple_seq stmts = NULL;
10984 65183 : tree lhs = gimple_assign_lhs (stmt);
10985 :
10986 : /* Boolean loads need to be rewritten to be a load from the same mode
10987 : and then a cast to the other type so the other bits are masked off
10988 : correctly since the load was done conditionally. It is similar to the VCE
10989 : case below. */
10990 65183 : if (gimple_assign_load_p (stmt)
10991 65183 : && TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
10992 : {
10993 124 : tree rhs = gimple_assign_rhs1 (stmt);
10994 :
10995 : /* Double check that gimple_needing_rewrite_undefined was called. */
10996 : /* Bit-fields loads will do the masking so don't need the rewriting. */
10997 124 : gcc_assert (TREE_CODE (rhs) != COMPONENT_REF
10998 : || !DECL_BIT_FIELD (TREE_OPERAND (rhs, 1)));
10999 : /* BFR is like a bit field load and will do the correct thing. */
11000 124 : gcc_assert (TREE_CODE (lhs) != BIT_FIELD_REF);
11001 : /* Complex boolean types are not valid so REAL/IMAG part will
11002 : never show up. */
11003 124 : gcc_assert (TREE_CODE (rhs) != REALPART_EXPR
11004 : && TREE_CODE (lhs) != IMAGPART_EXPR);
11005 :
11006 124 : auto bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (rhs)));
11007 124 : tree new_type = build_nonstandard_integer_type (bits, true);
11008 124 : location_t loc = gimple_location (stmt);
11009 124 : tree mem_ref = fold_build1_loc (loc, VIEW_CONVERT_EXPR, new_type, rhs);
11010 : /* Replace the original load with a new load and a new lhs. */
11011 124 : tree new_lhs = make_ssa_name (new_type);
11012 124 : gimple_assign_set_rhs1 (stmt, mem_ref);
11013 124 : gimple_assign_set_lhs (stmt, new_lhs);
11014 :
11015 124 : if (in_place)
11016 49 : update_stmt (stmt);
11017 : else
11018 : {
11019 75 : gimple_set_modified (stmt, true);
11020 75 : gimple_seq_add_stmt (&stmts, stmt);
11021 : }
11022 :
11023 : /* Build the conversion statement. */
11024 124 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
11025 124 : if (in_place)
11026 : {
11027 49 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11028 49 : update_stmt (stmt);
11029 : }
11030 : else
11031 75 : gimple_seq_add_stmt (&stmts, cvt);
11032 124 : return stmts;
11033 : }
11034 :
11035 : /* VCE from integral types to another integral types but with
11036 : smaller precisions need to be changed into casts
11037 : to be well defined. */
11038 65059 : if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
11039 : {
11040 60 : tree rhs = gimple_assign_rhs1 (stmt);
11041 60 : tree new_rhs = TREE_OPERAND (rhs, 0);
11042 60 : gcc_assert (TYPE_PRECISION (TREE_TYPE (rhs))
11043 : < TYPE_PRECISION (TREE_TYPE (new_rhs)));
11044 60 : gcc_assert (is_gimple_val (new_rhs));
11045 60 : gimple_assign_set_rhs_code (stmt, NOP_EXPR);
11046 60 : gimple_assign_set_rhs1 (stmt, new_rhs);
11047 60 : if (in_place)
11048 51 : update_stmt (stmt);
11049 : else
11050 : {
11051 9 : gimple_set_modified (stmt, true);
11052 9 : gimple_seq_add_stmt (&stmts, stmt);
11053 : }
11054 60 : return stmts;
11055 : }
11056 64999 : tree type = unsigned_type_for (TREE_TYPE (lhs));
11057 64999 : if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
11058 24 : gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
11059 : else
11060 194432 : for (unsigned i = 1; i < gimple_num_ops (stmt); ++i)
11061 : {
11062 129457 : tree op = gimple_op (stmt, i);
11063 129457 : op = gimple_convert (&stmts, type, op);
11064 129457 : gimple_set_op (stmt, i, op);
11065 : }
11066 64999 : gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
11067 64999 : if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
11068 8891 : gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
11069 64999 : gimple_set_modified (stmt, true);
11070 64999 : if (in_place)
11071 : {
11072 47284 : if (stmts)
11073 46924 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
11074 47284 : stmts = NULL;
11075 : }
11076 : else
11077 17715 : gimple_seq_add_stmt (&stmts, stmt);
11078 64999 : gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
11079 64999 : if (in_place)
11080 : {
11081 47284 : gsi_insert_after (gsi, cvt, GSI_SAME_STMT);
11082 47284 : update_stmt (stmt);
11083 : }
11084 : else
11085 17715 : gimple_seq_add_stmt (&stmts, cvt);
11086 :
11087 64999 : return stmts;
11088 : }
11089 :
11090 : void
11091 47384 : rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi)
11092 : {
11093 47384 : rewrite_to_defined_unconditional (gsi, gsi_stmt (*gsi), true);
11094 47384 : }
11095 :
11096 : gimple_seq
11097 17799 : rewrite_to_defined_unconditional (gimple *stmt)
11098 : {
11099 17799 : return rewrite_to_defined_unconditional (nullptr, stmt, false);
11100 : }
11101 :
11102 : /* The valueization hook we use for the gimple_build API simplification.
11103 : This makes us match fold_buildN behavior by only combining with
11104 : statements in the sequence(s) we are currently building. */
11105 :
11106 : static tree
11107 21358929 : gimple_build_valueize (tree op)
11108 : {
11109 21358929 : if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL)
11110 4678508 : return op;
11111 : return NULL_TREE;
11112 : }
11113 :
11114 : /* Helper for gimple_build to perform the final insertion of stmts on SEQ. */
11115 :
11116 : static inline void
11117 1368645 : gimple_build_insert_seq (gimple_stmt_iterator *gsi,
11118 : bool before, gsi_iterator_update update,
11119 : gimple_seq seq)
11120 : {
11121 1368645 : if (before)
11122 : {
11123 97933 : if (gsi->bb)
11124 97933 : gsi_insert_seq_before (gsi, seq, update);
11125 : else
11126 0 : gsi_insert_seq_before_without_update (gsi, seq, update);
11127 : }
11128 : else
11129 : {
11130 1270712 : if (gsi->bb)
11131 171 : gsi_insert_seq_after (gsi, seq, update);
11132 : else
11133 1270541 : gsi_insert_seq_after_without_update (gsi, seq, update);
11134 : }
11135 1368645 : }
11136 :
11137 : /* Build the expression CODE OP0 of type TYPE with location LOC,
11138 : simplifying it first if possible. Returns the built
11139 : expression value and inserts statements possibly defining it
11140 : before GSI if BEFORE is true or after GSI if false and advance
11141 : the iterator accordingly.
11142 : If gsi refers to a basic block simplifying is allowed to look
11143 : at all SSA defs while when it does not it is restricted to
11144 : SSA defs that are not associated with a basic block yet,
11145 : indicating they belong to the currently building sequence. */
11146 :
11147 : tree
11148 359103 : gimple_build (gimple_stmt_iterator *gsi,
11149 : bool before, gsi_iterator_update update,
11150 : location_t loc, enum tree_code code, tree type, tree op0)
11151 : {
11152 359103 : gimple_seq seq = NULL;
11153 359103 : tree res
11154 359103 : = gimple_simplify (code, type, op0, &seq,
11155 359103 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11156 359103 : if (!res)
11157 : {
11158 316555 : res = make_ssa_name (type);
11159 316555 : gimple *stmt;
11160 316555 : if (code == REALPART_EXPR
11161 : || code == IMAGPART_EXPR
11162 316555 : || code == VIEW_CONVERT_EXPR)
11163 16137 : stmt = gimple_build_assign (res, code, build1 (code, type, op0));
11164 : else
11165 300418 : stmt = gimple_build_assign (res, code, op0);
11166 316555 : gimple_set_location (stmt, loc);
11167 316555 : gimple_seq_add_stmt_without_update (&seq, stmt);
11168 : }
11169 359103 : gimple_build_insert_seq (gsi, before, update, seq);
11170 359103 : return res;
11171 : }
11172 :
11173 : /* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
11174 : simplifying it first if possible. Returns the built
11175 : expression value inserting any new statements at GSI honoring BEFORE
11176 : and UPDATE. */
11177 :
11178 : tree
11179 791121 : gimple_build (gimple_stmt_iterator *gsi,
11180 : bool before, gsi_iterator_update update,
11181 : location_t loc, enum tree_code code, tree type,
11182 : tree op0, tree op1)
11183 : {
11184 791121 : gimple_seq seq = NULL;
11185 791121 : tree res
11186 791121 : = gimple_simplify (code, type, op0, op1, &seq,
11187 791121 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11188 791121 : if (!res)
11189 : {
11190 694457 : res = make_ssa_name (type);
11191 694457 : gimple *stmt = gimple_build_assign (res, code, op0, op1);
11192 694457 : gimple_set_location (stmt, loc);
11193 694457 : gimple_seq_add_stmt_without_update (&seq, stmt);
11194 : }
11195 791121 : gimple_build_insert_seq (gsi, before, update, seq);
11196 791121 : return res;
11197 : }
11198 :
11199 : /* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
11200 : simplifying it first if possible. Returns the built
11201 : expression value inserting any new statements at GSI honoring BEFORE
11202 : and UPDATE. */
11203 :
11204 : tree
11205 49434 : gimple_build (gimple_stmt_iterator *gsi,
11206 : bool before, gsi_iterator_update update,
11207 : location_t loc, enum tree_code code, tree type,
11208 : tree op0, tree op1, tree op2)
11209 : {
11210 :
11211 49434 : gimple_seq seq = NULL;
11212 49434 : tree res
11213 49434 : = gimple_simplify (code, type, op0, op1, op2, &seq,
11214 49434 : gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
11215 49434 : if (!res)
11216 : {
11217 35525 : res = make_ssa_name (type);
11218 35525 : gimple *stmt;
11219 35525 : if (code == BIT_FIELD_REF)
11220 27842 : stmt = gimple_build_assign (res, code,
11221 : build3 (code, type, op0, op1, op2));
11222 : else
11223 7683 : stmt = gimple_build_assign (res, code, op0, op1, op2);
11224 35525 : gimple_set_location (stmt, loc);
11225 35525 : gimple_seq_add_stmt_without_update (&seq, stmt);
11226 : }
11227 49434 : gimple_build_insert_seq (gsi, before, update, seq);
11228 49434 : return res;
11229 : }
11230 :
11231 : /* Build the call FN () with a result of type TYPE (or no result if TYPE is
11232 : void) with a location LOC. Returns the built expression value (or NULL_TREE
11233 : if TYPE is void) inserting any new statements at GSI honoring BEFORE
11234 : and UPDATE. */
11235 :
11236 : tree
11237 0 : gimple_build (gimple_stmt_iterator *gsi,
11238 : bool before, gsi_iterator_update update,
11239 : location_t loc, combined_fn fn, tree type)
11240 : {
11241 0 : tree res = NULL_TREE;
11242 0 : gimple_seq seq = NULL;
11243 0 : gcall *stmt;
11244 0 : if (internal_fn_p (fn))
11245 0 : stmt = gimple_build_call_internal (as_internal_fn (fn), 0);
11246 : else
11247 : {
11248 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11249 0 : stmt = gimple_build_call (decl, 0);
11250 : }
11251 0 : if (!VOID_TYPE_P (type))
11252 : {
11253 0 : res = make_ssa_name (type);
11254 0 : gimple_call_set_lhs (stmt, res);
11255 : }
11256 0 : gimple_set_location (stmt, loc);
11257 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11258 0 : gimple_build_insert_seq (gsi, before, update, seq);
11259 0 : return res;
11260 : }
11261 :
11262 : /* Build the call FN (ARG0) with a result of type TYPE
11263 : (or no result if TYPE is void) with location LOC,
11264 : simplifying it first if possible. Returns the built
11265 : expression value (or NULL_TREE if TYPE is void) inserting any new
11266 : statements at GSI honoring BEFORE and UPDATE. */
11267 :
11268 : tree
11269 25283 : gimple_build (gimple_stmt_iterator *gsi,
11270 : bool before, gsi_iterator_update update,
11271 : location_t loc, combined_fn fn,
11272 : tree type, tree arg0)
11273 : {
11274 25283 : gimple_seq seq = NULL;
11275 25283 : tree res = gimple_simplify (fn, type, arg0, &seq, gimple_build_valueize);
11276 25283 : if (!res)
11277 : {
11278 25283 : gcall *stmt;
11279 25283 : if (internal_fn_p (fn))
11280 24903 : stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
11281 : else
11282 : {
11283 380 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11284 380 : stmt = gimple_build_call (decl, 1, arg0);
11285 : }
11286 25283 : if (!VOID_TYPE_P (type))
11287 : {
11288 24903 : res = make_ssa_name (type);
11289 24903 : gimple_call_set_lhs (stmt, res);
11290 : }
11291 25283 : gimple_set_location (stmt, loc);
11292 25283 : gimple_seq_add_stmt_without_update (&seq, stmt);
11293 : }
11294 25283 : gimple_build_insert_seq (gsi, before, update, seq);
11295 25283 : return res;
11296 : }
11297 :
11298 : /* Build the call FN (ARG0, ARG1) with a result of type TYPE
11299 : (or no result if TYPE is void) with location LOC,
11300 : simplifying it first if possible. Returns the built
11301 : expression value (or NULL_TREE if TYPE is void) inserting any new
11302 : statements at GSI honoring BEFORE and UPDATE. */
11303 :
11304 : tree
11305 0 : gimple_build (gimple_stmt_iterator *gsi,
11306 : bool before, gsi_iterator_update update,
11307 : location_t loc, combined_fn fn,
11308 : tree type, tree arg0, tree arg1)
11309 : {
11310 0 : gimple_seq seq = NULL;
11311 0 : tree res = gimple_simplify (fn, type, arg0, arg1, &seq,
11312 : gimple_build_valueize);
11313 0 : if (!res)
11314 : {
11315 0 : gcall *stmt;
11316 0 : if (internal_fn_p (fn))
11317 0 : stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
11318 : else
11319 : {
11320 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11321 0 : stmt = gimple_build_call (decl, 2, arg0, arg1);
11322 : }
11323 0 : if (!VOID_TYPE_P (type))
11324 : {
11325 0 : res = make_ssa_name (type);
11326 0 : gimple_call_set_lhs (stmt, res);
11327 : }
11328 0 : gimple_set_location (stmt, loc);
11329 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11330 : }
11331 0 : gimple_build_insert_seq (gsi, before, update, seq);
11332 0 : return res;
11333 : }
11334 :
11335 : /* Build the call FN (ARG0, ARG1, ARG2) with a result of type TYPE
11336 : (or no result if TYPE is void) with location LOC,
11337 : simplifying it first if possible. Returns the built
11338 : expression value (or NULL_TREE if TYPE is void) inserting any new
11339 : statements at GSI honoring BEFORE and UPDATE. */
11340 :
11341 : tree
11342 0 : gimple_build (gimple_stmt_iterator *gsi,
11343 : bool before, gsi_iterator_update update,
11344 : location_t loc, combined_fn fn,
11345 : tree type, tree arg0, tree arg1, tree arg2)
11346 : {
11347 0 : gimple_seq seq = NULL;
11348 0 : tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
11349 : &seq, gimple_build_valueize);
11350 0 : if (!res)
11351 : {
11352 0 : gcall *stmt;
11353 0 : if (internal_fn_p (fn))
11354 0 : stmt = gimple_build_call_internal (as_internal_fn (fn),
11355 : 3, arg0, arg1, arg2);
11356 : else
11357 : {
11358 0 : tree decl = builtin_decl_implicit (as_builtin_fn (fn));
11359 0 : stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
11360 : }
11361 0 : if (!VOID_TYPE_P (type))
11362 : {
11363 0 : res = make_ssa_name (type);
11364 0 : gimple_call_set_lhs (stmt, res);
11365 : }
11366 0 : gimple_set_location (stmt, loc);
11367 0 : gimple_seq_add_stmt_without_update (&seq, stmt);
11368 : }
11369 0 : gimple_build_insert_seq (gsi, before, update, seq);
11370 0 : return res;
11371 : }
11372 :
11373 : /* Build CODE (OP0) with a result of type TYPE (or no result if TYPE is
11374 : void) with location LOC, simplifying it first if possible. Returns the
11375 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11376 : statements at GSI honoring BEFORE and UPDATE. */
11377 :
11378 : tree
11379 21 : gimple_build (gimple_stmt_iterator *gsi,
11380 : bool before, gsi_iterator_update update,
11381 : location_t loc, code_helper code, tree type, tree op0)
11382 : {
11383 21 : if (code.is_tree_code ())
11384 0 : return gimple_build (gsi, before, update, loc, tree_code (code), type, op0);
11385 21 : return gimple_build (gsi, before, update, loc, combined_fn (code), type, op0);
11386 : }
11387 :
11388 : /* Build CODE (OP0, OP1) with a result of type TYPE (or no result if TYPE is
11389 : void) with location LOC, simplifying it first if possible. Returns the
11390 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11391 : statements at GSI honoring BEFORE and UPDATE. */
11392 :
11393 : tree
11394 24179 : gimple_build (gimple_stmt_iterator *gsi,
11395 : bool before, gsi_iterator_update update,
11396 : location_t loc, code_helper code, tree type, tree op0, tree op1)
11397 : {
11398 24179 : if (code.is_tree_code ())
11399 24179 : return gimple_build (gsi, before, update,
11400 24179 : loc, tree_code (code), type, op0, op1);
11401 0 : return gimple_build (gsi, before, update,
11402 0 : loc, combined_fn (code), type, op0, op1);
11403 : }
11404 :
11405 : /* Build CODE (OP0, OP1, OP2) with a result of type TYPE (or no result if TYPE
11406 : is void) with location LOC, simplifying it first if possible. Returns the
11407 : built expression value (or NULL_TREE if TYPE is void) inserting any new
11408 : statements at GSI honoring BEFORE and UPDATE. */
11409 :
11410 : tree
11411 0 : gimple_build (gimple_stmt_iterator *gsi,
11412 : bool before, gsi_iterator_update update,
11413 : location_t loc, code_helper code,
11414 : tree type, tree op0, tree op1, tree op2)
11415 : {
11416 0 : if (code.is_tree_code ())
11417 0 : return gimple_build (gsi, before, update,
11418 0 : loc, tree_code (code), type, op0, op1, op2);
11419 0 : return gimple_build (gsi, before, update,
11420 0 : loc, combined_fn (code), type, op0, op1, op2);
11421 : }
11422 :
11423 : /* Build the conversion (TYPE) OP with a result of type TYPE
11424 : with location LOC if such conversion is necessary in GIMPLE,
11425 : simplifying it first.
11426 : Returns the built expression inserting any new statements
11427 : at GSI honoring BEFORE and UPDATE. */
11428 :
11429 : tree
11430 2037898 : gimple_convert (gimple_stmt_iterator *gsi,
11431 : bool before, gsi_iterator_update update,
11432 : location_t loc, tree type, tree op)
11433 : {
11434 2037898 : if (useless_type_conversion_p (type, TREE_TYPE (op)))
11435 : return op;
11436 187084 : return gimple_build (gsi, before, update, loc, NOP_EXPR, type, op);
11437 : }
11438 :
11439 : /* Build the conversion (ptrofftype) OP with a result of a type
11440 : compatible with ptrofftype with location LOC if such conversion
11441 : is necessary in GIMPLE, simplifying it first.
11442 : Returns the built expression value inserting any new statements
11443 : at GSI honoring BEFORE and UPDATE. */
11444 :
11445 : tree
11446 208 : gimple_convert_to_ptrofftype (gimple_stmt_iterator *gsi,
11447 : bool before, gsi_iterator_update update,
11448 : location_t loc, tree op)
11449 : {
11450 208 : if (ptrofftype_p (TREE_TYPE (op)))
11451 : return op;
11452 0 : return gimple_convert (gsi, before, update, loc, sizetype, op);
11453 : }
11454 :
11455 : /* Build a vector of type TYPE in which each element has the value OP.
11456 : Return a gimple value for the result, inserting any new statements
11457 : at GSI honoring BEFORE and UPDATE. */
11458 :
11459 : tree
11460 327921 : gimple_build_vector_from_val (gimple_stmt_iterator *gsi,
11461 : bool before, gsi_iterator_update update,
11462 : location_t loc, tree type, tree op)
11463 : {
11464 327921 : if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()
11465 : && !CONSTANT_CLASS_P (op))
11466 : return gimple_build (gsi, before, update,
11467 : loc, VEC_DUPLICATE_EXPR, type, op);
11468 :
11469 327921 : tree res, vec = build_vector_from_val (type, op);
11470 327921 : if (is_gimple_val (vec))
11471 : return vec;
11472 28041 : if (gimple_in_ssa_p (cfun))
11473 28041 : res = make_ssa_name (type);
11474 : else
11475 0 : res = create_tmp_reg (type);
11476 28041 : gimple_seq seq = NULL;
11477 28041 : gimple *stmt = gimple_build_assign (res, vec);
11478 28041 : gimple_set_location (stmt, loc);
11479 28041 : gimple_seq_add_stmt_without_update (&seq, stmt);
11480 28041 : gimple_build_insert_seq (gsi, before, update, seq);
11481 28041 : return res;
11482 : }
11483 :
11484 : /* Build a vector from BUILDER, handling the case in which some elements
11485 : are non-constant. Return a gimple value for the result, inserting
11486 : any new instructions to GSI honoring BEFORE and UPDATE.
11487 :
11488 : BUILDER must not have a stepped encoding on entry. This is because
11489 : the function is not geared up to handle the arithmetic that would
11490 : be needed in the variable case, and any code building a vector that
11491 : is known to be constant should use BUILDER->build () directly. */
11492 :
11493 : tree
11494 373770 : gimple_build_vector (gimple_stmt_iterator *gsi,
11495 : bool before, gsi_iterator_update update,
11496 : location_t loc, tree_vector_builder *builder)
11497 : {
11498 373770 : gcc_assert (builder->nelts_per_pattern () <= 2);
11499 373770 : unsigned int encoded_nelts = builder->encoded_nelts ();
11500 1316185 : for (unsigned int i = 0; i < encoded_nelts; ++i)
11501 1058078 : if (!CONSTANT_CLASS_P ((*builder)[i]))
11502 : {
11503 115663 : gimple_seq seq = NULL;
11504 115663 : tree type = builder->type ();
11505 115663 : unsigned int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
11506 115663 : vec<constructor_elt, va_gc> *v;
11507 115663 : vec_alloc (v, nelts);
11508 368813 : for (i = 0; i < nelts; ++i)
11509 253150 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));
11510 :
11511 115663 : tree res;
11512 115663 : if (gimple_in_ssa_p (cfun))
11513 115663 : res = make_ssa_name (type);
11514 : else
11515 0 : res = create_tmp_reg (type);
11516 115663 : gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
11517 115663 : gimple_set_location (stmt, loc);
11518 115663 : gimple_seq_add_stmt_without_update (&seq, stmt);
11519 115663 : gimple_build_insert_seq (gsi, before, update, seq);
11520 115663 : return res;
11521 : }
11522 258107 : return builder->build ();
11523 : }
11524 :
11525 : /* Emit gimple statements into &stmts that take a value given in OLD_SIZE
11526 : and generate a value guaranteed to be rounded upwards to ALIGN.
11527 :
11528 : Return the tree node representing this size, it is of TREE_TYPE TYPE. */
11529 :
11530 : tree
11531 0 : gimple_build_round_up (gimple_stmt_iterator *gsi,
11532 : bool before, gsi_iterator_update update,
11533 : location_t loc, tree type,
11534 : tree old_size, unsigned HOST_WIDE_INT align)
11535 : {
11536 0 : unsigned HOST_WIDE_INT tg_mask = align - 1;
11537 : /* tree new_size = (old_size + tg_mask) & ~tg_mask; */
11538 0 : gcc_assert (INTEGRAL_TYPE_P (type));
11539 0 : tree tree_mask = build_int_cst (type, tg_mask);
11540 0 : tree oversize = gimple_build (gsi, before, update,
11541 : loc, PLUS_EXPR, type, old_size, tree_mask);
11542 :
11543 0 : tree mask = build_int_cst (type, -align);
11544 0 : return gimple_build (gsi, before, update,
11545 0 : loc, BIT_AND_EXPR, type, oversize, mask);
11546 : }
11547 :
11548 : /* Return true if the result of assignment STMT is known to be non-negative.
11549 : DEPTH is the current nesting depth of the query. */
11550 :
11551 : static bool
11552 6627979 : gimple_assign_nonnegative_p (gimple *stmt, int depth)
11553 : {
11554 6627979 : enum tree_code code = gimple_assign_rhs_code (stmt);
11555 6627979 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
11556 6627979 : switch (get_gimple_rhs_class (code))
11557 : {
11558 550303 : case GIMPLE_UNARY_RHS:
11559 550303 : return tree_unary_nonnegative_p (gimple_assign_rhs_code (stmt),
11560 : type,
11561 : gimple_assign_rhs1 (stmt),
11562 550303 : depth);
11563 3878389 : case GIMPLE_BINARY_RHS:
11564 3878389 : return tree_binary_nonnegative_p (gimple_assign_rhs_code (stmt),
11565 : type,
11566 : gimple_assign_rhs1 (stmt),
11567 : gimple_assign_rhs2 (stmt),
11568 3878389 : depth);
11569 : case GIMPLE_TERNARY_RHS:
11570 : return false;
11571 2182399 : case GIMPLE_SINGLE_RHS:
11572 2182399 : return tree_single_nonnegative_p (gimple_assign_rhs1 (stmt),
11573 2182399 : depth);
11574 : case GIMPLE_INVALID_RHS:
11575 : break;
11576 : }
11577 0 : gcc_unreachable ();
11578 : }
11579 :
11580 : /* Return true if return value of call STMT is known to be non-negative.
11581 : DEPTH is the current nesting depth of the query. */
11582 :
11583 : static bool
11584 13353805 : gimple_call_nonnegative_p (gimple *stmt, int depth)
11585 : {
11586 13353805 : tree arg0
11587 13353805 : = gimple_call_num_args (stmt) > 0 ? gimple_call_arg (stmt, 0) : NULL_TREE;
11588 13353805 : tree arg1
11589 13353805 : = gimple_call_num_args (stmt) > 1 ? gimple_call_arg (stmt, 1) : NULL_TREE;
11590 13353805 : tree lhs = gimple_call_lhs (stmt);
11591 13353805 : return (lhs
11592 13353805 : && tree_call_nonnegative_p (TREE_TYPE (lhs),
11593 : gimple_call_combined_fn (stmt),
11594 13353805 : arg0, arg1, depth));
11595 : }
11596 :
11597 : /* Return true if return value of call STMT is known to be non-negative.
11598 : DEPTH is the current nesting depth of the query. */
11599 :
11600 : static bool
11601 1242599 : gimple_phi_nonnegative_p (gimple *stmt, int depth)
11602 : {
11603 1678600 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11604 : {
11605 1665857 : tree arg = gimple_phi_arg_def (stmt, i);
11606 1665857 : if (!tree_single_nonnegative_p (arg, depth + 1))
11607 : return false;
11608 : }
11609 : return true;
11610 : }
11611 :
11612 : /* Return true if STMT is known to compute a non-negative value.
11613 : DEPTH is the current nesting depth of the query. */
11614 :
11615 : bool
11616 21885109 : gimple_stmt_nonnegative_p (gimple *stmt, int depth)
11617 : {
11618 21885109 : tree type = gimple_range_type (stmt);
11619 21885109 : if (type && frange::supports_p (type))
11620 : {
11621 1506067 : frange r;
11622 1506067 : bool sign;
11623 1506067 : if (get_global_range_query ()->range_of_stmt (r, stmt)
11624 1506067 : && r.signbit_p (sign))
11625 27993 : return !sign;
11626 1506067 : }
11627 21857116 : switch (gimple_code (stmt))
11628 : {
11629 6627979 : case GIMPLE_ASSIGN:
11630 6627979 : return gimple_assign_nonnegative_p (stmt, depth);
11631 13353805 : case GIMPLE_CALL:
11632 13353805 : return gimple_call_nonnegative_p (stmt, depth);
11633 1242599 : case GIMPLE_PHI:
11634 1242599 : return gimple_phi_nonnegative_p (stmt, depth);
11635 : default:
11636 : return false;
11637 : }
11638 : }
11639 :
11640 : /* Return true if the floating-point value computed by assignment STMT
11641 : is known to have an integer value. We also allow +Inf, -Inf and NaN
11642 : to be considered integer values. Return false for signaling NaN.
11643 :
11644 : DEPTH is the current nesting depth of the query. */
11645 :
11646 : static bool
11647 59009 : gimple_assign_integer_valued_real_p (gimple *stmt, int depth)
11648 : {
11649 59009 : enum tree_code code = gimple_assign_rhs_code (stmt);
11650 59009 : switch (get_gimple_rhs_class (code))
11651 : {
11652 15030 : case GIMPLE_UNARY_RHS:
11653 15030 : return integer_valued_real_unary_p (gimple_assign_rhs_code (stmt),
11654 15030 : gimple_assign_rhs1 (stmt), depth);
11655 13375 : case GIMPLE_BINARY_RHS:
11656 13375 : return integer_valued_real_binary_p (gimple_assign_rhs_code (stmt),
11657 : gimple_assign_rhs1 (stmt),
11658 13375 : gimple_assign_rhs2 (stmt), depth);
11659 : case GIMPLE_TERNARY_RHS:
11660 : return false;
11661 29449 : case GIMPLE_SINGLE_RHS:
11662 29449 : return integer_valued_real_single_p (gimple_assign_rhs1 (stmt), depth);
11663 : case GIMPLE_INVALID_RHS:
11664 : break;
11665 : }
11666 0 : gcc_unreachable ();
11667 : }
11668 :
11669 : /* Return true if the floating-point value computed by call STMT is known
11670 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11671 : considered integer values. Return false for signaling NaN.
11672 :
11673 : DEPTH is the current nesting depth of the query. */
11674 :
11675 : static bool
11676 1089 : gimple_call_integer_valued_real_p (gimple *stmt, int depth)
11677 : {
11678 1089 : tree arg0 = (gimple_call_num_args (stmt) > 0
11679 1089 : ? gimple_call_arg (stmt, 0)
11680 : : NULL_TREE);
11681 1089 : tree arg1 = (gimple_call_num_args (stmt) > 1
11682 1089 : ? gimple_call_arg (stmt, 1)
11683 : : NULL_TREE);
11684 1089 : return integer_valued_real_call_p (gimple_call_combined_fn (stmt),
11685 1089 : arg0, arg1, depth);
11686 : }
11687 :
11688 : /* Return true if the floating-point result of phi STMT is known to have
11689 : an integer value. We also allow +Inf, -Inf and NaN to be considered
11690 : integer values. Return false for signaling NaN.
11691 :
11692 : DEPTH is the current nesting depth of the query. */
11693 :
11694 : static bool
11695 1489 : gimple_phi_integer_valued_real_p (gimple *stmt, int depth)
11696 : {
11697 1652 : for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
11698 : {
11699 1643 : tree arg = gimple_phi_arg_def (stmt, i);
11700 1643 : if (!integer_valued_real_single_p (arg, depth + 1))
11701 : return false;
11702 : }
11703 : return true;
11704 : }
11705 :
11706 : /* Return true if the floating-point value computed by STMT is known
11707 : to have an integer value. We also allow +Inf, -Inf and NaN to be
11708 : considered integer values. Return false for signaling NaN.
11709 :
11710 : DEPTH is the current nesting depth of the query. */
11711 :
11712 : bool
11713 88988 : gimple_stmt_integer_valued_real_p (gimple *stmt, int depth)
11714 : {
11715 88988 : switch (gimple_code (stmt))
11716 : {
11717 59009 : case GIMPLE_ASSIGN:
11718 59009 : return gimple_assign_integer_valued_real_p (stmt, depth);
11719 1089 : case GIMPLE_CALL:
11720 1089 : return gimple_call_integer_valued_real_p (stmt, depth);
11721 1489 : case GIMPLE_PHI:
11722 1489 : return gimple_phi_integer_valued_real_p (stmt, depth);
11723 : default:
11724 : return false;
11725 : }
11726 : }
|